Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [JavaScript] Pole wielokrotnego wyboru
Forum PHP.pl > Forum > Przedszkole
miki22
Bardzo denerwuje mnie niewygodny i brzydki input typu multi select. W necie znalazłem bardzo fajsy skrypt pozwalający zastąpić go aktywnym polem wyboru.

Źródło w rozdziale: Fancy JavaScript method

Kod
HTLM:
<ul>
  <li onclick="this.parentNode.removeChild(this);"> <input type="hidden" name="ingredients[]" value="Cheese" /> Cheese </li>
  <li onclick="this.parentNode.removeChild(this);"> <input type="hidden" name="ingredients[]" value="Ham" /> Ham </li>
  <li onclick="this.parentNode.removeChild(this);"> <input type="hidden" name="ingredients[]" value="Mushrooms" /> Mushrooms </li>
</ul>

<select onchange="selectIngredient(this);">
  <option value="Cheese">Cheese</option>
  <option value="Olives">Olives</option>
  <option value="Pepperoni">Pepperoni</option>
  ...
</select>

JS:
function selectIngredient(select)
{
  var option = select.options[select.selectedIndex];
  var ul = select.parentNode.getElementsByTagName('ul')[0];
  var choices = ul.getElementsByTagName('input');
  for (var i = 0; i < choices.length; i++)
  if (choices[i].value == option.value) return;

  var li = document.createElement('li');
  var input = document.createElement('input');
  var text = document.createTextNode(option.firstChild.data);
  
  input.type = 'hidden';
  input.name = 'ingredients[]';
  input.value = option.value;

  li.appendChild(input);
  li.appendChild(text);
  li.setAttribute('onclick', 'this.parentNode.removeChild(this);');
  ul.appendChild(li);
}



Bardzo mi się to spodobało i pasuje idealnie do projektu który tworzę. Jest mały szkopuł. Potrzebuję dodatkowe opcje w select. Opcję 'wszystko' oraz 'nic'. Problem polega na tym, że wybranie którejś z tych opcji musi kasować wszystkie wybrane do tej pory. I odwrotnie. Jeśli jest już wybrana opcja 'wszystko' (bądź 'nic') a ktoś wybierze opcje np. 'Ham' to oczywiście wybrana poprzednio opcja np. 'wszystko' ulega skasowaniu.
Moja wiedza nt. js jest niewystarczająca by to zrobić. Może ktoś mądrzejszy znajdzie chwilkę by dopisać taki kod sprawdzający/kasujący? <prosi>
golabow
Przepisałem to w jQuery i dodałem opcje o które Ci chodziło. Zobacz tutaj:
skrytp js
miki22
Jesteś WIELKI Golabow! Na prawdę jestem Ci bardzo bardzo wdzięczny, że chciało ci się poświęcić swój czas!
Mam nadzieję, że nie tylko mi się przyda ten skrypt, bo jest to bardzo fajna alternatywa dla milti-select'a.
Mała uwaga, bo w ferworze roboty umknęło Ci, iż to ma być część formularza, więc dodawać ma nie tylko element <li> ale także <input> typu hidden by dodane dane nie tylko ukazywały się ale też mogły być przesłane razem z formularzem. Ale to nawet ja ze swoimi zerowymi umiętnościami w zakresie jQuery (ale pewną wiedzą nt języków skryptowych) na podstawie Twojego kodu potrafiłem dodać odpowiednie linijki.

A to wersja uwzględniająca możliwość przesyłania z formularzem: (pewnie nie tylko mi się przyda)
Kod
SKRYPT:

$(document).ready(function (){
function find( heap, needle )
{
    var b = 1;
    $( heap ).each(function(){
        if ( $( this ).text() == needle ) b = 0;
    });

    return b ? true : false;
}

function addNode( parent, nodeText )
{
    var newLi = document.createElement( "li" );
    var newInput = document.createElement( "input" );
    $( newLi ).text( nodeText ).addClass('food').on( 'click', function(){ $( this ).remove(); } );
    $( newInput ).attr('type','hidden').attr('value',nodeText).attr('name',nodeText);

    $( parent ).append( newLi );
    $( newLi ).append( newInput );
}

$(document).ready(function (){

    $( '.food' ).click(function(){
        $( this ).remove();
    });

    $( '#foodMenu' ).change(function(){
        var food = $( this ).val();

        switch( food )
        {
            case 'all':
                $( '#foodMenu option' ).each( function(){
                    var nodeName = $( this ).val();
                     if ( nodeName != 'all' && nodeName != 'nothing' && find( '.food', $( this ).text() ) )
                     {
                         addNode( '#foodList', $( this ).text() );
                     }
                });
                break;
            case 'nothing':
                $( '#foodList li' ).each( function() { $(this).remove(); } )
                break;
            default:
                if ( !find( '.food', food ) ) return false;
                addNode( '#foodList', food );
        }
    });

});
});


HTML:

<form method="post" action="">
<ul id="foodList">
        <li class="food">Cheese</li>
        <li class="food">Ham</li>
        <li class="food">Mushrooms</li>
    </ul>

    <select id="foodMenu">
        <option value="all">All</option>
        <option value="nothing">Nothing</option>
        <option value="Cheese">Cheese</option>
        <option value="Olives">Olives</option>
        <option value="Pepperoni">Pepperoni</option>
    </select>
<input type="submit">
</form>


Jeszcze raz WIELKIE DZĘKI thumbsupsmileyanim.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.