LibreNMS/lib/typeahead/src/typeahead/plugin.js

292 lines
7.4 KiB
JavaScript

/*
* typeahead.js
* https://github.com/twitter/typeahead.js
* Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
*/
(function() {
'use strict';
var old, keys, methods;
old = $.fn.typeahead;
keys = {
www: 'tt-www',
attrs: 'tt-attrs',
typeahead: 'tt-typeahead'
};
methods = {
// supported signatures:
// function(o, dataset, dataset, ...)
// function(o, [dataset, dataset, ...])
initialize: function initialize(o, datasets) {
var www;
datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
o = o || {};
www = WWW(o.classNames);
return this.each(attach);
function attach() {
var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu,
eventBus, input, menu, typeahead, MenuConstructor;
// highlight is a top-level config that needs to get inherited
// from all of the datasets
_.each(datasets, function(d) { d.highlight = !!o.highlight; });
$input = $(this);
$wrapper = $(www.html.wrapper);
$hint = $elOrNull(o.hint);
$menu = $elOrNull(o.menu);
defaultHint = o.hint !== false && !$hint;
defaultMenu = o.menu !== false && !$menu;
defaultHint && ($hint = buildHintFromInput($input, www));
defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
// hint should be empty on init
$hint && $hint.val('');
$input = prepInput($input, www);
// only apply inline styles and make dom changes if necessary
if (defaultHint || defaultMenu) {
$wrapper.css(www.css.wrapper);
$input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
$input
.wrap($wrapper)
.parent()
.prepend(defaultHint ? $hint : null)
.append(defaultMenu ? $menu : null);
}
MenuConstructor = defaultMenu ? DefaultMenu : Menu;
eventBus = new EventBus({ el: $input });
input = new Input({ hint: $hint, input: $input, }, www);
menu = new MenuConstructor({
node: $menu,
datasets: datasets
}, www);
typeahead = new Typeahead({
input: input,
menu: menu,
eventBus: eventBus,
minLength: o.minLength
}, www);
$input.data(keys.www, www);
$input.data(keys.typeahead, typeahead);
}
},
isEnabled: function isEnabled() {
var enabled;
ttEach(this.first(), function(t) { enabled = t.isEnabled(); });
return enabled;
},
enable: function enable() {
ttEach(this, function(t) { t.enable(); });
return this;
},
disable: function disable() {
ttEach(this, function(t) { t.disable(); });
return this;
},
isActive: function isActive() {
var active;
ttEach(this.first(), function(t) { active = t.isActive(); });
return active;
},
activate: function activate() {
ttEach(this, function(t) { t.activate(); });
return this;
},
deactivate: function deactivate() {
ttEach(this, function(t) { t.deactivate(); });
return this;
},
isOpen: function isOpen() {
var open;
ttEach(this.first(), function(t) { open = t.isOpen(); });
return open;
},
open: function open() {
ttEach(this, function(t) { t.open(); });
return this;
},
close: function close() {
ttEach(this, function(t) { t.close(); });
return this;
},
select: function select(el) {
var success = false, $el = $(el);
ttEach(this.first(), function(t) { success = t.select($el); });
return success;
},
autocomplete: function autocomplete(el) {
var success = false, $el = $(el);
ttEach(this.first(), function(t) { success = t.autocomplete($el); });
return success;
},
moveCursor: function moveCursoe(delta) {
var success = false;
ttEach(this.first(), function(t) { success = t.moveCursor(delta); });
return success;
},
// mirror jQuery#val functionality: reads operate on first match,
// write operates on all matches
val: function val(newVal) {
var query;
if (!arguments.length) {
ttEach(this.first(), function(t) { query = t.getVal(); });
return query;
}
else {
ttEach(this, function(t) { t.setVal(_.toStr(newVal)); });
return this;
}
},
destroy: function destroy() {
ttEach(this, function(typeahead, $input) {
revert($input);
typeahead.destroy();
});
return this;
}
};
$.fn.typeahead = function(method) {
// methods that should only act on initialized typeaheads
if (methods[method]) {
return methods[method].apply(this, [].slice.call(arguments, 1));
}
else {
return methods.initialize.apply(this, arguments);
}
};
$.fn.typeahead.noConflict = function noConflict() {
$.fn.typeahead = old;
return this;
};
// helper methods
// --------------
function ttEach($els, fn) {
$els.each(function() {
var $input = $(this), typeahead;
(typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
});
}
function buildHintFromInput($input, www) {
return $input.clone()
.addClass(www.classes.hint)
.removeData()
.css(www.css.hint)
.css(getBackgroundStyles($input))
.prop('readonly', true)
.removeAttr('id name placeholder required')
.attr({ autocomplete: 'off', spellcheck: 'false', tabindex: -1 });
}
function prepInput($input, www) {
// store the original values of the attrs that get modified
// so modifications can be reverted on destroy
$input.data(keys.attrs, {
dir: $input.attr('dir'),
autocomplete: $input.attr('autocomplete'),
spellcheck: $input.attr('spellcheck'),
style: $input.attr('style')
});
$input
.addClass(www.classes.input)
.attr({ autocomplete: 'off', spellcheck: false });
// ie7 does not like it when dir is set to auto
try { !$input.attr('dir') && $input.attr('dir', 'auto'); } catch (e) {}
return $input;
}
function getBackgroundStyles($el) {
return {
backgroundAttachment: $el.css('background-attachment'),
backgroundClip: $el.css('background-clip'),
backgroundColor: $el.css('background-color'),
backgroundImage: $el.css('background-image'),
backgroundOrigin: $el.css('background-origin'),
backgroundPosition: $el.css('background-position'),
backgroundRepeat: $el.css('background-repeat'),
backgroundSize: $el.css('background-size')
};
}
function revert($input) {
var www, $wrapper;
www = $input.data(keys.www);
$wrapper = $input.parent().filter(www.selectors.wrapper);
// need to remove attrs that weren't previously defined and
// revert attrs that originally had a value
_.each($input.data(keys.attrs), function(val, key) {
_.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
});
$input
.removeData(keys.typeahead)
.removeData(keys.www)
.removeData(keys.attr)
.removeClass(www.classes.input);
if ($wrapper.length) {
$input.detach().insertAfter($wrapper);
$wrapper.remove();
}
}
function $elOrNull(obj) {
var isValid, $el;
isValid = _.isJQuery(obj) || _.isElement(obj);
$el = isValid ? $(obj).first() : [];
return $el.length ? $el : null;
}
})();