302 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			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);
 |