I have the following code to filter a UL list based on click on another UL.
I will append dynamically some more elements to the bs-glyphicons-list-sub list to be filtered and I need to modify my code for this.
$('.show-fields').click(function(e) { e.preventDefault(); $('.subList').hide(); var filter = $(this).data('filtro'); if (filter == "tutti") { $('#closer').hide(); $('.fieldsList').show(); $('#closer').show(); $('.subList').show(); } else { $('#closer').hide(); $('.fieldsList').show().not('li[data-tipo=' + filter + ']').hide(); $('#closer').show(); $('.subList').show(); } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="bs-glyphicons"> <ul class="bs-glyphicons-list"> <li class="show-fields" data-filtro="tutti" data-html="true" title="Visualizza <b>tutti i campi</b>"><span class="glyphicon glyphicon-search"></span><span class="glyphicon-class">Tutti</span></li> <li class="show-fields" data-filtro="input" data-html="true" title="Campi basati su template <b>input</b>"><span class="glyphicon glyphicon-log-in"></span><span class="glyphicon-class">Input</span></li> <li class="show-fields" data-filtro="textarea" data-html="true" title="Campi su template <b>testo libero</b>"><span class="glyphicon glyphicon-unchecked"></span><span class="glyphicon-class">Testo libero</span></li> <li class="show-fields" data-filtro="opzioni" data-html="true" title="Campi su template <b>opzioni</b>"><span class="glyphicon glyphicon-th-list"></span><span class="glyphicon-class">Opzioni</span></li> <li class="show-fields" data-filtro="validato" data-html="true" title="Campi su template <b>input validati</b>"><span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Input validati</span></li> <li data-html="true" title="Aggiungi un campo" data-toggle="modal" id="addField"><span class="glyphicon glyphicon-plus"></span><span class="glyphicon-class">Aggiungi un campo</span></li> </ul> </div> <ul class="bs-glyphicons-list-sub"> <li class="fieldsList" data-tipo="input" data-label="Nome" data-value="1" data-description="Qual � il tuo nome di battesimo?" id="fields_nome"> <span class="glyphicon glyphicon-log-in"></span><span class="glyphicon-class">Nome</span> </li> <li class="fieldsList" data-tipo="input" data-label="Cognome" data-value="2" data-description="Qual � il tuo cognome? Per le donne il cognome da nubile" id="fields_cognome"> <span class="glyphicon glyphicon-log-in"></span><span class="glyphicon-class">Cognome</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Mail" data-value="3" data-description="Indica la tua mail aziendale" id="fields_mail"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Mail</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Telefono" data-value="4" data-description="Telefono: Un campo testo di massimo 256 caratteri senza formato specifico" id="fields_telefono"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Telefono</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Codice fiscale" data-value="5" data-description="Codice fiscale: Un campo testo in formato codice fiscale italiano" id="fields_codice-fiscale"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Codice fiscale</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Data" data-value="6" data-description="Data: Un campo data generico in formato gg/mm/aaaa" id="fields_data"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Data</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Ora" data-value="7" data-description="Ora: Un campo ora generico in formato hh:mm" id="fields_ora"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Ora</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Cellulare" data-value="8" data-description="Il tuo cellulare aziendale" id="fields_cellulare-it"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Cellulare</span> </li> <li class="fieldsList" data-tipo="validato" data-label="Cellulare internazionale" data-value="9" data-description="Cellulare internazionale: Un campo cellulare da minimo 12 massimo 15 cifre che richiede country code all'inizio (formato +############)" id="fields_cellulare-ex"> <span class="glyphicon glyphicon-filter"></span><span class="glyphicon-class">Cellulare internazionale</span> </li> <li class="fieldsList" data-tipo="textarea" data-label="Indirizzo di domicilio" data-value="13" data-description="Indirizzo di domicilio: dove vivi abitualmente" id="fields_indirizzo2"> <span class="glyphicon glyphicon-unchecked"></span><span class="glyphicon-class">Indirizzo di domicilio</span>
The line I need to modify is the following:
$('.fieldsList').show().not('li[data-tipo='+filter+']').hide();
where I need to include the elements that I appended after DOM ready. I know about delegated events, I know how to use .on(), what I don’t know is how to apply delegated events binding to the filter function here. The elements I click on are immutable so I don’t think that using .on() on the click event may lead to something useful.
Advertisement
Answer
What you are doing is: Add event handling to elements, which are available at the start ($('.show-fields').click()
). DOM elements that are added later don’t trigger this event.
What you need to be doing is: Delegate the click
event. By catching the event on the <ul>
which is already there at startup and delegating the event handling to the <li>
on which the event occurred, you also catch DOM elements inside the <ul>
which are added later.
I also deleted the then branch of the if, because you can set the filter for tutti
to the empty string and it will work automatically.
console.clear(); $('.show-fields-list').on('click', '.show-fields', function(e) { console.log(e) e.preventDefault(); $('.subList').hide(); var filter = $(this).data('filtro'); $('#closer').hide(); $('.fieldsList').show().not('li[data-tipo=' + filter + ']').hide(); $('#closer').show(); $('.subList').show(); }); $('#add-new-filter').on('click', function() { $('.show-fields-list').append($('<li class="show-fields" data-filtro="' + $('#add-new-filter-filter').val() + '">' + $('#add-new-filter-label').val() + '</li>')) }) $('#add-new-option').on('click', function() { $('.fields').append($('<li class="fieldsList" data-tipo="' + $('#add-new-option-tipo').val() + '">' + $('#add-new-option-label').val() + '</li>')) })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <input id="add-new-filter-filter" placeholder="filter"> <input id="add-new-filter-label" placeholder="label"> <button id="add-new-filter">Add new filter</button><br> <ul class="show-fields-list"> <li class="show-fields" data-filtro="">Tutti</li> <li class="show-fields" data-filtro="input">Input</li> <li class="show-fields" data-filtro="textarea">Testo libero</li> <li class="show-fields" data-filtro="opzioni">Opzioni</li> <li class="show-fields" data-filtro="validato">Input validati</li> </ul> <input id="add-new-option-tipo" placeholder="tipo"> <input id="add-new-option-label" placeholder="label"> <button id="add-new-option">Add new option</button><br> <ul class="fields"> <li class="fieldsList" data-tipo="input"> Nome </li> <li class="fieldsList" data-tipo="input"> Cognome </li> <li class="fieldsList" data-tipo="validato"> Mail </li> <li class="fieldsList" data-tipo="validato"> Telefono </li> <li class="fieldsList" data-tipo="validato"> Codice fiscale </li> <li class="fieldsList" data-tipo="validato"> Data </li> <li class="fieldsList" data-tipo="validato"> Ora </li> <li class="fieldsList" data-tipo="new"> New </li> <li class="fieldsList" data-tipo="validato"> Cellulare </li> <li class="fieldsList" data-tipo="validato"> Cellulare internazionale </li> <li class="fieldsList" data-tipo="textarea"> Indirizzo di domicilio </li> </ul>