Alberto Giorgis
Alberto Giorgis

Reputation: 153

Datatables data search and highlight with jmHighligh limit to one column (solution at the end)

I'm working with Datatables.

Datatables allows you to have one single search box included in plug in, but with help of many of your posts I was able to make a single column search for each column (I know there was a plugin of Datatables for I was unable to make it work for me).

After this I've tried to implement the code to obtain search results highlighted in table after search (again with Datatable highlight plugin). I was able to do this, but than I wanted to add another highlight plugin for each search box I've created.

I was also able to deal with this metter (using jquery.jmHighlight.min.js code) but I've found 2 different problems:

  1. I was unable to limit to a single column the highlighting
  2. I was unable to avoid highlight disappear clicking on next search box.

Here is the part of code I'm using:

<script>
function filterGlobal () {
    $('#example').DataTable().search(
       $('#global_filter').val()
    ).draw();
}

function filterColumn ( i ) {
    $('#example').DataTable().column( i ).search( 
       $('#col'+i+'_filter').val() 
    ).draw();

    var keyword = $('#col'+i+'_filter').val(); // this is to retrieve what have been inserted in search box called "colNUMOFCOLUMNfilter"

    $('#col'+i+'_filter td:nth-child(1)').jmRemoveHighlight(); //one of my test to limit search to a single column (the same as search box)
    $('#col'+i+'_filter td:nth-child(1)').jmHighlight(keyword); //one of my test to limit search to a single column (the same as search box)
   //I've also tried with:  $('input.column_filter').on( 'keyup click', jmRemoveHighlight()); $('input.column_filter').on( 'keyup click', jmHighlight(keyword));]

}

