From db46eddf418b1758d595f94d3604212cfe2977bf Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 27 Sep 2012 19:03:34 +0100 Subject: [PATCH] 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. --- user/selector/module.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/user/selector/module.js b/user/selector/module.js index 68b743d3b0a..de2f500d804 100644 --- a/user/selector/module.js +++ b/user/selector/module.js @@ -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');