Display full names in Allowed Users autocomplete
This commit is contained in:
parent
5341906767
commit
31ed09e607
|
@ -0,0 +1,289 @@
|
|||
/* An auto-complete module for select and input elements that can pull in
|
||||
* a list of terms from an API endpoint (provided using data-module-source).
|
||||
*
|
||||
* source - A url pointing to an API autocomplete endpoint.
|
||||
* interval - The interval between requests in milliseconds (default: 300).
|
||||
* items - The max number of items to display (default: 10)
|
||||
* tags - Boolean attribute if true will create a tag input.
|
||||
* key - A string of the key you want to be the form value to end up on
|
||||
* from the ajax returned results
|
||||
* label - A string of the label you want to appear within the dropdown for
|
||||
* returned results
|
||||
* tokensep - A string that contains characters which will be interpreted
|
||||
* as separators for tags when typed or pasted (default ",").
|
||||
* Examples
|
||||
*
|
||||
* // <input name="tags" data-module="autocomplete" data-module-source="http://" />
|
||||
*
|
||||
*/
|
||||
this.ckan.module('privatedatasets_autocomplete', function (jQuery) {
|
||||
return {
|
||||
/* Options for the module */
|
||||
options: {
|
||||
tags: false,
|
||||
key: false,
|
||||
label: false,
|
||||
items: 10,
|
||||
source: null,
|
||||
tokensep: ',',
|
||||
interval: 300,
|
||||
dropdownClass: '',
|
||||
containerClass: ''
|
||||
},
|
||||
|
||||
/* Sets up the module, binding methods, creating elements etc. Called
|
||||
* internally by ckan.module.initialize();
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
initialize: function () {
|
||||
jQuery.proxyAll(this, /_on/, /format/);
|
||||
this.setupAutoComplete();
|
||||
},
|
||||
|
||||
/* Sets up the auto complete plugin.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
setupAutoComplete: function () {
|
||||
var settings = {
|
||||
width: 'resolve',
|
||||
formatResult: this.formatResult,
|
||||
formatNoMatches: this.formatNoMatches,
|
||||
formatInputTooShort: this.formatInputTooShort,
|
||||
dropdownCssClass: this.options.dropdownClass,
|
||||
containerCssClass: this.options.containerClass,
|
||||
tokenSeparators: this.options.tokensep.split('')
|
||||
};
|
||||
|
||||
// Different keys are required depending on whether the select is
|
||||
// tags or generic completion.
|
||||
if (!this.el.is('select')) {
|
||||
if (this.options.tags) {
|
||||
settings.tags = this._onQuery;
|
||||
} else {
|
||||
settings.query = this._onQuery;
|
||||
settings.createSearchChoice = this.formatTerm;
|
||||
}
|
||||
settings.initSelection = this.formatInitialValue;
|
||||
}
|
||||
else {
|
||||
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
|
||||
var ieversion=new Number(RegExp.$1);
|
||||
if (ieversion<=7) {return}
|
||||
}
|
||||
}
|
||||
|
||||
var select2 = this.el.select2(settings).data('select2');
|
||||
|
||||
if (this.options.tags && select2 && select2.search) {
|
||||
// find the "fake" input created by select2 and add the keypress event.
|
||||
// This is not part of the plugins API and so may break at any time.
|
||||
select2.search.on('keydown', this._onKeydown);
|
||||
}
|
||||
|
||||
// This prevents Internet Explorer from causing a window.onbeforeunload
|
||||
// even from firing unnecessarily
|
||||
$('.select2-choice', select2.container).on('click', function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
this._select2 = select2;
|
||||
},
|
||||
|
||||
/* Looks up the completions for the current search term and passes them
|
||||
* into the provided callback function.
|
||||
*
|
||||
* The results are formatted for use in the select2 autocomplete plugin.
|
||||
*
|
||||
* string - The term to search for.
|
||||
* fn - A callback function.
|
||||
*
|
||||
* Examples
|
||||
*
|
||||
* module.getCompletions('cake', function (results) {
|
||||
* results === {results: []}
|
||||
* });
|
||||
*
|
||||
* Returns a jqXHR promise.
|
||||
*/
|
||||
getCompletions: function (string, fn) {
|
||||
var parts = this.options.source.split('?');
|
||||
var end = parts.pop();
|
||||
var source = parts.join('?') + encodeURIComponent(string) + end;
|
||||
var client = this.sandbox.client;
|
||||
var options = {
|
||||
format: function(data) {
|
||||
var completion_options = jQuery.extend(options, {objects: true});
|
||||
return {
|
||||
results: client.parseCompletions(data, completion_options)
|
||||
}
|
||||
},
|
||||
key: this.options.key,
|
||||
label: this.options.label
|
||||
};
|
||||
|
||||
return client.getCompletions(source, options, fn);
|
||||
},
|
||||
|
||||
/* Looks up the completions for the provided text but also provides a few
|
||||
* optimisations. If there is no search term it will automatically set
|
||||
* an empty array. Ajax requests will also be debounced to ensure that
|
||||
* the server is not overloaded.
|
||||
*
|
||||
* string - The term to search for.
|
||||
* fn - A callback function.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
lookup: function (string, fn) {
|
||||
var module = this;
|
||||
|
||||
// Cache the last searched term otherwise we'll end up searching for
|
||||
// old data.
|
||||
this._lastTerm = string;
|
||||
|
||||
// Kills previous timeout
|
||||
clearTimeout(this._debounced);
|
||||
|
||||
// OK, wipe the dropdown before we start ajaxing the completions
|
||||
fn({results:[]});
|
||||
|
||||
if (string) {
|
||||
// Set a timer to prevent the search lookup occurring too often.
|
||||
this._debounced = setTimeout(function () {
|
||||
var term = module._lastTerm;
|
||||
|
||||
// Cancel the previous request if it hasn't yet completed.
|
||||
if (module._last && typeof module._last.abort == 'function') {
|
||||
module._last.abort();
|
||||
}
|
||||
|
||||
module._last = module.getCompletions(term, fn);
|
||||
|
||||
}, this.options.interval);
|
||||
|
||||
// This forces the ajax throbber to appear, because we've called the
|
||||
// callback already and that hides the throbber
|
||||
$('.select2-search input', this._select2.dropdown).addClass('select2-active');
|
||||
}
|
||||
},
|
||||
|
||||
/* Formatter for the select2 plugin that returns a string for use in the
|
||||
* results list with the current term emboldened.
|
||||
*
|
||||
* state - The current object that is being rendered.
|
||||
* container - The element the content will be added to (added in 3.0)
|
||||
* query - The query object (added in select2 3.0).
|
||||
*
|
||||
*
|
||||
* Returns a text string.
|
||||
*/
|
||||
formatResult: function (state, container, query) {
|
||||
var term = this._lastTerm || null; // same as query.term
|
||||
|
||||
if (container) {
|
||||
// Append the select id to the element for styling.
|
||||
container.attr('data-value', state.id);
|
||||
}
|
||||
|
||||
// if the current string is the actual query, just format that
|
||||
if (state.text === term && state.id === term){
|
||||
var ret = state.text;
|
||||
}
|
||||
// if we're formatting a suggestion, concatenate the full name and
|
||||
// username of the suggestion
|
||||
else {
|
||||
var ret = state.text + " (" + state.id + ")";
|
||||
}
|
||||
|
||||
return ret.split(term).join(term && term.bold());
|
||||
},
|
||||
|
||||
/* Formatter for the select2 plugin that returns a string used when
|
||||
* the filter has no matches.
|
||||
*
|
||||
* Returns a text string.
|
||||
*/
|
||||
formatNoMatches: function (term) {
|
||||
return !term ? this._('Start typing…') : this._('No matches found');
|
||||
},
|
||||
|
||||
/* Formatter used by the select2 plugin that returns a string when the
|
||||
* input is too short.
|
||||
*
|
||||
* Returns a string.
|
||||
*/
|
||||
formatInputTooShort: function (term, min) {
|
||||
return this.ngettext(
|
||||
'Input is too short, must be at least one character',
|
||||
'Input is too short, must be at least %(num)d characters',
|
||||
min
|
||||
);
|
||||
},
|
||||
|
||||
/* Takes a string and converts it into an object used by the select2 plugin.
|
||||
*
|
||||
* term - The term to convert.
|
||||
*
|
||||
* Returns an object for use in select2.
|
||||
*/
|
||||
formatTerm: function (term) {
|
||||
term = jQuery.trim(term || '');
|
||||
|
||||
// Need to replace comma with a unicode character to trick the plugin
|
||||
// as it won't split this into multiple items.
|
||||
return {id: term.replace(/,/g, '\u002C'), text: term};
|
||||
},
|
||||
|
||||
/* Callback function that parses the initial field value.
|
||||
*
|
||||
* element - The initialized input element wrapped in jQuery.
|
||||
* callback - A callback to run once the formatting is complete.
|
||||
*
|
||||
* Returns a term object or an array depending on the type.
|
||||
*/
|
||||
formatInitialValue: function (element, callback) {
|
||||
var value = jQuery.trim(element.val() || '');
|
||||
var formatted;
|
||||
|
||||
if (this.options.tags) {
|
||||
formatted = jQuery.map(value.split(","), this.formatTerm);
|
||||
} else {
|
||||
formatted = this.formatTerm(value);
|
||||
}
|
||||
|
||||
// Select2 v3.0 supports a callback for async calls.
|
||||
if (typeof callback === 'function') {
|
||||
callback(formatted);
|
||||
}
|
||||
|
||||
return formatted;
|
||||
},
|
||||
|
||||
/* Callback triggered when the select2 plugin needs to make a request.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
_onQuery: function (options) {
|
||||
if (options) {
|
||||
this.lookup(options.term, options.callback);
|
||||
}
|
||||
},
|
||||
|
||||
/* Called when a key is pressed. If the key is a comma we block it and
|
||||
* then simulate pressing return.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
_onKeydown: function (event) {
|
||||
if (typeof event.key !== 'undefined' ? event.key === ',' : event.which === 188) {
|
||||
event.preventDefault();
|
||||
setTimeout(function () {
|
||||
var e = jQuery.Event("keydown", { which: 13 });
|
||||
jQuery(event.target).trigger(e);
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
|
@ -51,7 +51,7 @@
|
|||
<span class="info-block info-inline">
|
||||
<i class="icon-info-sign fa fa-info-circle"></i>
|
||||
{% trans %}
|
||||
Private datasets can only be accessed by certain users, while public datasets can be accessed by anyone.
|
||||
Private datasets can only be accessed by certain users, while public datasets can be accessed by anyone.
|
||||
{% endtrans %}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -82,10 +82,12 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% set users_attrs = {'data-module': 'autocomplete', 'data-module-tags': '', 'data-module-source': '/api/2/util/user/autocomplete?q=?'} %}
|
||||
{% resource 'privatedatasets/privatedatasets_autocomplete.js' %}
|
||||
|
||||
{% set users_attrs = {'data-module': 'privatedatasets_autocomplete', 'data-module-tags': '', 'data-module-label': 'fullname', 'data-module-source': '/api/2/util/user/autocomplete?q=?'} %}
|
||||
{{ form.input('allowed_users_str', label=_('Allowed Users'), id='field-allowed_users_str', placeholder=_('Allowed Users'), value=h.get_allowed_users_str(data.allowed_users), error=errors.custom_text, classes=['control-full'], attrs=users_attrs) }}
|
||||
|
||||
|
||||
|
||||
{% if editing and h.show_acquire_url_on_edit() or not editing and h.show_acquire_url_on_create() %}
|
||||
{{ form.input('acquire_url', label=_('Acquire URL'), id='field-acquire_url', placeholder=_('http://example.com/acquire/'), value=data.acquire_url, error=errors.custom_text, classes=['control-medium']) }}
|
||||
{% else %}
|
||||
|
|
Loading…
Reference in New Issue