$(document).ready(function() {
[...]
   var table = $('#example').DataTable( {
   [...]
      "ajax": {
      [...]
      // HIGHLIGHT SEARCH (from Datatable that works only with global filter)
      "searchHighlight": true,
      [...]
   $('input.global_filter').on( 'keyup click', function () {
    filterGlobal();
   });

   $('input.column_filter').on( 'keyup click', function () {
    filterColumn( $(this).parents('tr').attr('data-column') );
   });
   [...]
</script>

So my problems are:

  1. limit to a single column the highlighting. When I use the code above ($('#example tbody').jmRemoveHighlight()/jmHighlight(keyword)) it works but all the words matching with the input are highlighted.

  2. Avoid highlight disappear clicking on next search box. With that code, when I've something highlighted due to search box input, when I click on another search box, the highlighted word return normal, even deactivating jmRemoveHighlight().

It would be great to be able to add one search result highlighted to the next one, until you don't reset everything, limiting results to a single column each search box (only first search box would be a general search into the whole table).

UPDATE v. 0.1

That's true, I'm not really good with javascript and jquery, but I thought this would have worked, what's wrong?

 $(document).ready(function() {
     var table = $('#example').DataTable( {
     [all vars of plugin]
 } );

 //many listeners like
 // LINE FOR COL REORDER    
 new $.fn.dataTable.ColReorder( table );

 // LINE FOR ENLIGHT SELECTED ROW 
 $('#example tbody').on( 'click', 'tr', function () {
    $(this).toggleClass('selected');
 } );

 // HERE I've tried mine
 // TEST TEST
 $("input[name='keyword']").on("keyup", function () {
    window.alert("test");
    var datacol = table.column( 1 ).data(); //func of datatables to retrieve column data
    highilightMe( datacol ); //my function
});
// TEST TEST
[... many others working listeners]
});

//My function 
function highilightMe( datacol ) {
window.alert("HEY I AM HERE!");

// Read keyword
var keyword = $("input[name='keyword']").val(); //input for test highlight

//var table = $('#example').DataTable();
//var data = table.column( 0 ).data();
//Highlight the keyword inside the context
//$("#example, td, row").eq(1).jmRemoveHighlight();
//$("#example, td, row").eq(1).jmHighlight(keyword);
//window.alert();

$("#example", datacol).jmRemoveHighlight();
$("#example", datacol).jmHighilight(keyword);
}

But it stills doesn't work and not even WINDOWS.ALERT works... so it means function isn't well called, but why...?

P.S. what's really strange is that using $("#example, td, row").eq(1).jmRemoveHighlight() I was able to highlight just one CELL but in another TABLE (mine with datatables on is called #example).

UPDATE v. 0.2

In order to understand what wasn't working and considering my little knowledge of jQuery, I've rebuilt a test page to check what wasn't working.

Here follow the code of that page that uses datatables. I was able to recover also data column, but I'm not able to use that var (an array of data) as #container to limit highlight function.

Here is full code:

 [...]
 <script type="text/javascript" charset="utf8" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
 <script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
 <script type="text/javascript" src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
 <script type="text/javascript" src="https://cdn.datatables.net/fixedheader/3.0.0/js/dataTables.fixedHeader.min.js"></script>
 <script type="text/javascript" src="https://cdn.datatables.net/colreorder/1.2.0/js/dataTables.colReorder.min.js"></script>
 <script type="text/javascript" src="https://cdn.datatables.net/rowreorder/1.0.0/js/dataTables.rowReorder.min.js"></script>

 <title>Untitled Document</title>

 <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
 <script type="text/javascript" src="js/dataTables.searchHighlight.min.js"></script>
 <script type="text/javascript" src="js/jquery.highlight.js"></script>
 <link rel="stylesheet" type="text/css" href="css/dataTables.searchHighlight.css">
 <script type="text/javascript" src="js/jquery.jmHighlight.min.js">    </script>
 </head>

 <body>
 <br />
 <div class="title"><u>Search module</u></div><br />
 <br />
 <table id="example" class="show" id="show">
    <thead>
        <tr>
            <th>Market</th>
            <th>Curr</th>
            <th>Prods<br />(Qn)</th>
            <th>Quality</th>
            <th>Seller<br />(type)</th>
            <th>Type</th>
            <th>Stock</th>
            <th>Price<br />(curr)</th>
            <th>GOLD<br />Curr<br />change</th>
            <th>Price<br />(GOLD)</th>
            <th>Vat<br />tax</th>
            <th>Loc. Seller<br />price</th>
            <th>Imp.<br />Tax</th>
            <th>Int. Seller<br />price</th>
            <th>Link</th>
            <th>Serv</th>
            <th>Time Rec</th>
            <th>Date</th>
        </tr>
    </thead>
    <tbody>
    <br />
    </tbody>
 </table>
 <br />
 <hr width="95%" align="center">
 <br />
 <div class="col-xs-6">
    <span>Type in a keyword:</span>
    <input type="text" name="keyword" id="keyword" placeholder="Lorem ipsum..."> //I uses this for TESTING
 </div>
 <br />
 <hr width="95%" align="center">
 <br />

 <script>
 function test ( keyword ) {
     var col = $('#example').DataTable();
     var datac = col.column( 0 ).data();
     console.log( datac );
    //$.inArray(keyword,[datac]);
    //$.inArray(jmHighlight( keyword ),[datac]);

    //$("#example", datacol).jmRemoveHighlight();
    //$("#example", datacol).jmHighilight(keyword);
    $datac.jmRemoveHighlight(); //this return an error about finding datac var...
    $datac.jmHighlight( keyword );
 }

 $(document).ready(function() {
 // TEST TEST
     $("#keyword").on("keyup", function () {
     var keyword = $("#keyword").val(); 
     test( keyword );
});
// TEST TEST
var serverChoice = "server";
var table = $('#example').DataTable( {
    "processing": true,
    "rowReorder": true,
    "lengthMenu": [ [30, 60, 90, 120, 150, -1], [30, 60, 90, 120, 150, "All"] ],
    "language": {
    "loadingRecords": "Please wait - loading..."
    },
    select: {
        style: 'multi'
    },
    "ajax": {
        "url": "server_processing_prods.php?serverch="+serverChoice,
        "dataSrc": "demo",
    },
    //CHANGE COLOR OF FONT ON DATA  
    "createdRow": function ( row, data, index ) {
        // if ( data[7].replace(/[\$,]/g, '') * 1 > 10 ) {
        if ( (data[14]) = "Evening Record" ) {
            $('td', row).eq(14).addClass('evening_record');
        } else if ( (data[14]) = "Night Record" ) {
            $('td', row).eq(14).addClass('night_record');
        } else if ( (data[14]) = "Afernoon Record" ) {
            $('td', row).eq(14).addClass('afternoon_record');
        } else if ( (data[14]) = "Morning Record" ) {
            $('td', row).eq(14).addClass('morning_record');
        }
    },
    // HIGHLIGHT SEARCH
    //"searchHighlight": true,      
    //this is to set the link
       "columnDefs": [
            {  
                "targets": [0],
                "render": function ( data ) { 
                    return '<center><b><font size="1">' + data + '</font></b></center>'; 
                }
            },
            { 
                "targets": [1],
                "render": function ( data ) { 
                    return '<center><font size="1">' + data + '<br /><div class="sprite ' + data + '"></div></font></center>'; 
                }   
            },
            { 
                "targets": [2],
                "render": function ( data, type, row ) { 
                    return '<center><b><font size="1">'+ data +'</b><i> Q'+ row[3] +'</font></i></center>'; 
                }
            },              
            {  
                "targets": [3, 9, 11, 13],
                "render": function ( data ) { 
                    return '<font size="1"><center>' + data + '</center></font>'; 
                }
            },
            { 
                "targets": [4],
                "render": function ( data, type, row ) { 
                    return '<center><font size="1">'+ data +'<br><i>('+ row[5] +')</font></i></center>'; 
                }
            },      
            {  
                "targets": [8],
                "render": function ( data ) { 
                    return '<font size="1"><i><center>' + data + '</center></i></font>'; 
                }
            },      
            {  
                "targets": [10, 12],
                "render": function ( data ) { 
                    return '<font size="1"><i><center>' + data + '%</center></i></font>'; 
                }
            },      
            {  
                "targets": [14],
                "render": function ( data ) { 
                    return '<center><a href="' + data + '" target="_blank"><font color="#fff400" size="1">go to market</font></a></center>'; 
                }
            },  
            { 
                "targets": [6, 7, 15],
                "render": function ( data, type, row ) { 
                    return '<center><font size="1">'+ data +'</font></center>'; 
                }
            },
            { 
                "targets": [16],
                "render": function ( data, type, row ) { 
                    return '<center><i><font size="1">'+ data +'</font></i></center>';
                }
            },                     
            { "visible": false,  "targets": [ 3, 5 ] }
        ]   
    } );
 });
 </script>
 </body>
 </html>

Here is the code. Follows console result.

console reuslt

SOLUTION v. 1.0

And here we go. As usual solution is quite easier if correctly interpreted.

What was wrong in my idea is that I was trying to limit jmhighlight using the DATA (alias the data array) that would have fulfilled table column, but what I needed to do was to limit highlight function only to a particular column identified with a particular id.

So the easiest way was this: Datatables let you define how any single column of your table will be

       "columnDefs": [
            {  
                "targets": [0],
                "render": function ( data ) { 
                    return '<center><div id="country"><b><font size="1">' + data + '</font></b></div></center>'; 
                }
            },

so the easiest way to limit highlight function was to tell the function to highlight words in id.TABLE, part.of.TABLE and id.COLUMN. Adding a div id to each column with different names, I was able to determine function container easily like this:

$("#example tbody #country").jmRemoveHighlight();
$("#example tbody #country").jmHighlight(keyword);

That's it. Probably it was exactly what rafaelcastrocouto was suggesting me, but I was unable to understand it.

Upvotes: 0

Views: 1695

Answers (1)

dude
dude

Reputation: 6086

Congratulations that you have solved the issue for yourself. However, just for others having the same issue: I just added an example in the documentation that shows you how to search and highlight column specific inside a DataTable-table.

Update: There's now a new plugin to handle search highlighting for DataTables: datatables.mark.js.

Upvotes: 1

Related Questions