Skip to content
This repository

improvement request : listview search field callback on keyup #4721

Closed
nbigot opened this Issue July 18, 2012 · 13 comments

6 participants

Nicolas Bigot Ghislain Seguin Todd Parker Jasper de Groot John Bender jaivehall
Nicolas Bigot
nbigot commented July 18, 2012

Hi,

I would like to use the listview component with search field to make a search for ZIP code, postal code, city name.
Due to the large amount of postal codes (for example in France we have more than 36000 ;) I need to fill the listview
depending of what the user has typed.
I also need to set my own comparaison function (no accents, lower case, sort order, limit of items, ...)

So I managed to do this by simply add a callback to the existing code:
details of the change:
in listview.filter.js :

        .bind( "keyup change", function() {

        // begin of new code
        // Callback function allow to change listItems depending of the
        // value of search text
        if ( $.isFunction( listview.options.onkeyupcallback ) ) {
            listview.options.onkeyupcallback( $( this ) );
        }
        // end of new code  

        var $this = $( this ),
            val = this.value.toLowerCase(),
            listItems = null,
            lastval = $this.jqmData( "lastval" ) + "",
            childItems = false,
            itemtext = "",
            item;

Is it possible to include this improvement in the code?

I don't know much about github (not shure I done the right thing), I've made a fork and a new branch
https://github.com/nbigot/jquery-mobile/tree/dynamic-listview-filter

Should I send a pull request?

Thanks in avance.

ps: I didn't put there the javascript code to perform a ZIP/postal search but if you need it I'll be happy to share.

Nicolas Bigot.

Todd Parker

I like this idea. @gseguin will follow up.

Jasper de Groot
Owner

@nbigot

+1 for the idea. As a side note. I think people would really appreciate it if your share your code for the "ZIP code search" at the forum: http://forum.jquery.com/jquery-mobile
Thanks!

Nicolas Bigot
nbigot commented July 20, 2012

Ok thanks, I'm doing a little refactoring of my code to make a demo from it.
I'll let you know when it's ready and I'll post it on the forum.

Nicolas Bigot
nbigot commented July 21, 2012

Hi again,
I've just finished to clean up my code a little bit and I put it there
https://github.com/acsn/postalcodesearch
I needed one more parameter to do it well (the list itself):

.bind( "keyup change", function() {

        // begin of new code
        // Callback function allow to change listItems depending of the
        // value of search text
        if ( $.isFunction( listview.options.onkeyupcallback ) ) {
            listview.options.onkeyupcallback( $( this ), list );
        }
        // end of new code

I'm now going to put the dome on the forum.

edit:
https://forum.jquery.com/topic/using-listview-to-make-a-search-for-zip-code-postal-code-city-name

Ghislain Seguin gseguin referenced this issue from a commit in gseguin/jquery-mobile July 27, 2012
Ghislain Seguin Proposed fix for #4721: Added a "listviewbeforefilter" event f79a399
Ghislain Seguin
Collaborator

@nbigot: I submitted a proposed fix. Let me know if that addresses your use case.
/cc @johnbender, @uGoMobi

Nicolas Bigot
nbigot commented July 28, 2012

@gseguin
Hi, the fix does not work for me because I need to skip the filtering after I injected new data items in the list (I used to change the 'lastval' variable from outside the class but I realize that was an ugly hack so I changed your code a little bit and now it work find and it's clean (I hope) :

        .bind( "keyup change", function() {

            var $this = $(this),
                val = this.value.toLowerCase(),
                listItems = null,
                lastval = $this.jqmData( "lastval" ) + "",
                childItems = false,
                itemtext = "",
                item,
                lbfEvent = new $.Event( "listviewbeforefilter", { input: this, inputtext: this.value } );

            list.trigger( lbfEvent );
            if ( lbfEvent.isDefaultPrevented() ) {
                // Skip filtering
                val = "";
                lastval = "";
            }

            // Change val as lastval for next execution
            $this.jqmData( "lastval" , val );

Let me explain the modifications:
first I do need to know what is the value of the input text so I added two parameters to the event you created
(if I don't have this value I can't fill the list with my custom item values)
then when I fill the list with new items (all items are removed then new ones are added) : it means that they don't need to be filtered after.

in my event catch function I call event.preventDefault(); which means skip filtering;

onlistviewbeforefilter: function( event ) {
    var thisClass = dialog_postalCodeSearch; // custom internal class
    var listviewObj = $(this); // pointer to the listview object
    var searchText = lib_string.toNoAccents( event.inputtext ).toLowerCase(); // transform input text for search
    thisClass.fillListItems( listviewObj, searchText ); // fill list with custom items
    event.preventDefault(); // prevent from filtering items
},

note about filtering :
why do I added code to chane val and lastval variables?:
if I don't set val and lastval to "" then a search with accends won't work (exemple : enter "côte" the 'ô' would be filtered but I want it to be considered as a regular 'o')

I hope you understand my issues because it's not very easy for me to explain. ;)

Regards,

Nicolas.

/cc @johnbender, @uGoMobi

John Bender

@nbigot @gseguin

If you alter the $.listview.prototyope.options.filterCallback to be a no-op or something more complex, does that work in conjunction with the event?

I made a suggestion in the pull request that we include the search field as a data item on the event, or simply expose the search field somehow so that users's can bind to it as they please thereby avoiding any use case predictions.

Would making the search field available, either as event data or as an attribute, allow you to do what you want?

Nicolas Bigot
nbigot commented July 30, 2012

@johnbender @gseguin

Yes you're right it works this way too with less code modification,
I've tested it with success by doing something like this:


alwaysMatch: function ( itemtext, val ) {
    return false;
},

...
listviewObj.listview( 'option', 'filterCallback', thisClass.alwaysMatch );

As long as we keep the new event and the input value/input field as parameter of the event it's fine.

Thanks.

John Bender

@nbigot

I talked with @gseguin and he'll get this rolled in at the end of the week.

Ghislain Seguin
Collaborator

I just updated the PR. We now send the input field as an attribute of the data object.
@nbigot that should take care of your use case.

Nicolas Bigot

@gseguin Yes it does, thank you very much.

Ghislain Seguin gseguin closed this August 02, 2012
Todd Parker

Removing feature request flag, feature landed for 1.2

jaivehall

@nbigot

i improved this callback function base on your code, to pass the key event to the callback function:

.bind( "keyup change", function(e) {
// begin of new code
// Callback function allow to change listItems depending of the
// value of search text
if ( $.isFunction( listview.options.onkeyupcallback ) ) {
listview.options.onkeyupcallback( e, $( this ), list );
}
// end of new code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.