bachy 40f34e2191 first import
Signed-off-by: bachy <git@g-u-i.net>
2012-01-09 11:08:29 +01:00

302 lines
8.1 KiB
JavaScript

/*
* selectList jQuery plugin
* version 0.4.2
*
* Copyright (c) 2009-2011 Michal Wojciechowski (odyniec.net)
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://odyniec.net/projects/selectlist/
*
*/
(function ($) {
$.selectList = function (select, options) {
var
$selectSingle,
$list,
$item, $newItem,
$option,
keyEvent,
ready,
first = 0,
change, click, keypress, enter;
function show($item, callback) {
if (options.addAnimate && ready)
if (typeof options.addAnimate == 'function')
options.addAnimate($item.hide()[0], callback);
else
$item.hide().fadeIn(300, callback);
else {
$item.show();
if (callback)
callback.call($item[0]);
}
}
function hide($item, callback) {
if (options.removeAnimate && ready)
if (typeof options.removeAnimate == 'function')
options.removeAnimate($item[0], callback);
else
$item.fadeOut(300, callback);
else {
$item.hide();
if (callback)
callback.call($item[0]);
}
}
function cmp(item1, item2) {
return typeof options.sort == 'function' ?
options.sort(item1, item2)
: ($(item1).data('text') > $(item2).data('text'))
== (options.sort != 'desc');
}
function add(value, text, callHandler) {
if ($(value).is('option')) {
$option = $(value);
if ($option[0].index < first)
return;
value = $option.val();
text = $option.text();
}
else {
$option = $selectSingle.find("option[value=\"" +
value.replace("'", "\\\"") + "\"]");
if ($option.length)
$option = $option.filter(function () {
return !text || $(this).text() == text;
})
.add($option).eq(0);
else
$option = null;
}
if (text === undefined)
text = $option ? $option.text() : value;
if ($option && !options.duplicates)
$option.attr('disabled', 'disabled')
.data('disabled', 1);
$newItem = $(options.template.replace(/%text%/g,
$('<b/>').text(text).html()).replace(/%value%/g, value)).hide();
$newItem.data('value', value).data('text', text).data('option', $option)
.addClass(options.classPrefix + '-item');
$newItem.click(function () {
if (options.clickRemove)
remove($(this));
});
if (first && !keypress)
$selectSingle[0].selectedIndex = 0;
var callback = function () {
if (callHandler !== false)
options.onAdd(select, value, text);
};
if (options.sort && ($item = $list.children().eq(0)).length) {
while ($item.length && cmp($newItem[0], $item[0]))
$item = $item.next();
show($item.length ? $newItem.insertBefore($item)
: $newItem.appendTo($list), callback);
}
else
show($newItem.appendTo($list), callback);
$(select).empty();
$list.children().each(function () {
$(select).append($("<option/>").attr({ value: $(this).data('value'),
selected: "selected" }));
});
checkValidation();
}
function remove($item, callHandler) {
hide($item, function () {
var value = $(this).data('value'),
text = $(this).data('text');
if ($(this).data('option'))
$(this).data('option').removeAttr('disabled')
.removeData('disabled');
$(this).remove();
$(select).find("option[value=\"" + value + "\"]").remove();
checkValidation();
if (callHandler !== false)
options.onRemove(select, value, text);
});
}
function checkValidation() {
if (select.form && typeof ($(select.form).validate) == "function" &&
$(select).add($selectSingle).hasClass($(select.form)
.validate().settings.errorClass))
$(select.form).validate().element(select);
}
this.val = function () {
return $(select).val();
};
this.add = function (value, text) {
add(value, text);
};
this.remove = function (value) {
$list.children().each(function () {
if ($(this).data('value') == value || typeof value == 'undefined')
remove($(this));
});
};
this.setOptions = function (newOptions) {
var sort = newOptions.sort && newOptions.sort != options.sort;
options = $.extend(options, newOptions);
if (sort) {
var items = [];
$list.children().each(function () {
items[items.length] = $(this).data('value')
items[items.length] = $(this).data('text');
});
$list.empty();
for (var i = 0; i < items.length; i += 2)
add(items[i], items[i+1], false);
}
};
this.setOptions(options = $.extend({
addAnimate: true,
classPrefix: 'selectlist',
clickRemove: true,
removeAnimate: true,
template: '<li>%text%</li>',
onAdd: function () {},
onRemove: function () {}
}, options));
$selectSingle = $(select).clone();
$selectSingle.removeAttr('id').removeAttr('name')
.addClass(options.classPrefix + '-select').insertAfter($(select));
$(select).empty().hide();
($list = $(options.list || $("<ul/>").insertAfter($selectSingle)))
.addClass(options.classPrefix + '-list');
$selectSingle.find(':selected').each(function () {
add($(this), null, false);
});
$selectSingle.removeAttr('multiple');
$selectSingle.get(0).removeAttribute('size');
if ($selectSingle.attr("title")) {
$selectSingle.prepend($("<option/>")
.text($selectSingle.attr("title")));
first = 1;
$selectSingle[0].selectedIndex = 0;
}
keyEvent = $.browser.msie || $.browser.safari ? 'keydown' : 'keypress';
$selectSingle.bind(keyEvent, function (event) {
keypress = true;
if ((event.keyCode || event.which) == 13) {
enter = true;
$selectSingle.change();
keypress = true;
return false;
}
})
.change(function() {
if (!keypress && !click) return;
change = true;
$option = $selectSingle.find("option:selected");
if (!$option.data("disabled") && (!keypress || enter))
add($option);
if (keypress)
keypress = change = click = false;
enter = false;
})
.mousedown(function () {
click = true;
});
$selectSingle.find('option').click(function (event) {
if ($.browser.mozilla && event.pageX >= $selectSingle.offset().left &&
event.pageX <= $selectSingle.offset().left +
$selectSingle.outerWidth() &&
event.pageY >= $selectSingle.offset().top &&
event.pageY <= $selectSingle.offset().top +
$selectSingle.outerHeight())
return false;
click = true;
if (!($(this).attr('disabled') || $(this).data('disabled') || keypress
|| change))
add($(this));
if (!keypress)
change = click = false;
return false;
});
ready = true;
};
$.fn.selectList = function (options) {
options = options || {};
this.filter('select').each(function () {
if ($(this).data('selectList'))
$(this).data('selectList').setOptions(options);
else
$(this).data('selectList', new $.selectList(this, options));
});
if (options.instance)
return this.filter('select').data('selectList');
return this;
};
})(jQuery);