How to get select filters autoupdate?

How to get select filters autoupdate?

MickManMickMan Posts: 27Questions: 4Answers: 0

Hi everyone,

first of all sorry for my english.

I have 2 select filters and i need the second one to autoupdate itself whenever the first one is used.

I think the trick is done by the 'search applied' feature and i tried to make these examples to work on my case, but i'm not good enough.

http://live.datatables.net/gejojiqu/1/edit

http://live.datatables.net/xehimatu/1/edit

This is the code i'm using. The search feature is working fine except the autoupdate feature.

initComplete: function () {

            // Select Utente
            this.api().columns(0).every( function () {
                var column = this;
                var select = $('<select><option value="">MOSTRA TUTTI&#8287;&#8287;&#8287;</option></select>')
                .attr( "id", "idfiltrautente" )
                    .appendTo( $('#filtroutente') )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex(
                            $(this).val()
                        );

                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );

                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                } );
            } );

            // Apply the search
            this.api().columns().every( function () {
                var that = this;

                $( 'input', this.footer() ).on( 'keyup change clear', function () {
                    if ( that.search() !== this.value ) {
                        that
                            .search( this.value )
                            .draw();
                    }
                } );
            } );

        // Select Cliente
        this.api().columns(1).every( function () {
            var column = this;
            var select = $('<select><option value="">MOSTRA TUTTI&#8287;&#8287;&#8287;</option></select>')
            .attr( "id", "idfiltracliente" )
                .appendTo( $('#filtrocliente') )
                .on( 'change', function () {
                    var val = $.fn.dataTable.util.escapeRegex(
                        $(this).val()
                    );

                    column
                        .search( val ? '^'+val+'$' : '', true, false )
                        .draw();
                } );

            column.data().unique().sort().each( function ( d, j ) {
                select.append( '<option value="'+d+'">'+d+'</option>' )
            } );
        } );

        // Apply the search
        this.api().columns().every( function () {
            var that = this;

            $( 'input', this.footer() ).on( 'keyup change clear', function () {
                if ( that.search() !== this.value ) {
                    that
                        .search( this.value )
                        .draw();
                }
            } );
        } );
  }

Another cool addition would be to make the second filter disabled until the first one is used (not on the default option).

