7

In jquery datatable, I have to filter the result with exact match and highlight it. for exact match I am trying following code but it does not work. fiddle

table.aoPreSearchCols[ iCol ].sSearch = "^\\s*"+'1'+"\\s*$";
table.aoPreSearchCols[ iCol ].bRegex = false;
table.aoPreSearchCols[ iCol ].bSmart= false;
davidkonrad
  • 83,997
  • 17
  • 205
  • 265
Jitender
  • 7,593
  • 30
  • 104
  • 210

3 Answers3

9

I think you need to use a word boundary, \b :

Matches a word boundary. A word boundary matches the position where a word character is not followed or preceeded by another word-character.

So when you have search term "limit" and the strings "my word has no limit", "it is unlimited" only the first string is a match. So

$('#search-inp').keyup(function(){
    var term = $(this).val(),
        regex = '\\b' + term + '\\b';

    table.columns(1).search(regex, true, false).draw();
})

Highlight

Define some static "highlight tags" to inject and remove in order to highlight search matches :

var hlBegin = '<strong class="highlight">',
    hlEnd = '</strong>';

Adding the highlight tags to column content :

function highlight(term) {
    var row, str,
        rowCount = table.rows().nodes().length,
        regexp = new RegExp('('+term+')', 'ig');

    for (row=0; row<rowCount; row++) {
        str = table.cell(row, 1).data();
        str = str.replace(regexp, function($1, match) { 
           return hlBegin + match + hlEnd;
        })
        table.cell(row, 1).data(str).draw();
    }        
}  

Removing highlight tags :

function removeHighlight() {
    var row, str,
        rowCount = table.rows().nodes().length;

    for (row=0; row<rowCount; row++) {
        str = table.cell(row, 1).data();
        str = str.replace(/(<([^>]+)>)/ig, '');
        table.cell(row, 1).data(str).draw();
    }        
}    

Setting it all together :

$('#search-inp').keyup(function(){
    var term = $(this).val(),
        regex = '\\b' + term + '\\b';

    removeHighlight();
    table.columns(1).search(regex, true, false);
    highlight(term);
})

forked fiddle -> http://jsfiddle.net/Lnvbnp6c/


Update. I got the impression (through comments) that whole words anywhere should be matched. If it is about matching a whole word in the beginning of the column :

regex = '^' + term + '\\b';

http://jsfiddle.net/Lnvbnp6c/1/

If it is just about matching characters the column begins with, not nessecarily a whole word :

regex = '^' + term;

http://jsfiddle.net/Lnvbnp6c/2/

The last one is probably the one users would like the most, when they are typing in the search field.


As an alternative approach you could try to use a custom filter :

$('#search-inp').keyup(function() {
    var str,
        term = $(this).val(),
        regexp = new RegExp('\\b' + term + '\\b', 'ig');

    removeHighlight();    
    $.fn.dataTable.ext.search.push(
        function(settings, data, dataIndex ) {
            str = data[1];
            return regexp.test(str) ? true : false;
        }     
    );
    table.draw();
    highlight(term);    
    $.fn.dataTable.ext.search.pop();
})

demo with highlight as above -> http://jsfiddle.net/x96hzok4/

My impression is that this is a little bit faster. Certainly, if you have a lot of rows, and want to search on multiple columns, I think you should consider a custom filter, and consider not to make time-consuming complete regular expressions on all strings.

davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • Thanks a lot for nice answer. Just one more think. I checked fiddle attached by You. I need to modify word boundary. The regex should match world starting. – Jitender Apr 27 '15 at 12:19
  • Like if I type"Tige". Then it should select first, I have remove the last '\\b' from the regex but when I am typing "T" then word have t between the word is also get highlighted – Jitender Apr 27 '15 at 12:21
  • hey @amit, It was actually was I was started out with - but when I saw the comment : _I have two paragraph "my word has no limit" "it is unlimited". If I type limit then first paragraph should show and changed focus_. See update for either exact match starting word, or just match starting characters ...Seems to be starting characters you really want. – davidkonrad Apr 27 '15 at 12:31
  • fiddle with regex = '\\b' + term + '\\b' is seem to usefull for me. I removed the //regex = '\\b' + term the last '\\b'. when we type only one letter that it has a problem – Jitender Apr 27 '15 at 13:25
  • @amit "_when we type only one letter that it has a problem_", yes, you have the problem that nothing compares to that single character ..? Or what is the problem? Funny you say it, I have thought about the same, that you should have a click-button instead of instant search, or perhaps a delay after keyup instead. – davidkonrad Apr 27 '15 at 21:39
  • Hi, I've seen all your answers here. I was wondering if you could help me too? It's about filtering the gender in my table list. When I search for "Male", both Male and Female shows up. How will I do it that only records with gender Male will show up? Thank you so much, hope you can help me. So far this is just what I have. I have no idea how to do what I want. Please help me. https://jsfiddle.net/v0r4jr97/ – Louie May 11 '16 at 16:39
2

Try

$('#search-inp').keyup(function(){
    var key = $(this).val();
    var regExp = "."
    if (key)
        regExp = "^\\s*" + key + "\\s*$";

    table.columns(1).search(regExp, true).draw();
});

When search key is empty always set it to . matches any in regex.

Alvin Magalona
  • 771
  • 3
  • 13
0

Try

  $('#search-inp').keyup(function(){
      var elem = $(this)
      table.columns(1)
      .search("^\\s*"+elem.val()+"\\s*$", true)
      .draw()
  });

jsfiddle http://jsfiddle.net/yg32o2yh/6/

See column().search() ; see also $.fn.dataTable.util.escapeRegex()

guest271314
  • 1
  • 15
  • 104
  • 177