Sunday, September 20, 2015

STARTS WITH INSTEAD OF CONTAINS FILTER TEXT




HTML Markup


For the HTML markup, everything looks the same as the default filtering setup. For our example, we will have a listview that displays a list of names and has autodividers turned on:

<form class="ui-filterable">
  <input id="myFilter" data-type="search" placeholder="Enter search text..." />
</form>
<ul id="myList" data-role="listview" data-filter="true" data-input="#myFilter" data-autodividers="true" data-inset="true">
  <li data-filtertext="project manager"><a href="#">Aaron</a></li>
  <li><a href="#">A</a></li>
  <li><a href="#">B</a></li>
  <li><a href="#">C</a></li>
  <li><a href="#">D</a></li>
  <li><a href="#">E</a></li>
  <li><a href="#">F</a></li>
  <li><a href="#">G</a></li>
  <li><a href="#">H</a></li>
  <li><a href="#">I</a></li>
  <li><a href="#">J</a></li>
  <li><a href="#">K</a></li>
...
  <li><a href="#">L</a></li>
  <li><a href="#">M</a></li>
  <li><a href="#">N</a></li>
  <li><a href="#">O</a></li>
  <li><a href="#">P</a></li>
  <li><a href="#">Q</a></li>
  <li><a href="#">R</a></li>           
</ul>


The first name in the list also has some extra filter text: data-filtertext=”project manager”. So if you type the letter ‘p’ into the filter input, we would expect all listitems starting with p and the listitem for Adam to be displayed.


Script


In order to override the default filtering behavior, we need to provide JavaScript that assigns the filterCallback property of the filterable widget to our own custom filtering function:

$(document).on("pagecreate", "#page1", function(){
    $("#myList").filterable('option', 'filterCallback', startsWithSearch);
});


function startsWithSearch( idx, searchValue ) {
    var ret = false;
    if (searchValue && searchValue.length > 0){       
        var text = $(this).text().toLowerCase();
        var filttext = $(this).data("filtertext") || '';
        filttext = filttext.toLowerCase();
        if( text.lastIndexOf(searchValue.toLowerCase(), 0) != 0 && filttext.lastIndexOf(searchValue.toLowerCase(), 0) != 0){
            ret = true; //filter this one out
        }
    }
    return ret;
}



 
The callback function is called once for each of the items in the filterable and its context is set to the item DOM element for which a decision is needed.  We can, therefore, use the keyword this to refer to the item DOM element.

The startsWithSearch function gets the child element text and the data-filtertext attribute if it exists, then if search text has been entered, we see if either the listitem text or data-filtertext starts with the search text. If it does NOT, we return true which tells the filterable widget to mark this element as hidden in the page. To make the filter case insensitive, we convert all strings to lower case before comparing them; and as JavaScript does not have a string.startsWith() function built in, I am using lastIndexOf().

Popular Posts