diff --git a/Resources/public/js/adapter/fancytree.js b/Resources/public/js/adapter/fancytree.js index d793a86..693aa1e 100644 --- a/Resources/public/js/adapter/fancytree.js +++ b/Resources/public/js/adapter/fancytree.js @@ -195,6 +195,10 @@ addAction: function (name, url, icon) { this.actions[name] = { url: url, icon: icon }; + }, + + getFromCache: function (name) { + return cache.hasOwnProperty(name) ? cache[name] : undefined; } }; diff --git a/Resources/public/js/jquery.cmf_autocomplete.js b/Resources/public/js/jquery.cmf_autocomplete.js new file mode 100644 index 0000000..93e5a49 --- /dev/null +++ b/Resources/public/js/jquery.cmf_autocomplete.js @@ -0,0 +1,85 @@ +!function () { + var cache = []; + + /** + * A small plugin to add autocompletion features for paths + * in browsers. + * + * @author Wouter J + */ + window.jQuery.fn.cmfAutoComplete = function (options) { + options = jQuery.extend({ + /** + * The element used to show the suggestions. + * + * This has to be a element. + * + * @var string|null A selector or use the selector in + * the `list` attribute (when null is used) + */ + datalist_selector: null, + + /** + * A callback to retrieve the data. + * + * @return array + */ + data: function (path, next) { next([]); }, + }, options); + + var $input = $(this); + var $autocompleteList; + var previousBase; + + // find datalist + if (options.datalist_selector) { + $autocompleteList = $(options.datalist_selector); + $(this).attr('list', options.datalist_selector); + } else if ($(this).attr('list')) { + $autocompleteList = $('#' + $(this).attr('list')); + } else { + throw 'No datalist selected'; + } + + if ('DATALIST' !== $autocompleteList.prop('tagName')) { + throw 'The configured datalist element should be a element, <' + $autocompleteList.prop('tagName').toLowerCase() + '> given.'; + } + + // find autocompletion values + $input.on('keyup', function (e) { + // arrows are used to navigate through the data list, don't update it then + if (e.keyCode >= 37 && e.keyCode <= 40) { + return; + } + + var path = $(this).val(); + var base = path.substr(0, path.lastIndexOf('/')); // get everything except the child + + // skip if still in same node + if (base === previousBase) { + return; + } + previousBase = base; + + // cache node + if (!cache[base]) { + options.data(base, function (nodes) { + cache[base] = nodes; + updateAutocompleteList(base); + }); + } else { + updateAutocompleteList(base); + } + }); + + function updateAutocompleteList(base) { + // clear datalist + $autocompleteList.empty(); + + // add new autocomplete values + cache[base].forEach(function (child) { + $autocompleteList.append('