I can't link to a test case because i'm using private api data. :(
Is anyone willing to help me?

Thanks in advance
Michele

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    Basically those examples you linked to use the draw event to update the select lists. You need to choose one of the techniques and add the draw event code.

    Lines 24-35 and 58-69 are duplicates and will add multiple events to the select inputs. You only want to run this once. Remove 24-35.

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Than you very much for the reply kthorngren!

    You're right on the duplicate piece of code, of course.
    It works as before without it, indeed.

    About that draw event you mentioned, i really can't figure out how to use it with my code. :(

    I tried a lot of (messy, for sure) lines of code but i had no luck.
    I know luck is not what i need...

    If you could be more specific about what should i write and where i would be very grateful.

    I really thought the solutions was simply:

    var column = table.column( this, {search: 'applied'} );
    

    :#

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765
    Answer ✓

    var column = table.column( this, {search: 'applied'} );

    Yes, this is part of it. But you need to update the selects each time the table is drawn. Just running it once in initComplete creates a static list.

    I made a test case for you. Copied your code snippet into this example:
    http://live.datatables.net/jalaguxo/1/edit

    I used the first example. Copied your initComplete code into the buildSelect() function. Changed this.api() to table for the API instance. Changed to use table.column( this, {search: 'applied'} );. And removed the event handler in lines 58-69. The event is created on lines 9 and 43 in your above code snippet.

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Thank you so much for the time spent! Wow a custom example...
    Really. Thanks.

    I did it.
    I just kept the first filter with all values and just the second with the search applied.

    I also added the last part of code (from the example above) that repopulate the filter so i can use the option MOSTRA TUTTI to reset.


    Now i'm trying to disabling the second filter whenever the first one is on the default option MOSTRA TUTTI.

    I thought something like this would work, buuuuut nope (strange, uh?)

           if ($('#idfiltrautente').val() === "MOSTRA TUTTI";){
           $('#idfiltracliente').prop("disabled", true);};
    

    Here's my code, where i disable the second filter by default using .prop("disabled", true) until a draw is performed, using $('#idfiltracliente').prop("disabled", false);

    It's working, but of course won't disable the second filter when i choose the option MOSTRA TUTTI again on the first one.

    buildSelect( table );
      table.on( 'draw', function () {
        buildSelect( table );
      } );
    
    
    function buildSelect( table ) {
          // Select Utente
           table.columns(0).every( function () {
             var column = this;
             var select = $('<select><option value="">MOSTRA TUTTI;</option></select>')
             .attr( "id", "idfiltrautente" )
             .appendTo( $('#filtroutente').empty()  )
             .on( 'change', function () {
               var val = $.fn.dataTable.util.escapeRegex(
                 $(this).val()
               );
    
               column
               .search( val ? '^'+val+'$' : '', true, false )
               .draw();
               $('#idfiltracliente').prop("disabled", false);
             } );
    
             column.data().unique().sort().each( function ( d, j ) {
               select.append( '<option value="'+d+'">'+d+'</option>' );
             } );
             // The rebuild will clear the exisiting select, so it needs to be repopulated
        var currSearch = column.search();
        if ( currSearch ) {
          select.val( currSearch.substring(1, currSearch.length-1) );
        }
           } );
           // Select Cliente
           table.columns(1).every( function () {
             var column = table.column( this, {search: 'applied'} );
             var select = $('<select><option value="">MOSTRA TUTTI</option></select>')
             .attr( "id", "idfiltracliente" )
            .prop("disabled", true)
             .appendTo( $('#filtrocliente').empty()  )
             .on( 'change', function () {
               var val = $.fn.dataTable.util.escapeRegex(
                 $(this).val()
               );
    
               column
               .search( val ? '^'+val+'$' : '', true, false )
               .draw();
               $('#idfiltracliente').prop("disabled", false);
             } );
    
             column.data().unique().sort().each( function ( d, j ) {
               select.append( '<option value="'+d+'">'+d+'</option>' );
             } );
             // The rebuild will clear the exisiting select, so it needs to be repopulated
        var currSearch = column.search();
        if ( currSearch ) {
          select.val( currSearch.substring(1, currSearch.length-1) );
        }
           } );
    
    
    
         }
    

    This is not an important feature, but would be better for sure.

    Thanks again for your help kthorngren! <3

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765
    edited September 2021

    When MOSTRA TUTTI is displayed the value is "", for example: <option value="">MOSTRA TUTTI;</option>. Try if ($('#idfiltrautente').val() === "";){....}.

    You are welcome for the help.

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Thanks again Kevin.
    I tried it but doesn't work.
    The easiest thing can be an obstacle when you are a newbee like me. XD

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    The easiest way to progress this would be to update Kevin's example with what you've got, then we've got something we can work with together,

    Colin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Thank you Colin.
    Just updated.

    http://live.datatables.net/jalaguxo/2/edit

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    I just noticed that another cool feature would be to automatically reset the second filter to the default MOSTRA TUTTI when the first one is changed. This way you don't need to manually select it.

    I tried and of course i failed.

  • MickManMickMan Posts: 27Questions: 4Answers: 0
    edited September 2021

    I solved my problems. B)

    To reset the second filter (#idfiltracliente) whenever the first one is changed:

    $('#idfiltracliente').val('').trigger('change');
    

    in the change function of the buildSelect function of the first filter (#idfiltrautente)

    To reset and disable the second filter whenever the first one is resetted:

    if ($('#idfiltrautente').val() == '') {
               $('#idfiltracliente').val('');
               $('#idfiltracliente').prop("disabled", true);
                                 };
    

    If someone is interested:

    buildSelect( table );
      table.on( 'draw', function () {
        buildSelect( table );
      } );
    
    
    function buildSelect( table ) {
          // Select Utente
           table.columns(0).every( function () {
             var column = this;
             var select = $('<select><option value="">MOSTRA TUTTI&#8287;&#8287;&#8287;</option></select>')
             .attr( "id", "idfiltrautente" )
             .appendTo( $('#filtroutente').empty()  )
             .on( 'change', function () {
               var val = $.fn.dataTable.util.escapeRegex(
                 $(this).val()
               );
    
               $('#idfiltracliente').val('').trigger('change');
    
               column
               .search( val ? '^'+val+'$' : '', true, false )
               .draw();
             } );
    
             column.data().unique().sort().each( function ( d, j ) {
               select.append( '<option value="'+d+'">'+d+'</option>' );
             } );
             // The rebuild will clear the exisiting select, so it needs to be repopulated
        var currSearch = column.search();
        if ( currSearch ) {
          select.val( currSearch.substring(1, currSearch.length-1) );
        }
           } );
    
           // Select Cliente
           table.columns(1).every( function () {
             var column = table.column( this, {search: 'applied'} );
             var select = $('<select><option value="">MOSTRA TUTTI&#8287;&#8287;&#8287;</option></select>')
             .attr( "id", "idfiltracliente" )
             .appendTo( $('#filtrocliente').empty()  )
             .on( 'change', function () {
               var val = $.fn.dataTable.util.escapeRegex(
                 $(this).val()
               );
    
               column
               .search( val ? '^'+val+'$' : '', true, false )
               .draw();
             } );
    
             column.data().unique().sort().each( function ( d, j ) {
               select.append( '<option value="'+d+'">'+d+'</option>' );
             } );
             // The rebuild will clear the exisiting select, so it needs to be repopulated
        var currSearch = column.search();
        if ( currSearch ) {
          select.val( currSearch.substring(1, currSearch.length-1) );
        }
           } );
    
    
             if ($('#idfiltrautente').val() === '') {
               $('#idfiltracliente').val('');
               $('#idfiltracliente').prop("disabled", true);
                                 }
    
         }
    

    Thanks again and again and again for your help Kevin.
    I was lost.

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Ok now i'm nitpicking, but i want the table to be the more user friendly as possible.

    In my case i have more options for the second filter and whenever an option is selected all the others disappear and the only way to get them back is to reset the filter using the default option MOSTRA TUTTI.

    Is there a way to tell the second filter to update itself only when the first one is being used?

    // Select Cliente
           table.columns(1).every( function () {
             var column = table.column( this, {search: 'applied'} ); <-- is possible only for column 0?
    

    In the example in the second filter there's only one option, so i've edited it.
    Select the first name "Angelica Ramos" in the first filter to replicate the "problem".

    http://live.datatables.net/gugiviya/1/edit

    I know i'm tedious, but maybe the solution is simple...

    Thanks

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    Sorry, I'm not clear on what you are wanting to do. In the example choosing Angelica Ramos updates the Position select list with the three available options. Having more options available won't allow you to filter the table differently as those rows are already being filtered out.

    Datatables does an AND search across all the columns. Maybe you are wanting an OR search, like this example:
    http://live.datatables.net/mucevape/1/edit

    It allows you to search both columns independently. Doing an OR search requires creating a Search Plugin and not using the Datatables column().search() API.

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0
    edited September 2021

    Hi Kevin! Thanks as usual for your interest.

    The column filter is working perfectly, so the AND search is good.
    I'm talking about the dropdown list.

    What i'd like to do is that once i've selected one of the 3 options of Angelica Ramos in the second filter, the other 2 options doesn't disappear, so i can select them without clicking MOSTRA TUTTI to show the options again.

    In other words, i'd like the second filter being update only when using the first filter .

    It's not a vital feature of course, but it would save some clicks with big option lists. :)

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765
    Answer ✓

    Makes sense now. I would look at creating a global boolean variable. In each column's change event set the boolean true or false. Then is an if statement to determine if the Position column should be updated.

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Thank you Kevin.
    I'm going to set your message as answer, even if it's too much for me.
    I barely understand what you're talking about. :D

    I can understand the logic and a piece of code when i read it, but there's no way i can write something like that. I'm not so good.

    I don't want to bother you again. If i can save some time i'll try to cope with it learning the code.

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765
    Answer ✓
  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Kevin what can i say?

    T-H-A-N-K-Y-O-U

    That's not enough. How can i show you my gratitude?
    Can i at least offer you a couple of beer somehow? A paypal donation?

    We know you deserve it.

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    That beer sounds great - maybe after work :smiley:

    Please donate to the Datatables team who built the code you are using. Think think you can donate here:
    https://datatables.net/purchase/index

    Kevin

  • MickManMickMan Posts: 27Questions: 4Answers: 0

    Just did it.
    I'm now a medio supporter. :D
    A donation was absolutely deserved.

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Thank you, @MickMan , it's appreciated, and thanks for the suggestion, Kevin!

    Colin

Sign In or Register to comment.