MDL-35680 user selector: more usable when queries are slow.

The problem is to do when you pause a bit, so a search starts, and then
type a bit more before the search finishes. It was behaving like this:

1. Type a bit, then pause.
2. First search request sent.
3. Type a bit more, then pause.
4. Second search request sent.
5. First search request completes.
6. You try to select one result.
7. Second search request comples, overwriting what you are selecting.

This fix works by cancelling the first request before sending the
second.
This commit is contained in:
Tim Hunt 2012-09-27 19:03:34 +01:00
parent 5d6285c220
commit e783cc45ae

View File

@ -43,6 +43,8 @@ M.core_user.init_user_selector = function (Y, name, hash, extrafields, lastsearc
listbox : Y.one('#'+name),
/** Used to hold the timeout id of the timeout that waits before doing a search. */
timeoutid : null,
/** Stores any in-progress remote requests. */
iotransactions : {},
/** The last string that we searched for, so we can avoid unnecessary repeat searches. */
lastsearch : lastsearch,
/** Whether any options where selected last time we checked. Used by
@ -140,7 +142,12 @@ M.core_user.init_user_selector = function (Y, name, hash, extrafields, lastsearc
return;
}
Y.io(M.cfg.wwwroot + '/user/selector/search.php', {
// Try to cancel existing transactions.
Y.Object.each(this.iotransactions, function(trans) {
trans.abort();
});
var iotrans = Y.io(M.cfg.wwwroot + '/user/selector/search.php', {
method: 'POST',
data: 'selectorid='+hash+'&sesskey='+M.cfg.sesskey+'&search='+value + '&userselector_searchanywhere=' + this.get_option('searchanywhere'),
on: {
@ -149,6 +156,7 @@ M.core_user.init_user_selector = function (Y, name, hash, extrafields, lastsearc
},
context:this
});
this.iotransactions[iotrans.id] = iotrans;
this.lastsearch = value;
this.listbox.setStyle('background','url(' + M.util.image_url('i/loading', 'moodle') + ') no-repeat center center');
@ -160,17 +168,27 @@ M.core_user.init_user_selector = function (Y, name, hash, extrafields, lastsearc
*/
handle_response : function(requestid, response) {
try {
delete this.iotransactions[requestid];
if (!Y.Object.isEmpty(this.iotransactions)) {
// More searches pending. Wait until they are all done.
return;
}
this.listbox.setStyle('background','');
var data = Y.JSON.parse(response.responseText);
this.output_options(data);
} catch (e) {
this.handle_failure();
this.handle_failure(requestid);
}
},
/**
* Handles what happens when the ajax request fails.
*/
handle_failure : function() {
handle_failure : function(requestid) {
delete this.iotransactions[requestid];
if (!Y.Object.isEmpty(this.iotransactions)) {
// More searches pending. Wait until they are all done.
return;
}
this.listbox.setStyle('background','');
this.searchfield.addClass('error');