Значения из select выбираем в отдельный список.

Здесь мы собираем сниппеты - кусочки jQuery-кода, позволяющие решить какую-либо небольшую задачу. Топикстартер обязан предоставить свой сниппет, чтобы открыть тему!

Модераторы: zandroid, EGORR

Правила форума
Чтобы открыть тему, необходимо представить свой jQuery-код и html-разметку (при необходимости), а также подробно все прокомментировать! В открытой теме все могут оставлять комментарии, задавать вопросы.

Значения из select выбираем в отдельный список.

Сообщение EGORR » 20 дек 2010, 17:25

Недавно пришлось решать задачу предоставления юзеру выбора множества недублирующихся значения при ограниченности свободного места.
Использовал html select. Работает так: юзер из списка( например профессий ) выбирает нужные. Они исчезая из селекта наполняют список прямо под ним. Кликом по пункту в новом списке, его можно вернуть обратно в селект.
Я написал это как плагин. Может кому-то пригодится... Подробности в комментах...
Пример использования
Код: выделить все
<script type="text/javascript">

    $( document ).ready( function()
    {
                $( "select[name='city']" ).list_selected();

    } );

</script>

<style type="text/css">
    .displayResult
    {
        background-color   : #b0c4de;
        color              : white;
        border             : 1px #fff solid;
        padding            : 5px;
        -moz-border-radius : 3px;
        border-radius      : 3px;
        text-shadow        : 1px 1px 1px #000;
        -webkit-box-shadow : 0px 0px 3px #1a1a1a;
        -moz-box-shadow    : 0px 0px 3px #1a1a1a;
        box-shadow         : 0px 0px 3px #1a1a1a;
    }

    .displayResult span:hover
    {
        color              : red;
        text-shadow        : 0 0 0 transparent;
    }
</style>


    <select name="city" class="city">
        <option value="">Выбрать город</option>
        <option value="1">Ярославль</option>
        <option value="2">Москва</option>
        <option value="3">Пермь</option>
        <option value="4">Новосибирск</option>
        <option value="5">Хабаровск</option>
        <option value="6">Благовещенск</option>
        <option value="7">Нижневартовск</option>
        <option value="8">Тобольск</option>
        <option value="900">Тюмень</option>
    </select>



Код: выделить все
jQuery.fn.list_selected = function( options )
{
    var options = jQuery.extend( {

        elementClass: 'lsc', // класс элемента select

        displayResultClass: 'displayResult', // класс элемента select

        input_name: "ResultInput"  // имя инпата в который будут перекидываться значения выбираемых оптионов

    }, options );

    return this.each( function()
    {

        // если селект не имеет дефолтного класса,..

        if ( !jQuery( this ).hasClass( options.elementClass ) )
        {
            jQuery( this ).addClass( options.elementClass );  // добавляем его
        }


        jQuery( this ).change( function() // событие .change - изменение состояния выбора селекта
        {

            if ( !jQuery( this ).next().hasClass('result_')  ) // проверяем не создан ли уже элемент-контейнер для списка
            {
                // если не создан, добавляем его сразу после селекта с которым работаем

                jQuery( this ).after( "<div class=\"result_\">\n</div>\n" );

                jQuery( "div.result_").css( "width", jQuery( this ).width() );

            }

            // игнорируем выбор оптиона с пустым или равным нулю значением
            // предполагается, что в нем предложение юзеру выбрать из списка
            if ( this.selectedIndex != '0' || this.value != 0 )
            {

                 jQuery( this ).next()
                        .attr( 'title', 'Для удаления сделайте клик' )// добавляем в элемент-контейнер title-подсказку...
                        .prepend( "<span style='cursor:pointer' class=\"" + options.elementClass + "_item\"   id=\"" + options.elementClass + "_item\"  rel=\"" + this.options[this.selectedIndex].value + "\">" + this.options[this.selectedIndex].text + ",\n<input name=\"" + options.input_name + "[]\" value=\"" + this.options[this.selectedIndex].value + "\" type=\"hidden\"></span>" );

                //... и добавляем в него span в атрибут rel которого кладем взятое из option  value (это может понадобится позже, при удалении, для опознания...)
                // ещё в span кладем текст выбранного пункта, а за текстом добавляем скрытый input, в value которого кладем value  выбранного пункта
                // Для того, чтобы при отсылке на сервер из этих множественных значения получился массив, скрытому input даем имя вида name="inputName[]"

                // Теперь, когда выбранный пункт появился в результирующем списке под селектом, спрячем его из селекта, чтобы юзер не выбрал его ещё раз...
                // если для нормальных браузеров достаточно скрыть пункт, то недобраузер IE стилизовать селект не умеет. Поэтому для него будем выбранный
                // пункт дисаблить...
                // определять тупицу будем такой вот регуляркой /MSIE (\d+\.\d+);/


                if ( /MSIE (\d+\.\d+);/.test( navigator.userAgent ) )
                {
                    jQuery( this.options[this.selectedIndex] ).attr( 'disabled', true );
                    jQuery( this ).stop(true,true).animate( {opacity: .2}, 500 ).stop(true,true).animate( {opacity: 1}, 500 );
                }
                else
                {
                    jQuery( this.options[this.selectedIndex] ).hide();
                    jQuery( this ).stop(true,true).animate( {opacity: .2}, 500 ).stop(true,true).animate( {opacity: 1}, 500 );
                }
                jQuery( this.options[0] ).attr( 'selected', true ); // после всех этих операций, делаем выбранным самый первый оптион

            }


        } );

        // удалятор выбранных пунктов из списка-контейнера
        // Поскольку нам придется обращаться к элементам, которых призагрузке ещё не было в DOMике, используем .live, либо .delegate (лучше .delegate)
        // тут все просто... На клик по span пунктом, читаем его атрибут rel
        // Поскольку значение rel взято было из value скрытого/дисабленного ныне оптиона нашего селекта, то легко выполнить обратную процедуру.
       
        jQuery( "body" ).delegate( "span." + options.elementClass + "_item", "click", function()
        {

            if ( /MSIE (\d+\.\d+);/.test( navigator.userAgent ) )
            {
                jQuery( "select." + options.elementClass + " option[value=" + this.getAttribute( 'rel' ) + "]" ).attr( 'disabled', false );
                jQuery( "select." + options.elementClass ).animate( {opacity: .2}, 500 ).animate( {opacity: 1}, 500 );
            }
            else
            {
                jQuery( "select." + options.elementClass + " option[value=" + this.getAttribute( 'rel' ) + "]" ).show();
                jQuery( "select." + options.elementClass ).animate( {opacity: .2}, 500 ).animate( {opacity: 1}, 500 );
            }

            jQuery( this ).remove();

            jQuery( "div.result_:empty" ).remove(); // удаляем пустые контейнеры

        } );

    } );
};
Life is very short, and there's no time
For fussing and fighting, my friend...
Аватар пользователя
EGORR
Модератор
 
Сообщений: 720
Зарегистрирован: 22 янв 2010, 01:44
Откуда: Ярославль

Вернуться в jQuery сниппеты

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3