Commit 78162bf5 authored by Andrew Nicols's avatar Andrew Nicols Committed by Jake Dallimore
Browse files

MDL-60773 core: Add pendingJS checks for autocomplete interactions

parent 4275ea4a
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -448,6 +448,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
$(ele).prop('selected', true);
}
});
// Rerender the selection list.
updateSelectionList(options, state, originalSelect);
// Notifiy that the selection changed.
......@@ -478,6 +479,8 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
* @param {Object} ajaxHandler This is a module that does the ajax fetch and translates the results.
*/
var updateAjax = function(e, options, state, originalSelect, ajaxHandler) {
var pendingKey = 'form-autocomplete-updateajax';
M.util.js_pending(pendingKey);
// Get the query to pass to the ajax function.
var query = $(e.currentTarget).val();
// Call the transport function to do the ajax (name taken from Select2).
......@@ -514,7 +517,11 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
});
// Update the list of suggestions now from the new values in the select list.
updateSuggestions(options, state, '', originalSelect);
}, notification.exception);
M.util.js_complete(pendingKey);
}, function(error) {
M.util.js_complete(pendingKey);
notification.exception(error);
});
};
/**
......@@ -531,11 +538,15 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
var inputElement = $(document.getElementById(state.inputId));
// Add keyboard nav with keydown.
inputElement.on('keydown', function(e) {
var pendingKey = 'form-autocomplete-addnav-' + state.inputId + '-' + e.keyCode;
M.util.js_pending(pendingKey);
switch (e.keyCode) {
case KEYS.DOWN:
// If the suggestion list is open, move to the next item.
if (!options.showSuggestions) {
// Do not consume this event.
M.util.js_complete(pendingKey);
return true;
} else if (inputElement.attr('aria-expanded') === "true") {
activateNextItem(state);
......@@ -552,12 +563,14 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
}
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
case KEYS.UP:
// Choose the previous active item.
activatePreviousItem(state);
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
case KEYS.ENTER:
var suggestionsElement = $(document.getElementById(state.suggestionsId));
......@@ -571,6 +584,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
}
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
case KEYS.ESCAPE:
if (inputElement.attr('aria-expanded') === "true") {
......@@ -579,12 +593,16 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
}
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
}
M.util.js_complete(pendingKey);
return true;
});
// Support multi lingual COMMA keycode (44).
inputElement.on('keypress', function(e) {
var pendingKey = 'form-autocomplete-keypress-' + e.keyCode;
M.util.js_pending(pendingKey);
if (e.keyCode === KEYS.COMMA) {
if (options.tags) {
// If we are allowing tags, comma should create a tag (or enter).
......@@ -592,13 +610,17 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
}
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
}
M.util.js_complete(pendingKey);
return true;
});
// Handler used to force set the value from behat.
inputElement.on('behat:set-value', function() {
var suggestionsElement = $(document.getElementById(state.suggestionsId));
var pendingKey = 'form-autocomplete-behat';
M.util.js_pending(pendingKey);
if ((inputElement.attr('aria-expanded') === "true") &&
(suggestionsElement.children('[aria-selected=true]').length > 0)) {
// If the suggestion list has an active item, select it.
......@@ -607,8 +629,11 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
// If tags are enabled, create a tag.
createItem(options, state, originalSelect);
}
M.util.js_complete(pendingKey);
});
inputElement.on('blur', function() {
var pendingKey = 'form-autocomplete-blur';
M.util.js_pending(pendingKey);
window.setTimeout(function() {
// Get the current element with focus.
var focusElement = $(document.activeElement);
......@@ -619,11 +644,14 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
}
closeSuggestions(state);
}
M.util.js_complete(pendingKey);
}, 500);
});
if (options.showSuggestions) {
var arrowElement = $(document.getElementById(state.downArrowId));
arrowElement.on('click', function(e) {
var pendingKey = 'form-autocomplete-show-suggestions';
M.util.js_pending(pendingKey);
// Prevent the close timer, or we will open, then close the suggestions.
inputElement.focus();
// Handle ajax population of suggestions.
......@@ -635,11 +663,14 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
// Else - open the suggestions list.
updateSuggestions(options, state, inputElement.val(), originalSelect);
}
M.util.js_complete(pendingKey);
});
}
var suggestionsElement = $(document.getElementById(state.suggestionsId));
suggestionsElement.parent().on('click', '[role=option]', function(e) {
var pendingKey = 'form-autocomplete-parent';
M.util.js_pending(pendingKey);
// Handle clicks on suggestions.
var element = $(e.currentTarget).closest('[role=option]');
var suggestionsElement = $(document.getElementById(state.suggestionsId));
......@@ -649,29 +680,37 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
activateItem(current, state);
// And select it.
selectCurrentItem(options, state, originalSelect);
M.util.js_complete(pendingKey);
});
var selectionElement = $(document.getElementById(state.selectionId));
// Handle clicks on the selected items (will unselect an item).
selectionElement.on('click', '[role=listitem]', function(e) {
var pendingKey = 'form-autocomplete-clicks';
M.util.js_pending(pendingKey);
// Get the item that was clicked.
var item = $(e.currentTarget);
// Remove it from the selection.
deselectItem(options, state, item, originalSelect);
M.util.js_complete(pendingKey);
});
// Keyboard navigation for the selection list.
selectionElement.on('keydown', function(e) {
var pendingKey = 'form-autocomplete-keydown-' + e.keyCode;
M.util.js_pending(pendingKey);
switch (e.keyCode) {
case KEYS.DOWN:
// Choose the next selection item.
activateNextSelection(state);
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
case KEYS.UP:
// Choose the previous selection item.
activatePreviousSelection(state);
// We handled this event, so prevent it.
e.preventDefault();
M.util.js_complete(pendingKey);
return false;
case KEYS.SPACE:
case KEYS.ENTER:
......@@ -683,8 +722,10 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
// We handled this event, so prevent it.
e.preventDefault();
}
M.util.js_complete(pendingKey);
return false;
}
M.util.js_complete(pendingKey);
return true;
});
// Whenever the input field changes, update the suggestion list.
......@@ -693,8 +734,10 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
if (options.ajax) {
require([options.ajax], function(ajaxHandler) {
var throttleTimeout = null;
var pendingKey = 'autocomplete-throttledhandler';
var handler = function(e) {
updateAjax(e, options, state, originalSelect, ajaxHandler);
M.util.js_complete(pendingKey);
};
// For input events, we do not want to trigger many, many updates.
......@@ -702,6 +745,9 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
if (throttleTimeout !== null) {
window.clearTimeout(throttleTimeout);
throttleTimeout = null;
} else {
// No existing timeout handler, so this is the start of a throttling check.
M.util.js_pending(pendingKey);
}
throttleTimeout = window.setTimeout(handler.bind(this, e), 300);
};
......@@ -756,6 +802,8 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
showSuggestions: true,
noSelectionString: noSelectionString
};
var pendingKey = 'autocomplete-setup-' + selector;
M.util.js_pending(pendingKey);
if (typeof tags !== "undefined") {
options.tags = tags;
}
......@@ -778,6 +826,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
var originalSelect = $(selector);
if (!originalSelect) {
log.debug('Selector not found: ' + selector);
M.util.js_complete(pendingKey);
return false;
}
......@@ -839,7 +888,11 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
// Show the current values in the selection list.
updateSelectionList(options, state, originalSelect);
M.util.js_complete(pendingKey);
return true;
}).fail(function(error) {
M.util.js_complete(pendingKey);
notification.exception(error);
});
}
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment