Search code examples
jquery-mobilejquery-mobile-listview

JQuery Mobile filterable listview with multiple filters


I have a JQM 1.4.2 filterable listview which contain entries in different languages.

I would like to search only within items code, not the whole description, whereby i set the data-filtertext for list items to the item code, e.g. "Apple" or "Banana". This works ok but now i need an additional language filter, e.g. "EN", "DE", and so on:

...
<li data-filtertext="Apple language_en">
    <h2>Title</h2>
    <p>Red fruit</p>
    <p class="ui-li-aside"><strong>EN</strong></p>
</li>
...
...
<li data-filtertext="Banana language_de">
    <h2>Titel</h2>
    <p>Beschreibung</p>
    <p class="ui-li-aside"><strong>DE</strong></p>
</li>
...

This is my data input:

<form class="ui-filterable">
    <div class="ui-grid-a">
        <div class="ui-block-a">
            <input id="descriptions-input" data-type="search" placeholder="Search..." />
        </div>
        <div class="ui-block-b">
            <fieldset data-role="controlgroup" data-type="horizontal">
                <input name="lang-en" id="lang-en" type="checkbox" data-mini="true">
                <label for="lang-en">EN</label>
                <input name="lang-de" id="lang-de" type="checkbox" data-mini="true">
                <label for="lang-de">DE</label>
                <input name="lang-fr" id="lang-fr" type="checkbox" data-mini="true">
                <label for="lang-fr">FR</label>
            </fieldset>
        </div>
    </div>
</form>

What i try to do now, is that when a checkbox is selected, only the list items belonging to that language are visible.

How can i set this additional filter to my filterable jQuery Mobile listview?

Plunker: http://plnkr.co/edit/TV6rcatzdvaIvQzWBdoI?p=preview

EDIT:

This is the final solution, thanks to EZANKER: https://jsfiddle.net/m64kg5fw/4/


Solution

  • The filterable widget as a filterCallback property: http://api.jquerymobile.com/filterable/#option-filterCallback

    You can use this to write a function that checks both the text and which language checkboxes are checked.

    $(document).on("pagecreate", "#list-descriptions", function () {   
        $("#descriptions-list").filterable('option', 'filterCallback', checkedOrMatch);
    
        $("#searchLangs input").on("change", function(){
          $("#descriptions-list").filterable("refresh");
        });
    });
    
    function checkedOrMatch(idx, searchValue) {
        var ret = false;
        var en = $("#lang-en").is(':checked');
        var de = $("#lang-de").is(':checked');
        var fr = $("#lang-fr").is(':checked');
        var ignoreLang = false;
        if (!en && !de && !fr) {
            ignoreLang = true;
        }
    
        if (searchValue && searchValue.length > 0) {
            searchValue = searchValue.toLowerCase();
            var filttext = $(this).data("filtertext") || '';
            filttext = filttext.toLowerCase();
            if (filttext.indexOf(searchValue) < 0) {
                ret = true; //filter this one out
            } else if (!ignoreLang) {       
                //found filter text now check language
              if (  (filttext.indexOf("language_en") > 0 && !en) || (filttext.indexOf("language_de") > 0 && !de) || (filttext.indexOf("language_fr") > 0 && !fr) ) {
                ret = true; //filter this one out
              }            
            }      
        }    
        return ret;
    }
    

    Updated DEMO

    The checkedOrMatch functions runs for each item in the list. It first tests if the entered search text is found in the filter text. If it is, it then sees which language buttons are checked and tests the item for that language. I also added code to re-trigger the filter if the user selects language buttons after typing the search criteria.

    NOTE: if the user types in "lang" you might not get what you want... In that case you could move the language designation out of the filter text and into a separate data-attribute.