Filter table with exact match

Filter table with exact match

Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

Hello everybody
i have this code that should filter a table

if I click on the Alex checkbox nothing happens

but if I click on Alex 2 the filter will be executed

the problem is that the code is not doing an exact search

where is the error in the code?

<script>

// start filter checkbox    2 di 2

$('input:checkbox').on('change', function () {
   //build a regex filter string with an or(|) condition
   //build a filter string with an or(|) condition
   
   var credit = $('input:checkbox[name="cred"]:checked').map(function() {
     return this.value;
   }).get().join('|');
   
   //now filter in column 2, with no regex, no smart filtering, not case sensitive
   table.column(4).search(credit, true, false, false).draw(false);
   
   //
   
</script>

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    You have regex searching enabled:

    table.column(4).search(credit, true, false, false).draw(false);
    

    Your search string looks to be just Alex or Alex 2. With regex that will match both names. If you want Alex to match only Alex then you need to do something like this ^Alex$. You can try different regex patterns with this example.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    Thanks for the reply kthorngren :)
    can you help me with the code ?, it's too complicated there :/
    I'm not that experienced (I'm not a programmer) :(

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    Try this:

       var credit = $('input:checkbox[name="cred"]:checked').map(function() {
         return "^" + this.value + "$";
       }).get().join('|');
    

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    does not work :|

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0
    var credit = $('input:checkbox[name="cred"]:checked').map(function() {
      return "^" + this.value + "$";
    }).get().join('|');
       
     //now filter in column 2, with no regex, no smart filtering, not case sensitive
    table.column(4).search(credit, true, false, false).draw(false);
    
  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    alternative solution?

    does not work :/

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    I didn't look that close at your actual data - I thought it was "Alex" and "Alex 2". But its actually "Test movie per Alex" and "Test movie per Alex 2". If the exact match you want is always at the end of the string then you can remove the "^" + on line 2. If the exact match can be in the middle of the string then it will be very difficult, I think, to distinguish between "Alex" and "Alex 2" with an exact match. The solution I provided is an exact match for the full string.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    it should work like this
    example
    Alex, Alex 2, Alex 3
    Alex filter only Alex and exclude the others
    Alex 2 filter only Alex 2 and exclude the others
    Alex 3 filter only Alex 3 and exclude the others

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    The example I gave will do that if your cell data contains only the text you are trying to filter. For example:
    http://live.datatables.net/xoduxaye/2/edit

    But your data, in the first post, includes other text than the exact match string you are trying to filter. Your exact match will need to be "Test movie by Alex" to match only that row. Otherwise the regex search will match both rows with "Alex" and "Alex 2". There is not a simple solution to have "Test movie by Alex" and "Test movie by Alex 2" and have an exact match of just "Alex" show only "Test movie by Alex". Likely a Search plugin will need to be written to support this type of matching.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    Hi kthorngren,

    strange, in your code (which is I replicated) everything works
    but in mine the data is taken from a mysql database and processed in the php code and then passed to the checkbox
    column 0 'Movie Title' is not taken into account
    and column 4 "Credited 'which must be filtered, and also specified in the code
    table.column (4) .search (credit, true, false, false) .draw (false);
    but it doesn't happen :/

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    Can you link to your page please so we can debug it?

    Colin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    Hi colin

    sorry i'm not on the internet, everything works in localhost
    but I can post the piece of code in php that queries the database and executes everything

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    It looks like your data has extra text, ie, Alex (52) and Alex 2 (12). If this is consistent then the regex expression can be updated to include that part of the string. Something like this should work return "^" + this.value + "\\W\\(\\d+\\)";. Note the double backslashes. The backslashes need to be escaped so they are part of the string. See this updated example:
    http://live.datatables.net/xoduxaye/4/edit

    A good place to workout regex expressions is https://regex101.com/ . I tested the regex expression here:
    https://regex101.com/r/tst0sf/1

    Use the above to update and test the regex expression if the above doesn't work with your data. Make sure to use exact examples of your data.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    Hi kthorngren

    i found the error, and in the php code, exactly here


    <td><?php echo $row->credited;?> <br> <?php $var1 = $row->birthday; $var2 = $row->film_year; if($var1 != "0000-00-00" AND $var1 != null){ <?php > ?> (<font color="blue"><?php echo $var2 - substr($var1, 0, 4); ?></font>) <?php }else{ <?php > (No birthday) <?php } ?> <?php > ?>

    in the same column I entered the credited and birthday film_year, the latter calculates the release of the film and the birthday of the actor and returns how old he was when he starred in that film
    the regex works
    now I have to think how to fix it, I would not want to create another column :|

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    i have tested this and it doesn't work
    return "^" + this.value + "\\ W \\ (\\ d + \\)";
    the reason is why after credited there is **<br> **

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    so select everything

    it should be so

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    edited July 2021

    now I have to think how to fix it, I would not want to create another column

    You can have a hidden column and search the hidden column. Use columns.visible to hide the column.

    i have tested this and it doesn't work

    Looks like you have spaces following the backslashes. There should not be spaces. Not sure what you mean by the <br> comment.

    If you want further help for this please build a test case that replicates your exact data so we can provide a more specific answer. Otherwise use https://regex101.com/ to workout the appropriate regex.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    <td><?php echo $row->credited;?>
    <br>
    <?php

    $var1 = $row->birthday;

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951

    Maybe change \W to \W+ or maybe better \s+ for one or more matches. See the regex help for details of what these mean.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    look

    after the name is present <br>
    as you can see it doesn't work

    http://live.datatables.net/xoduxaye/6/edit

  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    Answer ✓

    Like I said you have extra spaces after the backslashes (and other places) in your regex expression. So regex is looking for literal spaces. Also, since you have more than one whitespace character between the name and the (52) you need to add a +. Either replace the \W with \W+ or use \s+. See the updated example:
    http://live.datatables.net/xoduxaye/7/edit

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    it works :)
    thank you kthorngren
    you were very kind to help me

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    kthorngren hi
    can you kindly explain this regex to me?

    return "^" + this.value + "\\W+\\(\\d+\\)";
    
  • kthorngrenkthorngren Posts: 21,330Questions: 26Answers: 4,951
    Answer ✓

    The regex101 site will explain it better than I can :smile:

    Take a look at the regex101 test case:
    https://regex101.com/r/tst0sf/1

    The top right provides the details of the regex. The bottom right has a quick reference so you can see other tokens. There are lots of regex tutorials online that you can use to learn regex.

    Kevin

  • Alex2019Alex2019 Posts: 62Questions: 9Answers: 0

    Thanky

Sign In or Register to comment.