Opened 14 years ago
Closed 13 years ago
#4451 closed bug (fixed)
AJAX tabs stop functioning properly after AJAX error callback is executed
Reported by: | JBeckton | Owned by: | Jörn Zaefferer |
---|---|---|---|
Priority: | critical | Milestone: | 1.8 |
Component: | ui.tabs | Version: | 1.7.1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description (last modified by )
I have some UI Tabs set up using AJAX calls to populate the container, set it up as suggested on the jQuery UI site.
In my AJAX options I have a handler for error event. I purposely broke the remote page to test the error handling. When I click the tab that calls the remote page my error callback runs as expected but now when I try to select the other tabs they freak out! I either have to click on them twice or they may load each others content inside them at the same time. Very strange!
My application handles the error and returns the http status 500 so the AJAX will know it took a crap.
Here is my code. HTML:
<div class="AJAXErrorContainer" style="display:none"></div> <div id="caseManagerWorkbench" class="ui-tabs ui-widget ui-widget- content ui-corner-all"> <ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget- header ui-corner-all"> <li class="ui-state-default ui-corner-top ui-tabs-selected ui-state- active"><a href="index.cfm?fuseaction=casemanager.exhibits" title="Exhibits">Exhibits</a></li> <li class="ui-state-default ui-corner-top"><a href="index.cfm? fuseaction=casemanager.checkwriter" title="Check Writer">Check Writer</ a></li> <li class="ui-state-default ui-corner-top"><a href="index.cfm? fuseaction=casemanager.comments" title="Comments">Comments</a></li> <li class="spinnerContainer"></li> </ul> <div id="Exhibits"></div> <div id="Check_Writer"></div> <div id="Comments"></div> </div>
JavaScript:
$(function() { //builds the tab interface for viewing the submittal data $("#caseManagerWorkbench").tabs({ ajaxOptions: { async: false, cache: false, success: function() { $(".AJAXErrorContainer").hide(); }, error: function() { $(".AJAXErrorContainer").html("An error has occured during the remote request, Please try again."); $(".AJAXErrorContainer").show(); } }, spinner: null, select: function() {$(".spinnerContainer").html("<span style='color:white;'><img src='images/ajax-loader-blue.gif' hspace='5' vspace='4' align='absmiddle'> Loading...</span>");}, load: function() {$(".spinnerContainer").html("");} });
Attachments (2)
Change History (12)
comment:1 Changed 14 years ago by
Description: | modified (diff) |
---|---|
Milestone: | TBD → 1.7.2 |
comment:2 Changed 14 years ago by
Milestone: | 1.7.2 → 1.8 |
---|
Changed 14 years ago by
Attachment: | ui.tabs.js-4451.patch added |
---|
comment:3 Changed 14 years ago by
comment:4 Changed 14 years ago by
Similarly, if the ajax request takes a long time, the user may click on a different tab. This causes the same behavior described for the error case -- the slow-loading tab becomes selected when the user clicks the next tab, the content is not loaded (so you end up with a blank panel), and the tab clicks become off-by-one in the stack of clicks.
To illustrate, consider the case of three tabs. Tab 1 is the currently selected. Tab 2 is a slow-loading tab. Tab 3 loads in a reasonable time.
The user starts on Tab 1 with the content loaded. He then clicks on Tab 2, but Tab 1 is still indicated as selected, since Tab 2 hasn't loaded yet. He quickly gets tired of waiting, so he clicks on Tab 3 before Tab 2 has loaded. At this point, Tab 2 becomes the selected tab, but there is no content in it. If he then clicks on Tab 3 again to try to get it to load, it does, but it has either the content for Tab 1 at the top and the content for Tab 3 at the bottom, or it has the blank div for Tab 1's panel at the top and the content for Tab 3 at the bottom (this is easiest to see if there is a minimum height set on the panels).
If instead of clicking Tab 3 a second time he clicks on Tab 1, he gets the off-by-one error behavior. Tab 3 will become selected when he clicks on Tab 1 with the double-content problem described above. If he then clicks on Tab 1 again, he will have the content from both Tab 1 and Tab 3 visible.
Obviously there is a more fundamental bug in the tabs than what this ticket initially suggests. However, I think the core if the issue would probably be corrected if selecting a tab always immediately updated the UI and displayed a spinner in the newly-displayed tab panel.
Getting this behavior may be as simple as moving
self.element.dequeue("tabs");
outside of the ajax callbacks and calling a new displayPanelSpinner
function (as well as adding a new option for a panelSpinner
). However, I haven't tried that fix yet.
This error is easily replicated by setting up the the three tabs as described above with normal ajax tab settings and setting a two second sleep on the server side for one of the tabs' target urls. As mentioned above, it is important to set the panels to have a minimum height in the css to be able to see the panels loading improperly.
comment:5 Changed 14 years ago by
I have verified that moving the self.element.dequeue("tabs");
line out of the success callback does fix the slow tab/fast user errors. Presumably the same would work well with the patch attached to this ticket for the ajax error callbacks.
The end of my load
function now looks like:
this.xhr = $.ajax($.extend({}, o.ajaxOptions, { url: url, success: function(r, s) { $(self._sanitizeSelector(a.hash)).html(r); // take care of tab labels self._cleanup(); if (o.cache) { $.data(a, 'cache.tabs', true); // if loaded once do not load them again } // callbacks self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); try { o.ajaxOptions.success(r, s); } catch (e) {} } })); // last, so that load event is fired before show... self.element.dequeue("tabs"); return this; },
Changed 13 years ago by
Attachment: | jquery.ui.tabs.js-4451.patch added |
---|
comment:6 follow-up: 7 Changed 13 years ago by
Added patch against [source:/trunk/ui/[email protected] r3488] which merges joerns patch with the following changes
- don't display an error message in the tab panel
- pass extra information to the error handler
- the index of the broken tab
- the anchor that initiated the request
comment:7 Changed 13 years ago by
Replying to andrew.sharpe.7.9:
And also moves
self.element.dequeue("tabs");
out of the success callback as suggested by itfische.
comment:8 Changed 13 years ago by
Patch tested by ogdoad8 http://forum.jquery.com/topic/ajax-tabs-bug-4451-patch-is-good
comment:9 Changed 13 years ago by
Owner: | set to joern.zaefferer |
---|---|
Status: | new → accepted |
comment:10 Changed 13 years ago by
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
Fixed in r3846. I removed the e-argument and changed it to call options.ajaxOptions.error to be consistent with options.ajaxOptions.success. Also extended the ajax demo to demo slow-loading and broken tabs.
Attached a patch to handle ajax errors. Currently the error message is hard coded.