first commit
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* @file js/controllers/AutocompleteHandler.js
|
||||
*
|
||||
* Copyright (c) 2014-2021 Simon Fraser University
|
||||
* Copyright (c) 2000-2021 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class AutocompleteHandler
|
||||
* @ingroup js_controllers
|
||||
*
|
||||
* @brief PKP autocomplete handler (extends the functionality of the
|
||||
* jqueryUI autocomplete)
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @extends $.pkp.classes.Handler
|
||||
*
|
||||
* @param {jQueryObject} $autocompleteField the wrapped HTML input element.
|
||||
* @param {Object} options options to be passed
|
||||
* into the jqueryUI autocomplete plugin.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler = function($autocompleteField, options) {
|
||||
var autocompleteOptions, opt;
|
||||
|
||||
this.parent($autocompleteField, options);
|
||||
|
||||
// Get the URL passed in
|
||||
this.sourceUrl_ = options.sourceUrl;
|
||||
options.sourceUrl = undefined;
|
||||
|
||||
this.disableSync_ = options.disableSync;
|
||||
|
||||
// Create autocomplete settings.
|
||||
opt = {};
|
||||
opt.source = this.callbackWrapper(this.fetchAutocomplete);
|
||||
|
||||
// Set the anchor where to append the suggestions menu
|
||||
opt.appendTo = '#' + $autocompleteField.attr('id');
|
||||
|
||||
autocompleteOptions = $.extend({ },
|
||||
this.self('DEFAULT_PROPERTIES_'), opt, options);
|
||||
|
||||
// Get the text input inside of this Div.
|
||||
this.textInput = $autocompleteField.find(':text');
|
||||
if (!this.disableSync_) {
|
||||
this.textInput.keyup(this.callbackWrapper(this.synchronizeFields_));
|
||||
}
|
||||
// Create the autocomplete field with the jqueryUI plug-in.
|
||||
this.textInput.autocomplete(autocompleteOptions);
|
||||
|
||||
// Get the text input inside of this Div.
|
||||
this.hiddenInput_ = $autocompleteField.find('input:hidden');
|
||||
|
||||
this.bind('autocompleteselect', this.itemSelected);
|
||||
this.bind('autocompletefocus', this.itemFocused);
|
||||
this.textInput.blur(this.callbackWrapper(this.textInputBlurHandler_));
|
||||
};
|
||||
$.pkp.classes.Helper.inherits(
|
||||
$.pkp.controllers.AutocompleteHandler, $.pkp.classes.Handler);
|
||||
|
||||
|
||||
//
|
||||
// Private static properties
|
||||
//
|
||||
/**
|
||||
* Whether or not to disable syncing the text and hidden field.
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.disableSync_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Default options
|
||||
* @private
|
||||
* @type {Object}
|
||||
* @const
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.DEFAULT_PROPERTIES_ = {
|
||||
// General settings
|
||||
minLength: 2
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private properties
|
||||
//
|
||||
/**
|
||||
* The hidden input inside the autocomplete div that holds the value.
|
||||
* @private
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.hiddenInput_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The URL to be used for autocomplete
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.sourceUrl_ = null;
|
||||
|
||||
|
||||
//
|
||||
// Protected properties
|
||||
//
|
||||
/**
|
||||
* The text input inside the autocomplete div that holds the label.
|
||||
* @protected
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.textInput = null;
|
||||
|
||||
|
||||
//
|
||||
// Public Methods
|
||||
//
|
||||
/**
|
||||
* Handle event triggered by selecting an autocomplete item
|
||||
*
|
||||
* @param {HTMLElement} autocompleteElement The element that triggered
|
||||
* the event.
|
||||
* @param {Event} event The triggered event.
|
||||
* @param {Object} ui The tabs ui data.
|
||||
* @return {boolean} Return value to be passed back
|
||||
* to jQuery.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.itemSelected =
|
||||
function(autocompleteElement, event, ui) {
|
||||
var $hiddenInput, $textInput;
|
||||
|
||||
$hiddenInput = this.hiddenInput_;
|
||||
$textInput = this.textInput;
|
||||
|
||||
// only update the text field if the item has a value
|
||||
// this allows us to return a 'no items' label with
|
||||
// an empty value.
|
||||
|
||||
if (ui.item.value !== '') {
|
||||
$hiddenInput.val(ui.item.value);
|
||||
$textInput.val(ui.item.label);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle event triggered by moving through the autocomplete suggestions.
|
||||
* The default behaviour is to insert the value in the text field. This
|
||||
* handler inserts the label instead.
|
||||
*
|
||||
* @param {HTMLElement} autocompleteElement The element that triggered
|
||||
* the event.
|
||||
* @param {Event} event The triggered event.
|
||||
* @param {Object} ui The tabs ui data.
|
||||
* @return {boolean} Return value to be passed back
|
||||
* to jQuery.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.itemFocused =
|
||||
function(autocompleteElement, event, ui) {
|
||||
var $textInput;
|
||||
|
||||
$textInput = this.textInput;
|
||||
|
||||
if (ui.item.value !== '') {
|
||||
$textInput.val(ui.item.label);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fetch autocomplete results.
|
||||
* @param {HTMLElement} callingElement The calling HTML element.
|
||||
* @param {Object} request The autocomplete search request.
|
||||
* @param {Function} response The response handler function.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.fetchAutocomplete =
|
||||
function(callingElement, request, response) {
|
||||
var $textInput;
|
||||
|
||||
$textInput = this.textInput;
|
||||
$textInput.addClass('spinner');
|
||||
$.post(this.getAutocompleteUrl(), { term: request.term }, function(data) {
|
||||
$textInput.removeClass('spinner');
|
||||
response(data.content);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the autocomplete Url
|
||||
* @return {?string} Autocomplete URL.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.getAutocompleteUrl =
|
||||
function() {
|
||||
return this.sourceUrl_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the autocomplete url
|
||||
* @param {string} url Autocomplete URL.
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.setAutocompleteUrl =
|
||||
function(url) {
|
||||
this.sourceUrl_ = url;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
/**
|
||||
* Text input element blur handler.
|
||||
* @param {HTMLElement} autocompleteElement The element that triggered
|
||||
* the event.
|
||||
* @param {Event} event The blur event.
|
||||
* @param {Object} ui UI.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.textInputBlurHandler_ =
|
||||
function(autocompleteElement, event, ui) {
|
||||
// Make sure we clean the text input if user selected no option
|
||||
// from the available ones but leaved some text behind. This
|
||||
// is needed to avoid bad form validation and to make it clear to
|
||||
// users that they need to select an option.
|
||||
if (this.hiddenInput_.val() === '') {
|
||||
this.textInput.val('');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Synchronize the input field and the hidden field.
|
||||
* @private
|
||||
*/
|
||||
$.pkp.controllers.AutocompleteHandler.prototype.synchronizeFields_ =
|
||||
function() {
|
||||
this.hiddenInput_.val(String(this.textInput.val()));
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
Reference in New Issue
Block a user