New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvement request : listview search field callback on keyup #4721

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

Comments

Projects
None yet
6 participants
@nbigot

nbigot commented Jul 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.

@ghost ghost assigned gseguin Jul 19, 2012

@toddparker

This comment has been minimized.

Show comment
Hide comment
@toddparker

toddparker Jul 19, 2012

Contributor

I like this idea. @gseguin will follow up.

Contributor

toddparker commented Jul 19, 2012

I like this idea. @gseguin will follow up.

@jaspermdegroot

This comment has been minimized.

Show comment
Hide comment
@jaspermdegroot

jaspermdegroot Jul 19, 2012

Member

@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!

Member

jaspermdegroot commented Jul 19, 2012

@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!

@nbigot

This comment has been minimized.

Show comment
Hide comment
@nbigot

nbigot Jul 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.

nbigot commented Jul 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.

@nbigot

This comment has been minimized.

Show comment
Hide comment
@nbigot

nbigot Jul 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

nbigot commented Jul 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

gseguin added a commit to gseguin/jquery-mobile that referenced this issue Jul 27, 2012

@gseguin

This comment has been minimized.

Show comment
Hide comment
@gseguin

gseguin Jul 27, 2012

Member

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

Member

gseguin commented Jul 27, 2012

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

@nbigot

This comment has been minimized.

Show comment
Hide comment
@nbigot

nbigot Jul 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

nbigot commented Jul 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

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Jul 30, 2012

Contributor

@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?

Contributor

johnbender commented Jul 30, 2012

@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?

@nbigot

This comment has been minimized.

Show comment
Hide comment
@nbigot

nbigot Jul 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.

nbigot commented Jul 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.

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Jul 30, 2012

Contributor

@nbigot

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

Contributor

johnbender commented Jul 30, 2012

@nbigot

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

@gseguin

This comment has been minimized.

Show comment
Hide comment
@gseguin

gseguin Aug 1, 2012

Member

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.

Member

gseguin commented Aug 1, 2012

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.

@nbigot

This comment has been minimized.

Show comment
Hide comment
@nbigot

nbigot Aug 2, 2012

@gseguin Yes it does, thank you very much.

nbigot commented Aug 2, 2012

@gseguin Yes it does, thank you very much.

gseguin added a commit that referenced this issue Aug 2, 2012

Merge pull request #4760 from gseguin/issue-4721
Proposed fix for #4721: Added a "listviewbeforefilter" event

@gseguin gseguin closed this Aug 2, 2012

@toddparker

This comment has been minimized.

Show comment
Hide comment
@toddparker

toddparker Sep 24, 2012

Contributor

Removing feature request flag, feature landed for 1.2

Contributor

toddparker commented Sep 24, 2012

Removing feature request flag, feature landed for 1.2

@jaivehall

This comment has been minimized.

Show comment
Hide comment
@jaivehall

jaivehall Dec 18, 2012

@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

jaivehall commented Dec 18, 2012

@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