mirror of
https://github.com/Neetpone/ponepaste.git
synced 2025-03-12 22:50:07 +01:00
2716 lines
85 KiB
JavaScript
2716 lines
85 KiB
JavaScript
/*!
|
|
* Tokenize2 v1.3.3 (https://github.com/dragonofmercy/Tokenize2)
|
|
* Copyright 2016-2017 DragonOfMercy.
|
|
* Licensed under the new BSD license
|
|
*/
|
|
(function (factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define(['jquery'], factory);
|
|
} else if (typeof module === 'object' && module.exports) {
|
|
// Node/CommonJS
|
|
module.exports = function (root, jQuery) {
|
|
if (jQuery === undefined) {
|
|
// require('jQuery') returns a factory that requires window to
|
|
// build a jQuery instance, we normalize how we use modules
|
|
// that require this pattern but the window provided is a noop
|
|
// if it's defined (how jquery works)
|
|
if (typeof window !== 'undefined') {
|
|
jQuery = require('jquery');
|
|
} else {
|
|
jQuery = require('jquery')(root);
|
|
}
|
|
}
|
|
factory(jQuery);
|
|
return jQuery;
|
|
};
|
|
} else {
|
|
// Browser globals
|
|
factory(jQuery);
|
|
}
|
|
}(function ($) {
|
|
/**
|
|
* Tokenize2 constructor.
|
|
*
|
|
* @param {object} element
|
|
* @param {object} options
|
|
* @constructor
|
|
*/
|
|
var Tokenize2 = function (element, options) {
|
|
|
|
this.control = false;
|
|
this.element = $(element);
|
|
this.options = $.extend({}, Tokenize2.DEFAULTS, options);
|
|
|
|
this.options.tabIndex = this.options.tabIndex === -1 ? 0 : this.options.tabIndex;
|
|
this.options.sortable = this.options.tokensMaxItems === 1 ? false : this.options.sortable;
|
|
|
|
this.bind();
|
|
this.trigger('tokenize:load');
|
|
|
|
};
|
|
|
|
/**
|
|
* Keycodes constants
|
|
*
|
|
* @type {object}
|
|
*/
|
|
var KEYS = {
|
|
BACKSPACE: 8,
|
|
TAB: 9,
|
|
ENTER: 13,
|
|
ESCAPE: 27,
|
|
ARROW_UP: 38,
|
|
ARROW_DOWN: 40,
|
|
CTRL: 17,
|
|
MAJ: 16
|
|
};
|
|
|
|
Tokenize2.VERSION = '1.3.3';
|
|
Tokenize2.DEBOUNCE = null;
|
|
Tokenize2.DEFAULTS = {
|
|
tokensMaxItems: 0,
|
|
tokensAllowCustom: false,
|
|
dropdownMaxItems: 10,
|
|
dropdownSelectFirstItem: true,
|
|
searchMinLength: 0,
|
|
searchMaxLength: 0,
|
|
searchFromStart: true,
|
|
searchHighlight: true,
|
|
displayNoResultsMessage: false,
|
|
noResultsMessageText: 'No results mached "%s"',
|
|
delimiter: ',',
|
|
dataSource: 'select',
|
|
debounce: 0,
|
|
placeholder: false,
|
|
sortable: false,
|
|
allowEmptyValues: false,
|
|
zIndexMargin: 500,
|
|
tabIndex: 0
|
|
};
|
|
|
|
/**
|
|
* Trigger an event
|
|
*
|
|
* @see $.trigger
|
|
*/
|
|
Tokenize2.prototype.trigger = function (event, data, elem, onlyHandlers) {
|
|
|
|
this.element.trigger(event, data, elem, onlyHandlers);
|
|
|
|
};
|
|
|
|
/**
|
|
* Bind events
|
|
*/
|
|
Tokenize2.prototype.bind = function () {
|
|
|
|
this.element.on('tokenize:load', {}, $.proxy(function () {
|
|
this.init()
|
|
}, this))
|
|
.on('tokenize:clear', {}, $.proxy(function () {
|
|
this.clear()
|
|
}, this))
|
|
.on('tokenize:remap', {}, $.proxy(function () {
|
|
this.remap()
|
|
}, this))
|
|
.on('tokenize:select', {}, $.proxy(function (e, c) {
|
|
this.focus(c)
|
|
}, this))
|
|
.on('tokenize:deselect', {}, $.proxy(function () {
|
|
this.blur()
|
|
}, this))
|
|
.on('tokenize:search', {}, $.proxy(function (e, v) {
|
|
this.find(v)
|
|
}, this))
|
|
.on('tokenize:paste', {}, $.proxy(function () {
|
|
this.paste()
|
|
}, this))
|
|
.on('tokenize:dropdown:up', {}, $.proxy(function () {
|
|
this.dropdownSelectionMove(-1)
|
|
}, this))
|
|
.on('tokenize:dropdown:down', {}, $.proxy(function () {
|
|
this.dropdownSelectionMove(1)
|
|
}, this))
|
|
.on('tokenize:dropdown:clear', {}, $.proxy(function () {
|
|
this.dropdownClear()
|
|
}, this))
|
|
.on('tokenize:dropdown:show', {}, $.proxy(function () {
|
|
this.dropdownShow()
|
|
}, this))
|
|
.on('tokenize:dropdown:hide', {}, $.proxy(function () {
|
|
this.dropdownHide()
|
|
}, this))
|
|
.on('tokenize:dropdown:fill', {}, $.proxy(function (e, i) {
|
|
this.dropdownFill(i)
|
|
}, this))
|
|
.on('tokenize:dropdown:itemAdd', {}, $.proxy(function (e, i) {
|
|
this.dropdownAddItem(i)
|
|
}, this))
|
|
.on('tokenize:keypress', {}, $.proxy(function (e, routedEvent) {
|
|
this.keypress(routedEvent)
|
|
}, this))
|
|
.on('tokenize:keydown', {}, $.proxy(function (e, routedEvent) {
|
|
this.keydown(routedEvent)
|
|
}, this))
|
|
.on('tokenize:keyup', {}, $.proxy(function (e, routedEvent) {
|
|
this.keyup(routedEvent)
|
|
}, this))
|
|
.on('tokenize:tokens:reorder', {}, $.proxy(function () {
|
|
this.reorder()
|
|
}, this))
|
|
.on('tokenize:tokens:add', {}, $.proxy(function (e, v, t, c) {
|
|
this.tokenAdd(v, t, c)
|
|
}, this))
|
|
.on('tokenize:tokens:remove', {}, $.proxy(function (e, v) {
|
|
this.tokenRemove(v)
|
|
}, this));
|
|
|
|
};
|
|
|
|
/**
|
|
* Init function
|
|
*/
|
|
Tokenize2.prototype.init = function () {
|
|
|
|
this.id = this.guid();
|
|
this.element.hide();
|
|
|
|
if (!this.element.attr('multiple')) {
|
|
console.error('Attribute multiple is missing, tokenize2 can be buggy !')
|
|
}
|
|
|
|
this.dropdown = undefined;
|
|
this.searchContainer = $('<li class="token-search" />');
|
|
this.input = $('<input autocomplete="off" />')
|
|
.on('keydown', {}, $.proxy(function (e) {
|
|
this.trigger('tokenize:keydown', [e])
|
|
}, this))
|
|
.on('keypress', {}, $.proxy(function (e) {
|
|
this.trigger('tokenize:keypress', [e])
|
|
}, this))
|
|
.on('keyup', {}, $.proxy(function (e) {
|
|
this.trigger('tokenize:keyup', [e])
|
|
}, this))
|
|
.on('focus', {}, $.proxy(function () {
|
|
if (this.input.val().length >= this.options.searchMinLength && this.input.val().length > 0) {
|
|
this.trigger('tokenize:search', [this.input.val()]);
|
|
}
|
|
}, this))
|
|
.on('paste', {}, $.proxy(function () {
|
|
if (this.options.tokensAllowCustom) {
|
|
setTimeout($.proxy(function () {
|
|
this.trigger('tokenize:paste');
|
|
}, this), 10);
|
|
}
|
|
}, this));
|
|
|
|
if (this.options.searchMaxLength > 0) {
|
|
this.input.attr('maxlength', this.options.searchMaxLength);
|
|
}
|
|
|
|
this.tokensContainer = $('<ul class="tokens-container form-control" />')
|
|
.addClass(this.element.attr('data-class'))
|
|
.attr('tabindex', this.options.tabIndex)
|
|
.append(this.searchContainer.append(this.input));
|
|
|
|
if (this.options.placeholder !== false) {
|
|
this.placeholder = $('<li class="placeholder" />').html(this.options.placeholder);
|
|
this.tokensContainer.prepend(this.placeholder);
|
|
this.element.on('tokenize:tokens:add tokenize:remap tokenize:select tokenize:deselect tokenize:tokens:remove', $.proxy(function () {
|
|
if (this.container.hasClass('focus') || $('li.token', this.tokensContainer).length > 0 || this.input.val().length > 0) {
|
|
this.placeholder.hide();
|
|
} else {
|
|
this.placeholder.show();
|
|
}
|
|
}, this));
|
|
}
|
|
|
|
this.container = $('<div class="tokenize" />').attr('id', this.id);
|
|
this.container.append(this.tokensContainer).insertAfter(this.element);
|
|
this.container.focusin($.proxy(function (e) {
|
|
this.trigger('tokenize:select', [($(e.target)[0] === this.tokensContainer[0])]);
|
|
}, this))
|
|
.focusout($.proxy(function () {
|
|
if (this.container.hasClass('focus')) {
|
|
this.trigger('tokenize:deselect')
|
|
}
|
|
}, this));
|
|
|
|
if (this.options.tokensMaxItems === 1) {
|
|
this.container.addClass('single');
|
|
}
|
|
|
|
if (this.options.sortable) {
|
|
this.container.addClass('sortable');
|
|
this.tokensContainer.tokenize2sortable({
|
|
itemSelector: 'li.token',
|
|
cursor: 'move',
|
|
placeholder: '<li class="token shadow"><br /></li>',
|
|
placeholderClass: 'token shadow',
|
|
onDragStart: $.proxy(function ($item, container, _super) {
|
|
this.searchContainer.hide();
|
|
_super($item, container);
|
|
}, this),
|
|
onDrop: $.proxy(function ($item, container, _super) {
|
|
this.searchContainer.show();
|
|
this.trigger('tokenize:tokens:reorder');
|
|
_super($item, container);
|
|
}, this)
|
|
});
|
|
}
|
|
|
|
this.element
|
|
.on('tokenize:tokens:add tokenize:tokens:remove', $.proxy(function () {
|
|
if (this.options.tokensMaxItems > 0 && $('li.token', this.tokensContainer).length >= this.options.tokensMaxItems) {
|
|
this.searchContainer.hide();
|
|
} else {
|
|
this.searchContainer.show();
|
|
}
|
|
}, this))
|
|
.on('tokenize:keydown tokenize:keyup tokenize:loaded', $.proxy(function () {
|
|
this.scaleInput();
|
|
}, this));
|
|
|
|
this.trigger('tokenize:remap');
|
|
this.trigger('tokenize:tokens:reorder');
|
|
this.trigger('tokenize:loaded');
|
|
|
|
if (this.element.is(':disabled')) {
|
|
this.disable();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Reorder tokens in the select
|
|
*/
|
|
Tokenize2.prototype.reorder = function () {
|
|
|
|
if (this.options.sortable) {
|
|
var previous, current, data = this.tokensContainer.tokenize2sortable('serialize').get(0);
|
|
$.each(data, $.proxy(function (k, v) {
|
|
current = $('option[value="' + v.value + '"]', this.element);
|
|
if (previous === undefined) {
|
|
current.prependTo(this.element);
|
|
} else {
|
|
previous.after(current);
|
|
}
|
|
previous = current;
|
|
}, this));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Transform clipboard item to tokens
|
|
*/
|
|
Tokenize2.prototype.paste = function () {
|
|
|
|
var $pattern = new RegExp(this.escapeRegex(Array.isArray(this.options.delimiter) ? this.options.delimiter.join('|') : this.options.delimiter), 'ig');
|
|
|
|
if ($pattern.test(this.input.val())) {
|
|
$.each(this.input.val().split($pattern), $.proxy(function (_, value) {
|
|
this.trigger('tokenize:tokens:add', [value, null, true]);
|
|
}, this))
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Add token
|
|
*
|
|
* If text is empty text = value
|
|
*
|
|
* @param {string} value
|
|
* @param {string} text
|
|
* @param {boolean} force
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.tokenAdd = function (value, text, force) {
|
|
|
|
value = this.escape(value);
|
|
text = this.escape(text) || value;
|
|
force = force || false;
|
|
this.resetInput();
|
|
|
|
// Check if token is empty
|
|
if (value === undefined || (!this.options.allowEmptyValues && value === '')) {
|
|
this.trigger('tokenize:tokens:error:empty');
|
|
return this;
|
|
}
|
|
|
|
// Check if max number of token is reached
|
|
if (this.options.tokensMaxItems > 0 && $('li.token', this.tokensContainer).length >= this.options.tokensMaxItems) {
|
|
this.trigger('tokenize:tokens:error:max');
|
|
return this;
|
|
}
|
|
|
|
// Check duplicate token
|
|
if ($('li.token[data-value="' + value + '"]', this.tokensContainer).length > 0) {
|
|
this.trigger('tokenize:tokens:error:duplicate', [value, text]);
|
|
return this;
|
|
}
|
|
|
|
if ($('option[value="' + value + '"]', this.element).length) {
|
|
$('option[value="' + value + '"]', this.element).attr('selected', 'selected').prop('selected', true);
|
|
} else if (force) {
|
|
this.element.append($('<option selected />').val(value).html(text));
|
|
} else if (this.options.tokensAllowCustom) {
|
|
this.element.append($('<option selected data-type="custom" />').val(value).html(text));
|
|
} else {
|
|
this.trigger('tokenize:tokens:error:notokensAllowCustom');
|
|
return this;
|
|
}
|
|
|
|
$('<li class="token" />')
|
|
.attr('data-value', value)
|
|
.append('<span>' + text + '</span>')
|
|
.prepend($('<a class="dismiss" />').on('mousedown touchstart', {}, $.proxy(function (e) {
|
|
e.preventDefault();
|
|
if (e.which == 1) {
|
|
this.trigger('tokenize:tokens:remove', [value]);
|
|
}
|
|
}, this)))
|
|
.insertBefore(this.searchContainer);
|
|
|
|
this.trigger('tokenize:dropdown:hide');
|
|
this.trigger('tokenize:tokens:added', [value, text]);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Remove token
|
|
*
|
|
* @param {string} v
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.tokenRemove = function (v) {
|
|
|
|
var $item = $('option[value="' + v + '"]', this.element);
|
|
|
|
if ($item.attr('data-type') === 'custom') {
|
|
$item.remove();
|
|
} else {
|
|
$item.removeAttr('selected').prop('selected', false);
|
|
}
|
|
|
|
$('li.token[data-value="' + v + '"]', this.tokensContainer).remove();
|
|
|
|
this.trigger('tokenize:tokens:reorder');
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Refresh tokens reflecting selected options
|
|
*
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.remap = function () {
|
|
|
|
var $selected = $('option:selected', this.element);
|
|
$selected.each($.proxy(function (v, t) {
|
|
this.trigger('tokenize:tokens:add', [$(t).val(), $(t).html(), false]);
|
|
}, this));
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Disable tokenize
|
|
*
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.disable = function () {
|
|
|
|
this.tokensContainer.addClass('disabled');
|
|
this.searchContainer.hide();
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Enable tokenize
|
|
*
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.enable = function () {
|
|
|
|
this.tokensContainer.removeClass('disabled');
|
|
this.searchContainer.show();
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Focus
|
|
*
|
|
* @param {boolean} container
|
|
*/
|
|
Tokenize2.prototype.focus = function (container) {
|
|
|
|
if (this.element.is(':disabled')) {
|
|
this.tokensContainer.blur();
|
|
return;
|
|
}
|
|
|
|
if (container) {
|
|
this.input.focus();
|
|
}
|
|
|
|
if (!this.container.hasClass('focus')) {
|
|
this.container.addClass('focus');
|
|
this.trigger('tokenize:focus');
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Blur
|
|
*/
|
|
Tokenize2.prototype.blur = function () {
|
|
|
|
if (this.isDropdownOpen()) {
|
|
this.trigger('tokenize:dropdown:hide');
|
|
}
|
|
this.container.removeClass('focus');
|
|
this.resetPending();
|
|
if (!this.tokensContainer.attr('tabindex')) {
|
|
this.tokensContainer.attr('tabindex', this.options.tabIndex);
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Keydown
|
|
*
|
|
* @param {Event} e
|
|
*/
|
|
Tokenize2.prototype.keydown = function (e) {
|
|
|
|
if (e.type === 'keydown') {
|
|
switch (e.keyCode) {
|
|
case KEYS.BACKSPACE:
|
|
if (this.input.val().length < 1) {
|
|
e.preventDefault();
|
|
if ($('li.token.pending-delete', this.tokensContainer).length > 0) {
|
|
this.trigger('tokenize:tokens:remove', [$('li.token.pending-delete', this.tokensContainer).first().attr('data-value')]);
|
|
} else {
|
|
var $token = $('li.token:last', this.tokensContainer);
|
|
if ($token.length > 0) {
|
|
this.trigger('tokenize:tokens:markForDelete', [$token.attr('data-value')]);
|
|
$token.addClass('pending-delete');
|
|
}
|
|
}
|
|
this.trigger('tokenize:dropdown:hide');
|
|
}
|
|
break;
|
|
|
|
case KEYS.TAB:
|
|
if (!e.shiftKey) {
|
|
this.pressedDelimiter(e);
|
|
} else {
|
|
this.tokensContainer.removeAttr('tabindex');
|
|
}
|
|
break;
|
|
|
|
case KEYS.ENTER:
|
|
this.pressedDelimiter(e);
|
|
break;
|
|
|
|
case KEYS.ESCAPE:
|
|
this.resetPending();
|
|
break;
|
|
|
|
case KEYS.ARROW_UP:
|
|
e.preventDefault();
|
|
this.trigger('tokenize:dropdown:up');
|
|
break;
|
|
|
|
case KEYS.ARROW_DOWN:
|
|
e.preventDefault();
|
|
this.trigger('tokenize:dropdown:down');
|
|
break;
|
|
|
|
case KEYS.CTRL:
|
|
this.control = true;
|
|
break;
|
|
|
|
default:
|
|
this.resetPending();
|
|
break;
|
|
|
|
}
|
|
} else {
|
|
e.preventDefault();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Keyup
|
|
*
|
|
* @param {Event} e
|
|
*/
|
|
Tokenize2.prototype.keyup = function (e) {
|
|
|
|
if (e.type === 'keyup') {
|
|
switch (e.keyCode) {
|
|
case KEYS.TAB:
|
|
case KEYS.ENTER:
|
|
case KEYS.ESCAPE:
|
|
case KEYS.ARROW_UP:
|
|
case KEYS.ARROW_DOWN:
|
|
case KEYS.MAJ:
|
|
break;
|
|
case KEYS.CTRL:
|
|
this.control = false;
|
|
break;
|
|
case KEYS.BACKSPACE:
|
|
default:
|
|
if (this.input.val().length >= this.options.searchMinLength && this.input.val().length > 0) {
|
|
this.trigger('tokenize:search', [this.input.val()]);
|
|
} else {
|
|
this.trigger('tokenize:dropdown:hide');
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
e.preventDefault();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Keypress
|
|
*
|
|
* @param {Event} e
|
|
*/
|
|
Tokenize2.prototype.keypress = function (e) {
|
|
|
|
if (e.type === 'keypress' && !this.element.is(':disabled')) {
|
|
var $delimiter = false;
|
|
|
|
if (Array.isArray(this.options.delimiter)) {
|
|
if (this.options.delimiter.indexOf(String.fromCharCode(e.which)) >= 0) {
|
|
$delimiter = true;
|
|
}
|
|
} else {
|
|
if (String.fromCharCode(e.which) === this.options.delimiter) {
|
|
$delimiter = true;
|
|
}
|
|
}
|
|
|
|
if ($delimiter) {
|
|
this.pressedDelimiter(e);
|
|
}
|
|
} else {
|
|
e.preventDefault();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* When a delimiter is pressed
|
|
*
|
|
* @param {Event} e
|
|
*/
|
|
Tokenize2.prototype.pressedDelimiter = function (e) {
|
|
|
|
this.resetPending();
|
|
if (this.isDropdownOpen() && $('li.active', this.dropdown).length > 0 && this.control === false) {
|
|
e.preventDefault();
|
|
$('li.active a', this.dropdown).trigger('mousedown');
|
|
} else {
|
|
if (this.input.val().length > 0) {
|
|
e.preventDefault();
|
|
this.trigger('tokenize:tokens:add', [this.input.val()]);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Search value
|
|
*
|
|
* @param {string} v
|
|
*/
|
|
Tokenize2.prototype.find = function (v) {
|
|
|
|
if (v.length < this.options.searchMinLength) {
|
|
this.trigger('tokenize:dropdown:hide');
|
|
return false;
|
|
}
|
|
|
|
this.lastSearchTerms = v;
|
|
|
|
if (this.options.dataSource === 'select') {
|
|
this.dataSourceLocal(v);
|
|
} else if (typeof this.options.dataSource === 'function') {
|
|
this.options.dataSource(v, this);
|
|
} else {
|
|
this.dataSourceRemote(v);
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Gets data from ajax
|
|
*
|
|
* @param {string} search
|
|
*/
|
|
Tokenize2.prototype.dataSourceRemote = function (search) {
|
|
|
|
this.debounce($.proxy(function () {
|
|
if (this.xhr !== undefined) {
|
|
this.xhr.abort();
|
|
}
|
|
this.xhr = $.ajax(this.options.dataSource, {
|
|
data: {search: search},
|
|
dataType: 'text',
|
|
success: $.proxy(function (data) {
|
|
var $items = [];
|
|
if (data != '') {
|
|
data = JSON.parse(data);
|
|
$.each(data, function (k, v) {
|
|
$items.push(v);
|
|
});
|
|
}
|
|
this.trigger('tokenize:dropdown:fill', [$items]);
|
|
}, this)
|
|
});
|
|
}, this), this.options.debounce);
|
|
|
|
};
|
|
|
|
/**
|
|
* Gets data from select
|
|
*
|
|
* @param {string} search
|
|
*/
|
|
Tokenize2.prototype.dataSourceLocal = function (search) {
|
|
|
|
var $searchString = this.transliteration(search);
|
|
var $items = [];
|
|
var $pattern = (this.options.searchFromStart ? '^' : '') + this.escapeRegex($searchString);
|
|
var $regexp = new RegExp($pattern, 'i');
|
|
var $this = this;
|
|
|
|
$('option', this.element)
|
|
.not(':selected, :disabled')
|
|
.each(function () {
|
|
var text = $this.trim($(this).html());
|
|
var value = $this.trim($(this).attr('value'));
|
|
if ($regexp.test($this.transliteration(text))) {
|
|
$items.push({value: value, text: text});
|
|
}
|
|
});
|
|
|
|
this.trigger('tokenize:dropdown:fill', [$items]);
|
|
|
|
};
|
|
|
|
/**
|
|
* Debounce method for ajax request
|
|
*
|
|
* @param {function} func
|
|
* @param {number} threshold
|
|
*/
|
|
Tokenize2.prototype.debounce = function (func, threshold) {
|
|
|
|
var $args = arguments;
|
|
var $delayed = $.proxy(function () {
|
|
func.apply(this, $args);
|
|
this.debounceTimeout = undefined;
|
|
}, this);
|
|
|
|
if (this.debounceTimeout !== undefined) {
|
|
clearTimeout(this.debounceTimeout);
|
|
}
|
|
|
|
this.debounceTimeout = setTimeout($delayed, threshold || 0);
|
|
|
|
};
|
|
|
|
/**
|
|
* Show dropdown
|
|
*/
|
|
Tokenize2.prototype.dropdownShow = function () {
|
|
|
|
if (!this.isDropdownOpen()) {
|
|
$('.tokenize-dropdown').remove();
|
|
this.dropdown = $('<div class="tokenize-dropdown dropdown"><ul class="dropdown-menu" /></div>').attr('data-related', this.id);
|
|
$('body').append(this.dropdown);
|
|
this.dropdown.show();
|
|
this.dropdown.css('z-index', this.calculatezindex() + this.options.zIndexMargin);
|
|
$(window).on('resize scroll', {}, $.proxy(function () {
|
|
this.dropdownMove()
|
|
}, this)).trigger('resize');
|
|
this.trigger('tokenize:dropdown:shown');
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Calculate z-index
|
|
*
|
|
* @returns {int}
|
|
*/
|
|
Tokenize2.prototype.calculatezindex = function () {
|
|
|
|
var el = this.container;
|
|
var zindex = 0;
|
|
|
|
if (!isNaN(parseInt(el.css('z-index'))) && parseInt(el.css('z-index')) > 0) {
|
|
zindex = parseInt(el.css('z-index'));
|
|
}
|
|
|
|
if (zindex < 1) {
|
|
while (el.length) {
|
|
el = el.parent();
|
|
if (el.length > 0) {
|
|
if (!isNaN(parseInt(el.css('z-index'))) && parseInt(el.css('z-index')) > 0) {
|
|
return parseInt(el.css('z-index'));
|
|
}
|
|
if (el.is('html')) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return zindex;
|
|
|
|
};
|
|
|
|
/**
|
|
* Hide dropdown
|
|
*/
|
|
Tokenize2.prototype.dropdownHide = function () {
|
|
|
|
if (this.isDropdownOpen()) {
|
|
$(window).off('resize scroll');
|
|
this.dropdown.remove();
|
|
this.dropdown = undefined;
|
|
this.trigger('tokenize:dropdown:hidden');
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Clear dropdown
|
|
*/
|
|
Tokenize2.prototype.dropdownClear = function () {
|
|
|
|
if (this.dropdown) {
|
|
this.dropdown.find('.dropdown-menu li').remove();
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Fill dropdown with options
|
|
*
|
|
* @param {object} items
|
|
*/
|
|
Tokenize2.prototype.dropdownFill = function (items) {
|
|
|
|
if (items && items.length > 0) {
|
|
this.trigger('tokenize:dropdown:show');
|
|
this.trigger('tokenize:dropdown:clear');
|
|
|
|
$.each(items, $.proxy(function (k, v) {
|
|
if ($('li.dropdown-item', this.dropdown).length <= this.options.dropdownMaxItems) {
|
|
this.trigger('tokenize:dropdown:itemAdd', [v]);
|
|
}
|
|
}, this));
|
|
|
|
if ($('li.active', this.dropdown).length < 1 && this.options.dropdownSelectFirstItem) {
|
|
$('li:first', this.dropdown).addClass('active');
|
|
}
|
|
|
|
if ($('li.dropdown-item', this.dropdown).length < 1) {
|
|
this.trigger('tokenize:dropdown:hide');
|
|
} else {
|
|
this.trigger('tokenize:dropdown:filled');
|
|
}
|
|
} else {
|
|
if (this.options.displayNoResultsMessage) {
|
|
this.trigger('tokenize:dropdown:show');
|
|
this.trigger('tokenize:dropdown:clear');
|
|
this.dropdown.find('.dropdown-menu').append(
|
|
$('<li class="dropdown-item locked" />').html(this.options.noResultsMessageText.replace('%s', this.input.val()))
|
|
);
|
|
} else {
|
|
this.trigger('tokenize:dropdown:hide');
|
|
}
|
|
}
|
|
|
|
// Fix the dropdown position when page start scroll
|
|
$(window).trigger('resize');
|
|
|
|
};
|
|
|
|
/**
|
|
* Move selection through dropdown items
|
|
* @param {int} d
|
|
*/
|
|
Tokenize2.prototype.dropdownSelectionMove = function (d) {
|
|
|
|
if ($('li.active', this.dropdown).length > 0) {
|
|
if (!$('li.active', this.dropdown).is('li:' + (d > 0 ? 'last-child' : 'first-child'))) {
|
|
var $active = $('li.active', this.dropdown);
|
|
$active.removeClass('active');
|
|
if (d > 0) {
|
|
$active.next().addClass('active');
|
|
} else {
|
|
$active.prev().addClass('active');
|
|
}
|
|
} else {
|
|
$('li.active', this.dropdown).removeClass('active');
|
|
if (this.options.dropdownSelectFirstItem) {
|
|
$('li:' + (d > 0 ? 'first-child' : 'last-child'), this.dropdown).addClass('active');
|
|
}
|
|
}
|
|
} else {
|
|
$('li:first', this.dropdown).addClass('active');
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Add dropdown item
|
|
*
|
|
* @param {object} item
|
|
*/
|
|
Tokenize2.prototype.dropdownAddItem = function (item) {
|
|
|
|
if (this.isDropdownOpen()) {
|
|
|
|
if (item.hasOwnProperty('text')) {
|
|
item.text = this.escape(item.text);
|
|
}
|
|
item.value = this.escape(item.value);
|
|
|
|
var $li = $('<li class="dropdown-item" />').html(this.dropdownItemFormat(item))
|
|
.on('mouseover', $.proxy(function (e) {
|
|
e.preventDefault();
|
|
e.target = this.fixTarget(e.target);
|
|
$('li', this.dropdown).removeClass('active');
|
|
$(e.target).parent().addClass('active');
|
|
}, this)).on('mouseout', $.proxy(function () {
|
|
$('li', this.dropdown).removeClass('active');
|
|
}, this)).on('mousedown touchstart', $.proxy(function (e) {
|
|
e.preventDefault();
|
|
e.target = this.fixTarget(e.target);
|
|
this.trigger('tokenize:tokens:add', [$(e.target).attr('data-value'), $(e.target).attr('data-text'), true]);
|
|
}, this));
|
|
if ($('li.token[data-value="' + $li.find('a').attr('data-value') + '"]', this.tokensContainer).length < 1) {
|
|
this.dropdown.find('.dropdown-menu').append($li);
|
|
this.trigger('tokenize:dropdown:itemAdded', [item]);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Fix target for hover and click event on dropdown items
|
|
*
|
|
* @param {object} target
|
|
* @returns {object}
|
|
*/
|
|
Tokenize2.prototype.fixTarget = function (target) {
|
|
|
|
var $target = $(target);
|
|
|
|
if (!$target.data('value')) {
|
|
var $link = $target.find('a');
|
|
if ($link.length) {
|
|
return $link.get(0);
|
|
}
|
|
var $parent = $target.parents('[data-value]');
|
|
if ($parent.length) {
|
|
return $parent.get(0);
|
|
}
|
|
}
|
|
|
|
return $target.get(0);
|
|
|
|
};
|
|
|
|
/**
|
|
* Format dropdown item
|
|
*
|
|
* @param {object} item
|
|
* @returns {object|jQuery}
|
|
*/
|
|
Tokenize2.prototype.dropdownItemFormat = function (item) {
|
|
if (item.hasOwnProperty('text')) {
|
|
var $display = '';
|
|
if (this.options.searchHighlight) {
|
|
var $regex = new RegExp((this.options.searchFromStart ? '^' : '') + '(' + this.escapeRegex(this.transliteration(this.lastSearchTerms)) + ')', 'gi');
|
|
$display = item.text.replace($regex, '<span class="tokenize-highlight">$1</span>');
|
|
} else {
|
|
$display = item.text;
|
|
}
|
|
|
|
return $('<a />').html($display).attr({
|
|
'data-value': item.value,
|
|
'data-text': item.text
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Move dropdown according tokens container
|
|
*/
|
|
Tokenize2.prototype.dropdownMove = function () {
|
|
|
|
var $position = this.tokensContainer.offset();
|
|
var $height = this.tokensContainer.outerHeight();
|
|
var $width = this.tokensContainer.outerWidth();
|
|
|
|
$position.top += $height;
|
|
this.dropdown.css({
|
|
width: $width
|
|
}).offset($position);
|
|
|
|
};
|
|
|
|
/**
|
|
* Returns the current status of the dropdown
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
Tokenize2.prototype.isDropdownOpen = function () {
|
|
|
|
return (this.dropdown !== undefined);
|
|
|
|
};
|
|
|
|
/**
|
|
* Clear control
|
|
*
|
|
* @returns {Tokenize2}
|
|
*/
|
|
Tokenize2.prototype.clear = function () {
|
|
|
|
$.each($('li.token', this.tokensContainer), $.proxy(function (e, item) {
|
|
this.trigger('tokenize:tokens:remove', [$(item).attr('data-value')]);
|
|
}, this));
|
|
|
|
this.trigger('tokenize:dropdown:hide');
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
/**
|
|
* Reset pending delete tokens
|
|
*/
|
|
Tokenize2.prototype.resetPending = function () {
|
|
|
|
var $token = $('li.pending-delete:last', this.tokensContainer);
|
|
|
|
if ($token.length > 0) {
|
|
this.trigger('tokenize:tokens:cancelDelete', [$token.attr('data-value')]);
|
|
$token.removeClass('pending-delete');
|
|
}
|
|
|
|
};
|
|
|
|
/**
|
|
* Scale input
|
|
*/
|
|
Tokenize2.prototype.scaleInput = function () {
|
|
|
|
if (!this.ctx) {
|
|
this.ctx = document.createElement('canvas').getContext('2d');
|
|
}
|
|
|
|
var $width, $tokensContainerWidth;
|
|
|
|
this.ctx.font = this.input.css('font-style') + ' ' +
|
|
this.input.css('font-variant') + ' ' +
|
|
this.input.css('font-weight') + ' ' +
|
|
Math.ceil(parseFloat(this.input.css('font-size'))) + 'px ' +
|
|
this.input.css('font-family');
|
|
|
|
$width = Math.round(this.ctx.measureText(this.input.val() + 'M').width) + Math.ceil(parseFloat(this.searchContainer.css('margin-left'))) + Math.ceil(parseFloat(this.searchContainer.css('margin-right')));
|
|
$tokensContainerWidth = this.tokensContainer.width() -
|
|
(
|
|
Math.ceil(parseFloat(this.tokensContainer.css('border-left-width'))) + Math.ceil(parseFloat(this.tokensContainer.css('border-right-width')) +
|
|
Math.ceil(parseFloat(this.tokensContainer.css('padding-left'))) + Math.ceil(parseFloat(this.tokensContainer.css('padding-right'))))
|
|
);
|
|
|
|
if ($width >= $tokensContainerWidth) {
|
|
$width = $tokensContainerWidth;
|
|
}
|
|
|
|
this.searchContainer.width($width);
|
|
this.ctx.restore();
|
|
|
|
};
|
|
|
|
/**
|
|
* Reset input
|
|
*/
|
|
Tokenize2.prototype.resetInput = function () {
|
|
|
|
this.input.val('');
|
|
this.scaleInput();
|
|
|
|
};
|
|
|
|
Tokenize2.prototype.trim = function (string) {
|
|
return string.trim();
|
|
};
|
|
|
|
/**
|
|
* Escape string
|
|
*
|
|
* @param {string} string
|
|
* @returns {string}
|
|
*/
|
|
Tokenize2.prototype.escape = function (string) {
|
|
|
|
if (string) {
|
|
string = string.replaceAll(/["]/g, '"');
|
|
string = string.replaceAll(/[<]/g, '<');
|
|
string = string.replaceAll(/[>]/g, '>');
|
|
}
|
|
|
|
return string;
|
|
|
|
};
|
|
|
|
/**
|
|
* Escape regex
|
|
*
|
|
* @param {string} value
|
|
* @returns {string}
|
|
*/
|
|
Tokenize2.prototype.escapeRegex = function (value) {
|
|
|
|
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
|
|
|
|
};
|
|
|
|
/**
|
|
* Generates guid
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
Tokenize2.prototype.guid = function () {
|
|
|
|
function s4() {
|
|
return Math.floor((1 + Math.random()) * 0x10000)
|
|
.toString(16)
|
|
.substring(1);
|
|
}
|
|
|
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
|
s4() + '-' + s4() + s4() + s4();
|
|
|
|
};
|
|
|
|
/**
|
|
* Retrieve tokens value to an array
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
Tokenize2.prototype.toArray = function () {
|
|
|
|
var $output = [];
|
|
$("option:selected", this.element).each(function () {
|
|
$output.push($(this).val());
|
|
});
|
|
return $output;
|
|
|
|
};
|
|
|
|
Tokenize2.prototype.transliteration = function (text) {
|
|
var diacritics = {
|
|
'\u24B6': 'A',
|
|
'\uFF21': 'A',
|
|
'\u00C0': 'A',
|
|
'\u00C1': 'A',
|
|
'\u00C2': 'A',
|
|
'\u1EA6': 'A',
|
|
'\u1EA4': 'A',
|
|
'\u1EAA': 'A',
|
|
'\u1EA8': 'A',
|
|
'\u00C3': 'A',
|
|
'\u0100': 'A',
|
|
'\u0102': 'A',
|
|
'\u1EB0': 'A',
|
|
'\u1EAE': 'A',
|
|
'\u1EB4': 'A',
|
|
'\u1EB2': 'A',
|
|
'\u0226': 'A',
|
|
'\u01E0': 'A',
|
|
'\u00C4': 'A',
|
|
'\u01DE': 'A',
|
|
'\u1EA2': 'A',
|
|
'\u00C5': 'A',
|
|
'\u01FA': 'A',
|
|
'\u01CD': 'A',
|
|
'\u0200': 'A',
|
|
'\u0202': 'A',
|
|
'\u1EA0': 'A',
|
|
'\u1EAC': 'A',
|
|
'\u1EB6': 'A',
|
|
'\u1E00': 'A',
|
|
'\u0104': 'A',
|
|
'\u023A': 'A',
|
|
'\u2C6F': 'A',
|
|
'\uA732': 'AA',
|
|
'\u00C6': 'AE',
|
|
'\u01FC': 'AE',
|
|
'\u01E2': 'AE',
|
|
'\uA734': 'AO',
|
|
'\uA736': 'AU',
|
|
'\uA738': 'AV',
|
|
'\uA73A': 'AV',
|
|
'\uA73C': 'AY',
|
|
'\u24B7': 'B',
|
|
'\uFF22': 'B',
|
|
'\u1E02': 'B',
|
|
'\u1E04': 'B',
|
|
'\u1E06': 'B',
|
|
'\u0243': 'B',
|
|
'\u0182': 'B',
|
|
'\u0181': 'B',
|
|
'\u24B8': 'C',
|
|
'\uFF23': 'C',
|
|
'\u0106': 'C',
|
|
'\u0108': 'C',
|
|
'\u010A': 'C',
|
|
'\u010C': 'C',
|
|
'\u00C7': 'C',
|
|
'\u1E08': 'C',
|
|
'\u0187': 'C',
|
|
'\u023B': 'C',
|
|
'\uA73E': 'C',
|
|
'\u24B9': 'D',
|
|
'\uFF24': 'D',
|
|
'\u1E0A': 'D',
|
|
'\u010E': 'D',
|
|
'\u1E0C': 'D',
|
|
'\u1E10': 'D',
|
|
'\u1E12': 'D',
|
|
'\u1E0E': 'D',
|
|
'\u0110': 'D',
|
|
'\u018B': 'D',
|
|
'\u018A': 'D',
|
|
'\u0189': 'D',
|
|
'\uA779': 'D',
|
|
'\u01F1': 'DZ',
|
|
'\u01C4': 'DZ',
|
|
'\u01F2': 'Dz',
|
|
'\u01C5': 'Dz',
|
|
'\u24BA': 'E',
|
|
'\uFF25': 'E',
|
|
'\u00C8': 'E',
|
|
'\u00C9': 'E',
|
|
'\u00CA': 'E',
|
|
'\u1EC0': 'E',
|
|
'\u1EBE': 'E',
|
|
'\u1EC4': 'E',
|
|
'\u1EC2': 'E',
|
|
'\u1EBC': 'E',
|
|
'\u0112': 'E',
|
|
'\u1E14': 'E',
|
|
'\u1E16': 'E',
|
|
'\u0114': 'E',
|
|
'\u0116': 'E',
|
|
'\u00CB': 'E',
|
|
'\u1EBA': 'E',
|
|
'\u011A': 'E',
|
|
'\u0204': 'E',
|
|
'\u0206': 'E',
|
|
'\u1EB8': 'E',
|
|
'\u1EC6': 'E',
|
|
'\u0228': 'E',
|
|
'\u1E1C': 'E',
|
|
'\u0118': 'E',
|
|
'\u1E18': 'E',
|
|
'\u1E1A': 'E',
|
|
'\u0190': 'E',
|
|
'\u018E': 'E',
|
|
'\u24BB': 'F',
|
|
'\uFF26': 'F',
|
|
'\u1E1E': 'F',
|
|
'\u0191': 'F',
|
|
'\uA77B': 'F',
|
|
'\u24BC': 'G',
|
|
'\uFF27': 'G',
|
|
'\u01F4': 'G',
|
|
'\u011C': 'G',
|
|
'\u1E20': 'G',
|
|
'\u011E': 'G',
|
|
'\u0120': 'G',
|
|
'\u01E6': 'G',
|
|
'\u0122': 'G',
|
|
'\u01E4': 'G',
|
|
'\u0193': 'G',
|
|
'\uA7A0': 'G',
|
|
'\uA77D': 'G',
|
|
'\uA77E': 'G',
|
|
'\u24BD': 'H',
|
|
'\uFF28': 'H',
|
|
'\u0124': 'H',
|
|
'\u1E22': 'H',
|
|
'\u1E26': 'H',
|
|
'\u021E': 'H',
|
|
'\u1E24': 'H',
|
|
'\u1E28': 'H',
|
|
'\u1E2A': 'H',
|
|
'\u0126': 'H',
|
|
'\u2C67': 'H',
|
|
'\u2C75': 'H',
|
|
'\uA78D': 'H',
|
|
'\u24BE': 'I',
|
|
'\uFF29': 'I',
|
|
'\u00CC': 'I',
|
|
'\u00CD': 'I',
|
|
'\u00CE': 'I',
|
|
'\u0128': 'I',
|
|
'\u012A': 'I',
|
|
'\u012C': 'I',
|
|
'\u0130': 'I',
|
|
'\u00CF': 'I',
|
|
'\u1E2E': 'I',
|
|
'\u1EC8': 'I',
|
|
'\u01CF': 'I',
|
|
'\u0208': 'I',
|
|
'\u020A': 'I',
|
|
'\u1ECA': 'I',
|
|
'\u012E': 'I',
|
|
'\u1E2C': 'I',
|
|
'\u0197': 'I',
|
|
'\u24BF': 'J',
|
|
'\uFF2A': 'J',
|
|
'\u0134': 'J',
|
|
'\u0248': 'J',
|
|
'\u24C0': 'K',
|
|
'\uFF2B': 'K',
|
|
'\u1E30': 'K',
|
|
'\u01E8': 'K',
|
|
'\u1E32': 'K',
|
|
'\u0136': 'K',
|
|
'\u1E34': 'K',
|
|
'\u0198': 'K',
|
|
'\u2C69': 'K',
|
|
'\uA740': 'K',
|
|
'\uA742': 'K',
|
|
'\uA744': 'K',
|
|
'\uA7A2': 'K',
|
|
'\u24C1': 'L',
|
|
'\uFF2C': 'L',
|
|
'\u013F': 'L',
|
|
'\u0139': 'L',
|
|
'\u013D': 'L',
|
|
'\u1E36': 'L',
|
|
'\u1E38': 'L',
|
|
'\u013B': 'L',
|
|
'\u1E3C': 'L',
|
|
'\u1E3A': 'L',
|
|
'\u0141': 'L',
|
|
'\u023D': 'L',
|
|
'\u2C62': 'L',
|
|
'\u2C60': 'L',
|
|
'\uA748': 'L',
|
|
'\uA746': 'L',
|
|
'\uA780': 'L',
|
|
'\u01C7': 'LJ',
|
|
'\u01C8': 'Lj',
|
|
'\u24C2': 'M',
|
|
'\uFF2D': 'M',
|
|
'\u1E3E': 'M',
|
|
'\u1E40': 'M',
|
|
'\u1E42': 'M',
|
|
'\u2C6E': 'M',
|
|
'\u019C': 'M',
|
|
'\u24C3': 'N',
|
|
'\uFF2E': 'N',
|
|
'\u01F8': 'N',
|
|
'\u0143': 'N',
|
|
'\u00D1': 'N',
|
|
'\u1E44': 'N',
|
|
'\u0147': 'N',
|
|
'\u1E46': 'N',
|
|
'\u0145': 'N',
|
|
'\u1E4A': 'N',
|
|
'\u1E48': 'N',
|
|
'\u0220': 'N',
|
|
'\u019D': 'N',
|
|
'\uA790': 'N',
|
|
'\uA7A4': 'N',
|
|
'\u01CA': 'NJ',
|
|
'\u01CB': 'Nj',
|
|
'\u24C4': 'O',
|
|
'\uFF2F': 'O',
|
|
'\u00D2': 'O',
|
|
'\u00D3': 'O',
|
|
'\u00D4': 'O',
|
|
'\u1ED2': 'O',
|
|
'\u1ED0': 'O',
|
|
'\u1ED6': 'O',
|
|
'\u1ED4': 'O',
|
|
'\u00D5': 'O',
|
|
'\u1E4C': 'O',
|
|
'\u022C': 'O',
|
|
'\u1E4E': 'O',
|
|
'\u014C': 'O',
|
|
'\u1E50': 'O',
|
|
'\u1E52': 'O',
|
|
'\u014E': 'O',
|
|
'\u022E': 'O',
|
|
'\u0230': 'O',
|
|
'\u00D6': 'O',
|
|
'\u022A': 'O',
|
|
'\u1ECE': 'O',
|
|
'\u0150': 'O',
|
|
'\u01D1': 'O',
|
|
'\u020C': 'O',
|
|
'\u020E': 'O',
|
|
'\u01A0': 'O',
|
|
'\u1EDC': 'O',
|
|
'\u1EDA': 'O',
|
|
'\u1EE0': 'O',
|
|
'\u1EDE': 'O',
|
|
'\u1EE2': 'O',
|
|
'\u1ECC': 'O',
|
|
'\u1ED8': 'O',
|
|
'\u01EA': 'O',
|
|
'\u01EC': 'O',
|
|
'\u00D8': 'O',
|
|
'\u01FE': 'O',
|
|
'\u0186': 'O',
|
|
'\u019F': 'O',
|
|
'\uA74A': 'O',
|
|
'\uA74C': 'O',
|
|
'\u01A2': 'OI',
|
|
'\uA74E': 'OO',
|
|
'\u0222': 'OU',
|
|
'\u24C5': 'P',
|
|
'\uFF30': 'P',
|
|
'\u1E54': 'P',
|
|
'\u1E56': 'P',
|
|
'\u01A4': 'P',
|
|
'\u2C63': 'P',
|
|
'\uA750': 'P',
|
|
'\uA752': 'P',
|
|
'\uA754': 'P',
|
|
'\u24C6': 'Q',
|
|
'\uFF31': 'Q',
|
|
'\uA756': 'Q',
|
|
'\uA758': 'Q',
|
|
'\u024A': 'Q',
|
|
'\u24C7': 'R',
|
|
'\uFF32': 'R',
|
|
'\u0154': 'R',
|
|
'\u1E58': 'R',
|
|
'\u0158': 'R',
|
|
'\u0210': 'R',
|
|
'\u0212': 'R',
|
|
'\u1E5A': 'R',
|
|
'\u1E5C': 'R',
|
|
'\u0156': 'R',
|
|
'\u1E5E': 'R',
|
|
'\u024C': 'R',
|
|
'\u2C64': 'R',
|
|
'\uA75A': 'R',
|
|
'\uA7A6': 'R',
|
|
'\uA782': 'R',
|
|
'\u24C8': 'S',
|
|
'\uFF33': 'S',
|
|
'\u1E9E': 'S',
|
|
'\u015A': 'S',
|
|
'\u1E64': 'S',
|
|
'\u015C': 'S',
|
|
'\u1E60': 'S',
|
|
'\u0160': 'S',
|
|
'\u1E66': 'S',
|
|
'\u1E62': 'S',
|
|
'\u1E68': 'S',
|
|
'\u0218': 'S',
|
|
'\u015E': 'S',
|
|
'\u2C7E': 'S',
|
|
'\uA7A8': 'S',
|
|
'\uA784': 'S',
|
|
'\u24C9': 'T',
|
|
'\uFF34': 'T',
|
|
'\u1E6A': 'T',
|
|
'\u0164': 'T',
|
|
'\u1E6C': 'T',
|
|
'\u021A': 'T',
|
|
'\u0162': 'T',
|
|
'\u1E70': 'T',
|
|
'\u1E6E': 'T',
|
|
'\u0166': 'T',
|
|
'\u01AC': 'T',
|
|
'\u01AE': 'T',
|
|
'\u023E': 'T',
|
|
'\uA786': 'T',
|
|
'\uA728': 'TZ',
|
|
'\u24CA': 'U',
|
|
'\uFF35': 'U',
|
|
'\u00D9': 'U',
|
|
'\u00DA': 'U',
|
|
'\u00DB': 'U',
|
|
'\u0168': 'U',
|
|
'\u1E78': 'U',
|
|
'\u016A': 'U',
|
|
'\u1E7A': 'U',
|
|
'\u016C': 'U',
|
|
'\u00DC': 'U',
|
|
'\u01DB': 'U',
|
|
'\u01D7': 'U',
|
|
'\u01D5': 'U',
|
|
'\u01D9': 'U',
|
|
'\u1EE6': 'U',
|
|
'\u016E': 'U',
|
|
'\u0170': 'U',
|
|
'\u01D3': 'U',
|
|
'\u0214': 'U',
|
|
'\u0216': 'U',
|
|
'\u01AF': 'U',
|
|
'\u1EEA': 'U',
|
|
'\u1EE8': 'U',
|
|
'\u1EEE': 'U',
|
|
'\u1EEC': 'U',
|
|
'\u1EF0': 'U',
|
|
'\u1EE4': 'U',
|
|
'\u1E72': 'U',
|
|
'\u0172': 'U',
|
|
'\u1E76': 'U',
|
|
'\u1E74': 'U',
|
|
'\u0244': 'U',
|
|
'\u24CB': 'V',
|
|
'\uFF36': 'V',
|
|
'\u1E7C': 'V',
|
|
'\u1E7E': 'V',
|
|
'\u01B2': 'V',
|
|
'\uA75E': 'V',
|
|
'\u0245': 'V',
|
|
'\uA760': 'VY',
|
|
'\u24CC': 'W',
|
|
'\uFF37': 'W',
|
|
'\u1E80': 'W',
|
|
'\u1E82': 'W',
|
|
'\u0174': 'W',
|
|
'\u1E86': 'W',
|
|
'\u1E84': 'W',
|
|
'\u1E88': 'W',
|
|
'\u2C72': 'W',
|
|
'\u24CD': 'X',
|
|
'\uFF38': 'X',
|
|
'\u1E8A': 'X',
|
|
'\u1E8C': 'X',
|
|
'\u24CE': 'Y',
|
|
'\uFF39': 'Y',
|
|
'\u1EF2': 'Y',
|
|
'\u00DD': 'Y',
|
|
'\u0176': 'Y',
|
|
'\u1EF8': 'Y',
|
|
'\u0232': 'Y',
|
|
'\u1E8E': 'Y',
|
|
'\u0178': 'Y',
|
|
'\u1EF6': 'Y',
|
|
'\u1EF4': 'Y',
|
|
'\u01B3': 'Y',
|
|
'\u024E': 'Y',
|
|
'\u1EFE': 'Y',
|
|
'\u24CF': 'Z',
|
|
'\uFF3A': 'Z',
|
|
'\u0179': 'Z',
|
|
'\u1E90': 'Z',
|
|
'\u017B': 'Z',
|
|
'\u017D': 'Z',
|
|
'\u1E92': 'Z',
|
|
'\u1E94': 'Z',
|
|
'\u01B5': 'Z',
|
|
'\u0224': 'Z',
|
|
'\u2C7F': 'Z',
|
|
'\u2C6B': 'Z',
|
|
'\uA762': 'Z',
|
|
'\u24D0': 'a',
|
|
'\uFF41': 'a',
|
|
'\u1E9A': 'a',
|
|
'\u00E0': 'a',
|
|
'\u00E1': 'a',
|
|
'\u00E2': 'a',
|
|
'\u1EA7': 'a',
|
|
'\u1EA5': 'a',
|
|
'\u1EAB': 'a',
|
|
'\u1EA9': 'a',
|
|
'\u00E3': 'a',
|
|
'\u0101': 'a',
|
|
'\u0103': 'a',
|
|
'\u1EB1': 'a',
|
|
'\u1EAF': 'a',
|
|
'\u1EB5': 'a',
|
|
'\u1EB3': 'a',
|
|
'\u0227': 'a',
|
|
'\u01E1': 'a',
|
|
'\u00E4': 'a',
|
|
'\u01DF': 'a',
|
|
'\u1EA3': 'a',
|
|
'\u00E5': 'a',
|
|
'\u01FB': 'a',
|
|
'\u01CE': 'a',
|
|
'\u0201': 'a',
|
|
'\u0203': 'a',
|
|
'\u1EA1': 'a',
|
|
'\u1EAD': 'a',
|
|
'\u1EB7': 'a',
|
|
'\u1E01': 'a',
|
|
'\u0105': 'a',
|
|
'\u2C65': 'a',
|
|
'\u0250': 'a',
|
|
'\uA733': 'aa',
|
|
'\u00E6': 'ae',
|
|
'\u01FD': 'ae',
|
|
'\u01E3': 'ae',
|
|
'\uA735': 'ao',
|
|
'\uA737': 'au',
|
|
'\uA739': 'av',
|
|
'\uA73B': 'av',
|
|
'\uA73D': 'ay',
|
|
'\u24D1': 'b',
|
|
'\uFF42': 'b',
|
|
'\u1E03': 'b',
|
|
'\u1E05': 'b',
|
|
'\u1E07': 'b',
|
|
'\u0180': 'b',
|
|
'\u0183': 'b',
|
|
'\u0253': 'b',
|
|
'\u24D2': 'c',
|
|
'\uFF43': 'c',
|
|
'\u0107': 'c',
|
|
'\u0109': 'c',
|
|
'\u010B': 'c',
|
|
'\u010D': 'c',
|
|
'\u00E7': 'c',
|
|
'\u1E09': 'c',
|
|
'\u0188': 'c',
|
|
'\u023C': 'c',
|
|
'\uA73F': 'c',
|
|
'\u2184': 'c',
|
|
'\u24D3': 'd',
|
|
'\uFF44': 'd',
|
|
'\u1E0B': 'd',
|
|
'\u010F': 'd',
|
|
'\u1E0D': 'd',
|
|
'\u1E11': 'd',
|
|
'\u1E13': 'd',
|
|
'\u1E0F': 'd',
|
|
'\u0111': 'd',
|
|
'\u018C': 'd',
|
|
'\u0256': 'd',
|
|
'\u0257': 'd',
|
|
'\uA77A': 'd',
|
|
'\u01F3': 'dz',
|
|
'\u01C6': 'dz',
|
|
'\u24D4': 'e',
|
|
'\uFF45': 'e',
|
|
'\u00E8': 'e',
|
|
'\u00E9': 'e',
|
|
'\u00EA': 'e',
|
|
'\u1EC1': 'e',
|
|
'\u1EBF': 'e',
|
|
'\u1EC5': 'e',
|
|
'\u1EC3': 'e',
|
|
'\u1EBD': 'e',
|
|
'\u0113': 'e',
|
|
'\u1E15': 'e',
|
|
'\u1E17': 'e',
|
|
'\u0115': 'e',
|
|
'\u0117': 'e',
|
|
'\u00EB': 'e',
|
|
'\u1EBB': 'e',
|
|
'\u011B': 'e',
|
|
'\u0205': 'e',
|
|
'\u0207': 'e',
|
|
'\u1EB9': 'e',
|
|
'\u1EC7': 'e',
|
|
'\u0229': 'e',
|
|
'\u1E1D': 'e',
|
|
'\u0119': 'e',
|
|
'\u1E19': 'e',
|
|
'\u1E1B': 'e',
|
|
'\u0247': 'e',
|
|
'\u025B': 'e',
|
|
'\u01DD': 'e',
|
|
'\u24D5': 'f',
|
|
'\uFF46': 'f',
|
|
'\u1E1F': 'f',
|
|
'\u0192': 'f',
|
|
'\uA77C': 'f',
|
|
'\u24D6': 'g',
|
|
'\uFF47': 'g',
|
|
'\u01F5': 'g',
|
|
'\u011D': 'g',
|
|
'\u1E21': 'g',
|
|
'\u011F': 'g',
|
|
'\u0121': 'g',
|
|
'\u01E7': 'g',
|
|
'\u0123': 'g',
|
|
'\u01E5': 'g',
|
|
'\u0260': 'g',
|
|
'\uA7A1': 'g',
|
|
'\u1D79': 'g',
|
|
'\uA77F': 'g',
|
|
'\u24D7': 'h',
|
|
'\uFF48': 'h',
|
|
'\u0125': 'h',
|
|
'\u1E23': 'h',
|
|
'\u1E27': 'h',
|
|
'\u021F': 'h',
|
|
'\u1E25': 'h',
|
|
'\u1E29': 'h',
|
|
'\u1E2B': 'h',
|
|
'\u1E96': 'h',
|
|
'\u0127': 'h',
|
|
'\u2C68': 'h',
|
|
'\u2C76': 'h',
|
|
'\u0265': 'h',
|
|
'\u0195': 'hv',
|
|
'\u24D8': 'i',
|
|
'\uFF49': 'i',
|
|
'\u00EC': 'i',
|
|
'\u00ED': 'i',
|
|
'\u00EE': 'i',
|
|
'\u0129': 'i',
|
|
'\u012B': 'i',
|
|
'\u012D': 'i',
|
|
'\u00EF': 'i',
|
|
'\u1E2F': 'i',
|
|
'\u1EC9': 'i',
|
|
'\u01D0': 'i',
|
|
'\u0209': 'i',
|
|
'\u020B': 'i',
|
|
'\u1ECB': 'i',
|
|
'\u012F': 'i',
|
|
'\u1E2D': 'i',
|
|
'\u0268': 'i',
|
|
'\u0131': 'i',
|
|
'\u24D9': 'j',
|
|
'\uFF4A': 'j',
|
|
'\u0135': 'j',
|
|
'\u01F0': 'j',
|
|
'\u0249': 'j',
|
|
'\u24DA': 'k',
|
|
'\uFF4B': 'k',
|
|
'\u1E31': 'k',
|
|
'\u01E9': 'k',
|
|
'\u1E33': 'k',
|
|
'\u0137': 'k',
|
|
'\u1E35': 'k',
|
|
'\u0199': 'k',
|
|
'\u2C6A': 'k',
|
|
'\uA741': 'k',
|
|
'\uA743': 'k',
|
|
'\uA745': 'k',
|
|
'\uA7A3': 'k',
|
|
'\u24DB': 'l',
|
|
'\uFF4C': 'l',
|
|
'\u0140': 'l',
|
|
'\u013A': 'l',
|
|
'\u013E': 'l',
|
|
'\u1E37': 'l',
|
|
'\u1E39': 'l',
|
|
'\u013C': 'l',
|
|
'\u1E3D': 'l',
|
|
'\u1E3B': 'l',
|
|
'\u017F': 'l',
|
|
'\u0142': 'l',
|
|
'\u019A': 'l',
|
|
'\u026B': 'l',
|
|
'\u2C61': 'l',
|
|
'\uA749': 'l',
|
|
'\uA781': 'l',
|
|
'\uA747': 'l',
|
|
'\u01C9': 'lj',
|
|
'\u24DC': 'm',
|
|
'\uFF4D': 'm',
|
|
'\u1E3F': 'm',
|
|
'\u1E41': 'm',
|
|
'\u1E43': 'm',
|
|
'\u0271': 'm',
|
|
'\u026F': 'm',
|
|
'\u24DD': 'n',
|
|
'\uFF4E': 'n',
|
|
'\u01F9': 'n',
|
|
'\u0144': 'n',
|
|
'\u00F1': 'n',
|
|
'\u1E45': 'n',
|
|
'\u0148': 'n',
|
|
'\u1E47': 'n',
|
|
'\u0146': 'n',
|
|
'\u1E4B': 'n',
|
|
'\u1E49': 'n',
|
|
'\u019E': 'n',
|
|
'\u0272': 'n',
|
|
'\u0149': 'n',
|
|
'\uA791': 'n',
|
|
'\uA7A5': 'n',
|
|
'\u01CC': 'nj',
|
|
'\u24DE': 'o',
|
|
'\uFF4F': 'o',
|
|
'\u00F2': 'o',
|
|
'\u00F3': 'o',
|
|
'\u00F4': 'o',
|
|
'\u1ED3': 'o',
|
|
'\u1ED1': 'o',
|
|
'\u1ED7': 'o',
|
|
'\u1ED5': 'o',
|
|
'\u00F5': 'o',
|
|
'\u1E4D': 'o',
|
|
'\u022D': 'o',
|
|
'\u1E4F': 'o',
|
|
'\u014D': 'o',
|
|
'\u1E51': 'o',
|
|
'\u1E53': 'o',
|
|
'\u014F': 'o',
|
|
'\u022F': 'o',
|
|
'\u0231': 'o',
|
|
'\u00F6': 'o',
|
|
'\u022B': 'o',
|
|
'\u1ECF': 'o',
|
|
'\u0151': 'o',
|
|
'\u01D2': 'o',
|
|
'\u020D': 'o',
|
|
'\u020F': 'o',
|
|
'\u01A1': 'o',
|
|
'\u1EDD': 'o',
|
|
'\u1EDB': 'o',
|
|
'\u1EE1': 'o',
|
|
'\u1EDF': 'o',
|
|
'\u1EE3': 'o',
|
|
'\u1ECD': 'o',
|
|
'\u1ED9': 'o',
|
|
'\u01EB': 'o',
|
|
'\u01ED': 'o',
|
|
'\u00F8': 'o',
|
|
'\u01FF': 'o',
|
|
'\u0254': 'o',
|
|
'\uA74B': 'o',
|
|
'\uA74D': 'o',
|
|
'\u0275': 'o',
|
|
'\u01A3': 'oi',
|
|
'\u0223': 'ou',
|
|
'\uA74F': 'oo',
|
|
'\u24DF': 'p',
|
|
'\uFF50': 'p',
|
|
'\u1E55': 'p',
|
|
'\u1E57': 'p',
|
|
'\u01A5': 'p',
|
|
'\u1D7D': 'p',
|
|
'\uA751': 'p',
|
|
'\uA753': 'p',
|
|
'\uA755': 'p',
|
|
'\u24E0': 'q',
|
|
'\uFF51': 'q',
|
|
'\u024B': 'q',
|
|
'\uA757': 'q',
|
|
'\uA759': 'q',
|
|
'\u24E1': 'r',
|
|
'\uFF52': 'r',
|
|
'\u0155': 'r',
|
|
'\u1E59': 'r',
|
|
'\u0159': 'r',
|
|
'\u0211': 'r',
|
|
'\u0213': 'r',
|
|
'\u1E5B': 'r',
|
|
'\u1E5D': 'r',
|
|
'\u0157': 'r',
|
|
'\u1E5F': 'r',
|
|
'\u024D': 'r',
|
|
'\u027D': 'r',
|
|
'\uA75B': 'r',
|
|
'\uA7A7': 'r',
|
|
'\uA783': 'r',
|
|
'\u24E2': 's',
|
|
'\uFF53': 's',
|
|
'\u00DF': 's',
|
|
'\u015B': 's',
|
|
'\u1E65': 's',
|
|
'\u015D': 's',
|
|
'\u1E61': 's',
|
|
'\u0161': 's',
|
|
'\u1E67': 's',
|
|
'\u1E63': 's',
|
|
'\u1E69': 's',
|
|
'\u0219': 's',
|
|
'\u015F': 's',
|
|
'\u023F': 's',
|
|
'\uA7A9': 's',
|
|
'\uA785': 's',
|
|
'\u1E9B': 's',
|
|
'\u24E3': 't',
|
|
'\uFF54': 't',
|
|
'\u1E6B': 't',
|
|
'\u1E97': 't',
|
|
'\u0165': 't',
|
|
'\u1E6D': 't',
|
|
'\u021B': 't',
|
|
'\u0163': 't',
|
|
'\u1E71': 't',
|
|
'\u1E6F': 't',
|
|
'\u0167': 't',
|
|
'\u01AD': 't',
|
|
'\u0288': 't',
|
|
'\u2C66': 't',
|
|
'\uA787': 't',
|
|
'\uA729': 'tz',
|
|
'\u24E4': 'u',
|
|
'\uFF55': 'u',
|
|
'\u00F9': 'u',
|
|
'\u00FA': 'u',
|
|
'\u00FB': 'u',
|
|
'\u0169': 'u',
|
|
'\u1E79': 'u',
|
|
'\u016B': 'u',
|
|
'\u1E7B': 'u',
|
|
'\u016D': 'u',
|
|
'\u00FC': 'u',
|
|
'\u01DC': 'u',
|
|
'\u01D8': 'u',
|
|
'\u01D6': 'u',
|
|
'\u01DA': 'u',
|
|
'\u1EE7': 'u',
|
|
'\u016F': 'u',
|
|
'\u0171': 'u',
|
|
'\u01D4': 'u',
|
|
'\u0215': 'u',
|
|
'\u0217': 'u',
|
|
'\u01B0': 'u',
|
|
'\u1EEB': 'u',
|
|
'\u1EE9': 'u',
|
|
'\u1EEF': 'u',
|
|
'\u1EED': 'u',
|
|
'\u1EF1': 'u',
|
|
'\u1EE5': 'u',
|
|
'\u1E73': 'u',
|
|
'\u0173': 'u',
|
|
'\u1E77': 'u',
|
|
'\u1E75': 'u',
|
|
'\u0289': 'u',
|
|
'\u24E5': 'v',
|
|
'\uFF56': 'v',
|
|
'\u1E7D': 'v',
|
|
'\u1E7F': 'v',
|
|
'\u028B': 'v',
|
|
'\uA75F': 'v',
|
|
'\u028C': 'v',
|
|
'\uA761': 'vy',
|
|
'\u24E6': 'w',
|
|
'\uFF57': 'w',
|
|
'\u1E81': 'w',
|
|
'\u1E83': 'w',
|
|
'\u0175': 'w',
|
|
'\u1E87': 'w',
|
|
'\u1E85': 'w',
|
|
'\u1E98': 'w',
|
|
'\u1E89': 'w',
|
|
'\u2C73': 'w',
|
|
'\u24E7': 'x',
|
|
'\uFF58': 'x',
|
|
'\u1E8B': 'x',
|
|
'\u1E8D': 'x',
|
|
'\u24E8': 'y',
|
|
'\uFF59': 'y',
|
|
'\u1EF3': 'y',
|
|
'\u00FD': 'y',
|
|
'\u0177': 'y',
|
|
'\u1EF9': 'y',
|
|
'\u0233': 'y',
|
|
'\u1E8F': 'y',
|
|
'\u00FF': 'y',
|
|
'\u1EF7': 'y',
|
|
'\u1E99': 'y',
|
|
'\u1EF5': 'y',
|
|
'\u01B4': 'y',
|
|
'\u024F': 'y',
|
|
'\u1EFF': 'y',
|
|
'\u24E9': 'z',
|
|
'\uFF5A': 'z',
|
|
'\u017A': 'z',
|
|
'\u1E91': 'z',
|
|
'\u017C': 'z',
|
|
'\u017E': 'z',
|
|
'\u1E93': 'z',
|
|
'\u1E95': 'z',
|
|
'\u01B6': 'z',
|
|
'\u0225': 'z',
|
|
'\u0240': 'z',
|
|
'\u2C6C': 'z',
|
|
'\uA763': 'z',
|
|
'\u0386': '\u0391',
|
|
'\u0388': '\u0395',
|
|
'\u0389': '\u0397',
|
|
'\u038A': '\u0399',
|
|
'\u03AA': '\u0399',
|
|
'\u038C': '\u039F',
|
|
'\u038E': '\u03A5',
|
|
'\u03AB': '\u03A5',
|
|
'\u038F': '\u03A9',
|
|
'\u03AC': '\u03B1',
|
|
'\u03AD': '\u03B5',
|
|
'\u03AE': '\u03B7',
|
|
'\u03AF': '\u03B9',
|
|
'\u03CA': '\u03B9',
|
|
'\u0390': '\u03B9',
|
|
'\u03CC': '\u03BF',
|
|
'\u03CD': '\u03C5',
|
|
'\u03CB': '\u03C5',
|
|
'\u03B0': '\u03C5',
|
|
'\u03C9': '\u03C9',
|
|
'\u03C2': '\u03C3'
|
|
};
|
|
|
|
var $match = function (a) {
|
|
return diacritics[a] || a;
|
|
};
|
|
|
|
return text.replace(/[^\u0000-\u007E]/g, $match);
|
|
};
|
|
|
|
/**
|
|
* Tokenize plugin main function
|
|
*
|
|
* @param {object} options
|
|
* @returns {object|Tokenize2|Array}
|
|
*/
|
|
function Plugin(options) {
|
|
|
|
var $items = [];
|
|
this.filter('select').each(function () {
|
|
var $this = $(this);
|
|
var $data = $this.data('tokenize2');
|
|
var $options = typeof options === 'object' && options;
|
|
if (!$data) {
|
|
$this.data('tokenize2', new Tokenize2(this, $options));
|
|
}
|
|
$items.push($this.data('tokenize2'));
|
|
});
|
|
|
|
if ($items.length > 1) {
|
|
return $items;
|
|
} else {
|
|
return $items[0];
|
|
}
|
|
}
|
|
|
|
var old = $.fn.tokenize2;
|
|
|
|
/**
|
|
* jQuery plugin entry
|
|
*/
|
|
$.fn.tokenize2 = Plugin;
|
|
$.fn.tokenize2.Constructor = Tokenize2;
|
|
$.fn.tokenize2.noConflict = function () {
|
|
$.fn.tokenize2 = old;
|
|
return this;
|
|
}
|
|
|
|
}));
|
|
|
|
/* ===================================================
|
|
* jquery-sortable.js v0.9.13
|
|
* http://johnny.github.com/jquery-sortable/
|
|
* ===================================================
|
|
* Copyright (c) 2012 Jonas von Andrian
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* ========================================================== */
|
|
|
|
!function ($, window, pluginName, undefined) {
|
|
var containerDefaults = {
|
|
// If true, items can be dragged from this container
|
|
drag: true,
|
|
// If true, items can be droped onto this container
|
|
drop: true,
|
|
// Exclude items from being draggable, if the
|
|
// selector matches the item
|
|
exclude: "",
|
|
// If true, search for nested containers within an item.If you nest containers,
|
|
// either the original selector with which you call the plugin must only match the top containers,
|
|
// or you need to specify a group (see the bootstrap nav example)
|
|
nested: true,
|
|
// If true, the items are assumed to be arranged vertically
|
|
vertical: true
|
|
}, // end container defaults
|
|
groupDefaults = {
|
|
// This is executed after the placeholder has been moved.
|
|
// $closestItemOrContainer contains the closest item, the placeholder
|
|
// has been put at or the closest empty Container, the placeholder has
|
|
// been appended to.
|
|
afterMove: function ($placeholder, container, $closestItemOrContainer) {
|
|
},
|
|
// The exact css path between the container and its items, e.g. "> tbody"
|
|
containerPath: "",
|
|
// The css selector of the containers
|
|
containerSelector: "ol, ul",
|
|
// Distance the mouse has to travel to start dragging
|
|
distance: 0,
|
|
// Time in milliseconds after mousedown until dragging should start.
|
|
// This option can be used to prevent unwanted drags when clicking on an element.
|
|
delay: 0,
|
|
// The css selector of the drag handle
|
|
handle: "",
|
|
// The exact css path between the item and its subcontainers.
|
|
// It should only match the immediate items of a container.
|
|
// No item of a subcontainer should be matched. E.g. for ol>div>li the itemPath is "> div"
|
|
itemPath: "",
|
|
// The css selector of the items
|
|
itemSelector: "li",
|
|
// The class given to "body" while an item is being dragged
|
|
bodyClass: "dragging",
|
|
// The class giving to an item while being dragged
|
|
draggedClass: "dragged",
|
|
// Check if the dragged item may be inside the container.
|
|
// Use with care, since the search for a valid container entails a depth first search
|
|
// and may be quite expensive.
|
|
isValidTarget: function ($item, container) {
|
|
return true
|
|
},
|
|
// Executed before onDrop if placeholder is detached.
|
|
// This happens if pullPlaceholder is set to false and the drop occurs outside a container.
|
|
onCancel: function ($item, container, _super, event) {
|
|
},
|
|
// Executed at the beginning of a mouse move event.
|
|
// The Placeholder has not been moved yet.
|
|
onDrag: function ($item, position, _super, event) {
|
|
$item.css(position)
|
|
},
|
|
// Called after the drag has been started,
|
|
// that is the mouse button is being held down and
|
|
// the mouse is moving.
|
|
// The container is the closest initialized container.
|
|
// Therefore it might not be the container, that actually contains the item.
|
|
onDragStart: function ($item, container, _super, event) {
|
|
$item.css({
|
|
height: $item.outerHeight(),
|
|
width: $item.outerWidth()
|
|
})
|
|
$item.addClass(container.group.options.draggedClass)
|
|
$("body").addClass(container.group.options.bodyClass)
|
|
},
|
|
// Called when the mouse button is being released
|
|
onDrop: function ($item, container, _super, event) {
|
|
$item.removeClass(container.group.options.draggedClass).removeAttr("style")
|
|
$("body").removeClass(container.group.options.bodyClass)
|
|
},
|
|
// Called on mousedown. If falsy value is returned, the dragging will not start.
|
|
// Ignore if element clicked is input, select or textarea
|
|
onMousedown: function ($item, _super, event) {
|
|
if (!event.target.nodeName.match(/^(input|select|textarea)$/i)) {
|
|
event.preventDefault()
|
|
return true
|
|
}
|
|
},
|
|
// The class of the placeholder (must match placeholder option markup)
|
|
placeholderClass: "placeholder",
|
|
// Template for the placeholder. Can be any valid jQuery input
|
|
// e.g. a string, a DOM element.
|
|
// The placeholder must have the class "placeholder"
|
|
placeholder: '<li class="placeholder"></li>',
|
|
// If true, the position of the placeholder is calculated on every mousemove.
|
|
// If false, it is only calculated when the mouse is above a container.
|
|
pullPlaceholder: true,
|
|
// Specifies serialization of the container group.
|
|
// The pair $parent/$children is either container/items or item/subcontainers.
|
|
serialize: function ($parent, $children, parentIsContainer) {
|
|
var result = $.extend({}, $parent.data())
|
|
|
|
if (parentIsContainer)
|
|
return [$children]
|
|
else if ($children[0]) {
|
|
result.children = $children
|
|
}
|
|
|
|
delete result.subContainers
|
|
delete result.sortable
|
|
|
|
return result
|
|
},
|
|
// Set tolerance while dragging. Positive values decrease sensitivity,
|
|
// negative values increase it.
|
|
tolerance: 0
|
|
}, // end group defaults
|
|
containerGroups = {},
|
|
groupCounter = 0,
|
|
emptyBox = {
|
|
left: 0,
|
|
top: 0,
|
|
bottom: 0,
|
|
right: 0
|
|
},
|
|
eventNames = {
|
|
start: "touchstart.sortable mousedown.sortable",
|
|
drop: "touchend.sortable touchcancel.sortable mouseup.sortable",
|
|
drag: "touchmove.sortable mousemove.sortable",
|
|
scroll: "scroll.sortable"
|
|
},
|
|
subContainerKey = "subContainers"
|
|
|
|
/*
|
|
* a is Array [left, right, top, bottom]
|
|
* b is array [left, top]
|
|
*/
|
|
function d(a, b) {
|
|
var x = Math.max(0, a[0] - b[0], b[0] - a[1]),
|
|
y = Math.max(0, a[2] - b[1], b[1] - a[3])
|
|
return x + y;
|
|
}
|
|
|
|
function setDimensions(array, dimensions, tolerance, useOffset) {
|
|
var i = array.length,
|
|
offsetMethod = useOffset ? "offset" : "position"
|
|
tolerance = tolerance || 0
|
|
|
|
while (i--) {
|
|
var el = array[i].el ? array[i].el : $(array[i]),
|
|
// use fitting method
|
|
pos = el[offsetMethod]()
|
|
pos.left += parseInt(el.css('margin-left'), 10)
|
|
pos.top += parseInt(el.css('margin-top'), 10)
|
|
dimensions[i] = [
|
|
pos.left - tolerance,
|
|
pos.left + el.outerWidth() + tolerance,
|
|
pos.top - tolerance,
|
|
pos.top + el.outerHeight() + tolerance
|
|
]
|
|
}
|
|
}
|
|
|
|
function getRelativePosition(pointer, element) {
|
|
var offset = element.offset()
|
|
return {
|
|
left: pointer.left - offset.left,
|
|
top: pointer.top - offset.top
|
|
}
|
|
}
|
|
|
|
function sortByDistanceDesc(dimensions, pointer, lastPointer) {
|
|
pointer = [pointer.left, pointer.top]
|
|
lastPointer = lastPointer && [lastPointer.left, lastPointer.top]
|
|
|
|
var dim,
|
|
i = dimensions.length,
|
|
distances = []
|
|
|
|
while (i--) {
|
|
dim = dimensions[i]
|
|
distances[i] = [i, d(dim, pointer), lastPointer && d(dim, lastPointer)]
|
|
}
|
|
distances = distances.sort(function (a, b) {
|
|
return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]
|
|
})
|
|
|
|
// last entry is the closest
|
|
return distances
|
|
}
|
|
|
|
function ContainerGroup(options) {
|
|
this.options = $.extend({}, groupDefaults, options)
|
|
this.containers = []
|
|
|
|
if (!this.options.rootGroup) {
|
|
this.scrollProxy = $.proxy(this.scroll, this)
|
|
this.dragProxy = $.proxy(this.drag, this)
|
|
this.dropProxy = $.proxy(this.drop, this)
|
|
this.placeholder = $(this.options.placeholder)
|
|
|
|
if (!options.isValidTarget)
|
|
this.options.isValidTarget = undefined
|
|
}
|
|
}
|
|
|
|
ContainerGroup.get = function (options) {
|
|
if (!containerGroups[options.group]) {
|
|
if (options.group === undefined)
|
|
options.group = groupCounter++
|
|
|
|
containerGroups[options.group] = new ContainerGroup(options)
|
|
}
|
|
|
|
return containerGroups[options.group]
|
|
}
|
|
|
|
ContainerGroup.prototype = {
|
|
dragInit: function (e, itemContainer) {
|
|
this.$document = $(itemContainer.el[0].ownerDocument)
|
|
|
|
// get item to drag
|
|
var closestItem = $(e.target).closest(this.options.itemSelector);
|
|
// using the length of this item, prevents the plugin from being started if there is no handle being clicked on.
|
|
// this may also be helpful in instantiating multidrag.
|
|
if (closestItem.length) {
|
|
this.item = closestItem;
|
|
this.itemContainer = itemContainer;
|
|
if (this.item.is(this.options.exclude) || !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)) {
|
|
return;
|
|
}
|
|
this.setPointer(e);
|
|
this.toggleListeners('on');
|
|
this.setupDelayTimer();
|
|
this.dragInitDone = true;
|
|
}
|
|
},
|
|
drag: function (e) {
|
|
if (!this.dragging) {
|
|
if (!this.distanceMet(e) || !this.delayMet)
|
|
return
|
|
|
|
this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e)
|
|
this.item.before(this.placeholder)
|
|
this.dragging = true
|
|
}
|
|
|
|
this.setPointer(e)
|
|
// place item under the cursor
|
|
this.options.onDrag(this.item,
|
|
getRelativePosition(this.pointer, this.item.offsetParent()),
|
|
groupDefaults.onDrag,
|
|
e)
|
|
|
|
var p = this.getPointer(e),
|
|
box = this.sameResultBox,
|
|
t = this.options.tolerance
|
|
|
|
if (!box || box.top - t > p.top || box.bottom + t < p.top || box.left - t > p.left || box.right + t < p.left)
|
|
if (!this.searchValidTarget()) {
|
|
this.placeholder.detach()
|
|
this.lastAppendedItem = undefined
|
|
}
|
|
},
|
|
drop: function (e) {
|
|
this.toggleListeners('off')
|
|
|
|
this.dragInitDone = false
|
|
|
|
if (this.dragging) {
|
|
// processing Drop, check if placeholder is detached
|
|
if (this.placeholder.closest("html")[0]) {
|
|
this.placeholder.before(this.item).detach()
|
|
} else {
|
|
this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel, e)
|
|
}
|
|
this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop, e)
|
|
|
|
// cleanup
|
|
this.clearDimensions()
|
|
this.clearOffsetParent()
|
|
this.lastAppendedItem = this.sameResultBox = undefined
|
|
this.dragging = false
|
|
}
|
|
},
|
|
searchValidTarget: function (pointer, lastPointer) {
|
|
if (!pointer) {
|
|
pointer = this.relativePointer || this.pointer
|
|
lastPointer = this.lastRelativePointer || this.lastPointer
|
|
}
|
|
|
|
var distances = sortByDistanceDesc(this.getContainerDimensions(),
|
|
pointer,
|
|
lastPointer),
|
|
i = distances.length
|
|
|
|
while (i--) {
|
|
var index = distances[i][0],
|
|
distance = distances[i][1]
|
|
|
|
if (!distance || this.options.pullPlaceholder) {
|
|
var container = this.containers[index]
|
|
if (!container.disabled) {
|
|
if (!this.$getOffsetParent()) {
|
|
var offsetParent = container.getItemOffsetParent()
|
|
pointer = getRelativePosition(pointer, offsetParent)
|
|
lastPointer = getRelativePosition(lastPointer, offsetParent)
|
|
}
|
|
if (container.searchValidTarget(pointer, lastPointer))
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
if (this.sameResultBox)
|
|
this.sameResultBox = undefined
|
|
},
|
|
movePlaceholder: function (container, item, method, sameResultBox) {
|
|
var lastAppendedItem = this.lastAppendedItem
|
|
if (!sameResultBox && lastAppendedItem && lastAppendedItem[0] === item[0])
|
|
return;
|
|
|
|
item[method](this.placeholder)
|
|
this.lastAppendedItem = item
|
|
this.sameResultBox = sameResultBox
|
|
this.options.afterMove(this.placeholder, container, item)
|
|
},
|
|
getContainerDimensions: function () {
|
|
if (!this.containerDimensions)
|
|
setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent())
|
|
return this.containerDimensions
|
|
},
|
|
getContainer: function (element) {
|
|
return element.closest(this.options.containerSelector).data(pluginName)
|
|
},
|
|
$getOffsetParent: function () {
|
|
if (this.offsetParent === undefined) {
|
|
var i = this.containers.length - 1,
|
|
offsetParent = this.containers[i].getItemOffsetParent()
|
|
|
|
if (!this.options.rootGroup) {
|
|
while (i--) {
|
|
if (offsetParent[0] != this.containers[i].getItemOffsetParent()[0]) {
|
|
// If every container has the same offset parent,
|
|
// use position() which is relative to this parent,
|
|
// otherwise use offset()
|
|
// compare #setDimensions
|
|
offsetParent = false
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.offsetParent = offsetParent
|
|
}
|
|
return this.offsetParent
|
|
},
|
|
setPointer: function (e) {
|
|
var pointer = this.getPointer(e)
|
|
|
|
if (this.$getOffsetParent()) {
|
|
var relativePointer = getRelativePosition(pointer, this.$getOffsetParent())
|
|
this.lastRelativePointer = this.relativePointer
|
|
this.relativePointer = relativePointer
|
|
}
|
|
|
|
this.lastPointer = this.pointer
|
|
this.pointer = pointer
|
|
},
|
|
distanceMet: function (e) {
|
|
var currentPointer = this.getPointer(e)
|
|
return (Math.max(
|
|
Math.abs(this.pointer.left - currentPointer.left),
|
|
Math.abs(this.pointer.top - currentPointer.top)
|
|
) >= this.options.distance)
|
|
},
|
|
getPointer: function (e) {
|
|
var o = e.originalEvent || e.originalEvent.touches && e.originalEvent.touches[0]
|
|
return {
|
|
left: e.pageX || o.pageX,
|
|
top: e.pageY || o.pageY
|
|
}
|
|
},
|
|
setupDelayTimer: function () {
|
|
var that = this
|
|
this.delayMet = !this.options.delay
|
|
|
|
// init delay timer if needed
|
|
if (!this.delayMet) {
|
|
clearTimeout(this._mouseDelayTimer);
|
|
this._mouseDelayTimer = setTimeout(function () {
|
|
that.delayMet = true
|
|
}, this.options.delay)
|
|
}
|
|
},
|
|
scroll: function (e) {
|
|
this.clearDimensions()
|
|
this.clearOffsetParent() // TODO is this needed?
|
|
},
|
|
toggleListeners: function (method) {
|
|
var that = this,
|
|
events = ['drag', 'drop', 'scroll']
|
|
|
|
$.each(events, function (i, event) {
|
|
that.$document[method](eventNames[event], that[event + 'Proxy'])
|
|
})
|
|
},
|
|
clearOffsetParent: function () {
|
|
this.offsetParent = undefined
|
|
},
|
|
// Recursively clear container and item dimensions
|
|
clearDimensions: function () {
|
|
this.traverse(function (object) {
|
|
object._clearDimensions()
|
|
})
|
|
},
|
|
traverse: function (callback) {
|
|
callback(this)
|
|
var i = this.containers.length
|
|
while (i--) {
|
|
this.containers[i].traverse(callback)
|
|
}
|
|
},
|
|
_clearDimensions: function () {
|
|
this.containerDimensions = undefined
|
|
},
|
|
_destroy: function () {
|
|
containerGroups[this.options.group] = undefined
|
|
}
|
|
}
|
|
|
|
function Container(element, options) {
|
|
this.el = element
|
|
this.options = $.extend({}, containerDefaults, options)
|
|
|
|
this.group = ContainerGroup.get(this.options)
|
|
this.rootGroup = this.options.rootGroup || this.group
|
|
this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector
|
|
|
|
var itemPath = this.rootGroup.options.itemPath
|
|
this.target = itemPath ? this.el.find(itemPath) : this.el
|
|
|
|
this.target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this))
|
|
|
|
if (this.options.drop)
|
|
this.group.containers.push(this)
|
|
}
|
|
|
|
Container.prototype = {
|
|
dragInit: function (e) {
|
|
var rootGroup = this.rootGroup
|
|
|
|
if (!this.disabled &&
|
|
!rootGroup.dragInitDone &&
|
|
this.options.drag &&
|
|
this.isValidDrag(e)) {
|
|
rootGroup.dragInit(e, this)
|
|
}
|
|
},
|
|
isValidDrag: function (e) {
|
|
return e.which == 1 ||
|
|
e.type == "touchstart" && e.originalEvent.touches.length == 1
|
|
},
|
|
searchValidTarget: function (pointer, lastPointer) {
|
|
var distances = sortByDistanceDesc(this.getItemDimensions(),
|
|
pointer,
|
|
lastPointer),
|
|
i = distances.length,
|
|
rootGroup = this.rootGroup,
|
|
validTarget = !rootGroup.options.isValidTarget ||
|
|
rootGroup.options.isValidTarget(rootGroup.item, this)
|
|
|
|
if (!i && validTarget) {
|
|
rootGroup.movePlaceholder(this, this.target, "append")
|
|
return true
|
|
} else
|
|
while (i--) {
|
|
var index = distances[i][0],
|
|
distance = distances[i][1]
|
|
if (!distance && this.hasChildGroup(index)) {
|
|
var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)
|
|
if (found)
|
|
return true
|
|
} else if (validTarget) {
|
|
this.movePlaceholder(index, pointer)
|
|
return true
|
|
}
|
|
}
|
|
},
|
|
movePlaceholder: function (index, pointer) {
|
|
var item = $(this.items[index]),
|
|
dim = this.itemDimensions[index],
|
|
method = "after",
|
|
width = item.outerWidth(),
|
|
height = item.outerHeight(),
|
|
offset = item.offset(),
|
|
sameResultBox = {
|
|
left: offset.left,
|
|
right: offset.left + width,
|
|
top: offset.top,
|
|
bottom: offset.top + height
|
|
}
|
|
if (this.options.vertical) {
|
|
var yCenter = (dim[2] + dim[3]) / 2,
|
|
inUpperHalf = pointer.top <= yCenter
|
|
if (inUpperHalf) {
|
|
method = "before"
|
|
sameResultBox.bottom -= height / 2
|
|
} else
|
|
sameResultBox.top += height / 2
|
|
} else {
|
|
var xCenter = (dim[0] + dim[1]) / 2,
|
|
inLeftHalf = pointer.left <= xCenter
|
|
if (inLeftHalf) {
|
|
method = "before"
|
|
sameResultBox.right -= width / 2
|
|
} else
|
|
sameResultBox.left += width / 2
|
|
}
|
|
if (this.hasChildGroup(index))
|
|
sameResultBox = emptyBox
|
|
this.rootGroup.movePlaceholder(this, item, method, sameResultBox)
|
|
},
|
|
getItemDimensions: function () {
|
|
if (!this.itemDimensions) {
|
|
this.items = this.$getChildren(this.el, "item").filter(
|
|
":not(." + this.group.options.placeholderClass + ", ." + this.group.options.draggedClass + ")"
|
|
).get()
|
|
setDimensions(this.items, this.itemDimensions = [], this.options.tolerance)
|
|
}
|
|
return this.itemDimensions
|
|
},
|
|
getItemOffsetParent: function () {
|
|
var offsetParent,
|
|
el = this.el
|
|
// Since el might be empty we have to check el itself and
|
|
// can not do something like el.children().first().offsetParent()
|
|
if (el.css("position") === "relative" || el.css("position") === "absolute" || el.css("position") === "fixed")
|
|
offsetParent = el
|
|
else
|
|
offsetParent = el.offsetParent()
|
|
return offsetParent
|
|
},
|
|
hasChildGroup: function (index) {
|
|
return this.options.nested && this.getContainerGroup(index)
|
|
},
|
|
getContainerGroup: function (index) {
|
|
var childGroup = $.data(this.items[index], subContainerKey)
|
|
if (childGroup === undefined) {
|
|
var childContainers = this.$getChildren(this.items[index], "container")
|
|
childGroup = false
|
|
|
|
if (childContainers[0]) {
|
|
var options = $.extend({}, this.options, {
|
|
rootGroup: this.rootGroup,
|
|
group: groupCounter++
|
|
})
|
|
childGroup = childContainers[pluginName](options).data(pluginName).group
|
|
}
|
|
$.data(this.items[index], subContainerKey, childGroup)
|
|
}
|
|
return childGroup
|
|
},
|
|
$getChildren: function (parent, type) {
|
|
var options = this.rootGroup.options,
|
|
path = options[type + "Path"],
|
|
selector = options[type + "Selector"]
|
|
|
|
parent = $(parent)
|
|
if (path)
|
|
parent = parent.find(path)
|
|
|
|
return parent.children(selector)
|
|
},
|
|
_serialize: function (parent, isContainer) {
|
|
var that = this,
|
|
childType = isContainer ? "item" : "container",
|
|
|
|
children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () {
|
|
return that._serialize($(this), !isContainer)
|
|
}).get()
|
|
|
|
return this.rootGroup.options.serialize(parent, children, isContainer)
|
|
},
|
|
traverse: function (callback) {
|
|
$.each(this.items || [], function (item) {
|
|
var group = $.data(this, subContainerKey)
|
|
if (group)
|
|
group.traverse(callback)
|
|
});
|
|
|
|
callback(this)
|
|
},
|
|
_clearDimensions: function () {
|
|
this.itemDimensions = undefined
|
|
},
|
|
_destroy: function () {
|
|
var that = this;
|
|
|
|
this.target.off(eventNames.start, this.handle);
|
|
this.el.removeData(pluginName)
|
|
|
|
if (this.options.drop)
|
|
this.group.containers = $.grep(this.group.containers, function (val) {
|
|
return val != that
|
|
})
|
|
|
|
$.each(this.items || [], function () {
|
|
$.removeData(this, subContainerKey)
|
|
})
|
|
}
|
|
}
|
|
|
|
var API = {
|
|
enable: function () {
|
|
this.traverse(function (object) {
|
|
object.disabled = false
|
|
})
|
|
},
|
|
disable: function () {
|
|
this.traverse(function (object) {
|
|
object.disabled = true
|
|
})
|
|
},
|
|
serialize: function () {
|
|
return this._serialize(this.el, true)
|
|
},
|
|
refresh: function () {
|
|
this.traverse(function (object) {
|
|
object._clearDimensions()
|
|
})
|
|
},
|
|
destroy: function () {
|
|
this.traverse(function (object) {
|
|
object._destroy();
|
|
})
|
|
}
|
|
}
|
|
|
|
$.extend(Container.prototype, API)
|
|
|
|
/**
|
|
* jQuery API
|
|
*
|
|
* Parameters are
|
|
* either options on init
|
|
* or a method name followed by arguments to pass to the method
|
|
*/
|
|
$.fn[pluginName] = function (methodOrOptions) {
|
|
var args = Array.prototype.slice.call(arguments, 1)
|
|
|
|
return this.map(function () {
|
|
var $t = $(this),
|
|
object = $t.data(pluginName)
|
|
|
|
if (object && API[methodOrOptions])
|
|
return API[methodOrOptions].apply(object, args) || this
|
|
else if (!object && (methodOrOptions === undefined ||
|
|
typeof methodOrOptions === "object"))
|
|
$t.data(pluginName, new Container($t, methodOrOptions))
|
|
|
|
return this
|
|
});
|
|
};
|
|
|
|
}(jQuery, window, 'tokenize2sortable');
|