Best way to chain multiple dependant AJAX calls where some calls are optional (depending on the result of previous AJAX request)
I have 3 dependant select lists - "Component", "Modifer" and "Defect Type". When the user changes the selected "Component" I need to updated the items in the "Modifier" select list and then depending on how many modifiers are returned I may or may not need to update the items in the "Defect Type" select list.
Pseudo code:
1. Display loading panel
2. Make an AJAX call to find all modifiers for the selected component
3. If the number of modifiers returned from step 2) is greater than 0 then
Add the returned modifiers to the "Modifer" select list
Else
Make an AJAX call to find all defect types for the selected component
Add the returned defect types to the "Defect Type" select list
4. Hide the loading panel.
I have been able to implement this using the following jQuery code and it works, but it involves having multiple levels of nesting in the done event handlers and it seems untidy and not very maintainable.
Am I doing this the right way or there a better way to do it? I have thought of using deferred's and chaining them using .then but I can't seem to figure out how to deal with the optional AJAX call.
- $("#ComponentCode").change(function (e) {
- // Save the currently selected modifier (so we can re-select it after re-populating the modifier select list)
- var oldModifierCode = $("#ModifierCode").val();
- // Clear the modifier select list
- $("#ModifierCode").empty();
- showLoadingPanel();
- // Begin an AJAX to get all modifiers for the EGI and selected component
- var modifierSearchRequest = $.ajax({
- type: 'POST',
- url: '@Url.Action("ModifierSearch")',
- dataType: "json",
- data: {
- egi: $("#Egi").val(),
- componentCode: $("#ComponentCode").val()
- }
- });
- modifierSearchRequest.done(function (modifiers, textStatus, jqXhr) {
- /// <summary>Callback function executed once the modifier search AJAX request has completed</summary>
- /// <param name="modifiers" type="JSON">The JSON formatted list of modifiers returned from the server</param>
- /// <param name="textStatus" type="String">A string describing the status</param>
- /// <param name="jqXhr" type="jqXHR">The jQuery XMLHttpRequest (jqXHR) object</param>
- if (modifiers.length > 0) {
- // The search returned at least 1 modifier. Fill the modifier select list with the search results
- fillSelectList($("#ModifierCode"), modifiers, oldModifierCode);
- hideLoadingPanel();
- $("#ModifierCode").effect("highlight", { color: "#428bca" }, 2000);
- }
- else {
- // The search returned no modifiers
- // Save the currently selected defect type (so we can re-select it after re-populating the defect type select list)
- var oldDefectTypeCode = $("#DefectTypeCode").val();
- // Clear the defect type select list
- $("#DefectTypeCode").empty();
- // Begin an AJAX to get all defect types for the EGI and selected component
- var defectTypeSearchRequest = $.ajax({
- type: 'POST',
- url: '@Url.Action("DefectTypeSearch")',
- dataType: "json",
- data: {
- egi: $("#Egi").val(),
- componentCode: $("#ComponentCode").val()
- }
- });
- defectTypeSearchRequest.done(function (defectTypes, textStatus, jqXhr) {
- fillSelectList($("#DefectTypeCode"), defectTypes, oldDefectTypeCode);
- hideLoadingPanel();
- $("#DefectTypeCode").effect("highlight", {}, 2000);
- });
- defectTypeSearchRequest.fail(handlejQueryAjaxError);
- }
- });
- modifierSearchRequest.fail(handlejQueryAjaxError);
- })
Thanks
David