2

I have a Bootstrap DataTable with 3 columns:

  • In column "Id" each cell has a plain <label .../> html element with string content
  • In column "Name" each cell contains an <input .../> html element with respective values
  • In column "Job" each cell contains a <select options .../>html element with respective values

Using the default Filter object, I can filter the entire DataTable using the "Id" labels. However, I cannot filter the DataTable using values from the <select options .../> or from the <input .../> of each cell from the "Name" and "Job" columns.

This is a piece of the datatable.

enter image description here

Do you have any suggestions or jquery code samples I could follow? Thank you.

I am not using serverSide option in the implementation.

Here is the datatable:

$('#tbl').DataTable({
    "iDisplayLength": 50,
    "order": [[ 0, "asc" ]],
    "columnDefs": [{
        "sortable": false,
        "searchable" : true,
        "render" : function(data, type, full) { return data;},
        "targets": [1, 2]
    }]
   });
1
  • Hi! You mean, if You write some text into the Filter field, you want to find the text among the options of the select field, or in the value of the input field? Is that what you want? Also, could you add your datatable code? Commented Dec 8, 2016 at 14:51

2 Answers 2

3

Unfortunatley, according to this link it can't be done with the default Filter (see the last post). You have to define your own filter.

Here is an example for that: https://jsfiddle.net/Igorovics/m5vy656x/19/ . It only contains filtering for input fields, but can be extended to select fields easily.

  1. You have to put a new input field to the screen, in the example this is the 'Custom filter', with the id of filterField. I didn't do any css on that, but that can be placed into your table, if you want to.

  2. You can bind a keyup event to the new filter, which is redrawing your table.

  3. To write your own filtering function, you have to extend the $.fn.dataTable.ext.search function of Datatable. Some informaton can be found here, and an official example can be found here. Unfortunately the official example misses the data you really need. The function has 5 parameters and you need the fourth parameter (the original data source for the row). In my example I call it original. This fourth parameter is a JavaScript array, where the original HTML code of the given columns of the given rows can be found. In my example I read the 5th element of the array into the valueToFilter variable, it is because the 5th element of the given row in the example is always the column, which contains the input field. I also read the value of filterField field to a variable, called filterValue.

  4. Last step is to check whether the field contains the filter value, or not. If yes, we return true, so the row will be seen in the table, otherwise we return false.

  5. As you can see, I left the original filter on the screen. They can be used together, but it's good to know that the original filter always works first. So if you write something into the original, and that filters the rows, your custom filter will only receive the rest of the rows. If you don't need the original filter anymore, you can remove it with the dom option.

Sorry for the long explanation, I hope I was clear.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi! Excellent answer. Thanks!!! One comment from my side. Instead of using the dom option, I have replaced the default Filter element with my custom one, using the DOM replaceChild() method. It was like a charm.
You are welcome :) Yes, maybe the DOM replaceChild() is better, sometimes the dom option worked strange for me.
1

I updated Igorovics' excellent jsfiddle with two additions:

  • I connected the search filter to all columns (if anyone was interested in that) like this:

    $.fn.dataTable.ext.search.push(
        function( settings, data, dataIndex,original,counter ) {
            var filterValue = $('#filterField').val();
          var valueToFilter0 = original[0];
          var valueToFilter1 = original[1];
          var valueToFilter2 = original[2];
          var valueToFilter3 = original[3];
          var valueToFilter4 = original[4];
          var valueToFilter5 = original[5];
          var valueToFilter6 = original[6];
          if(valueToFilter0.indexOf(filterValue) != -1 || valueToFilter1.indexOf(filterValue) != -1 || valueToFilter2.indexOf(filterValue) != -1 || valueToFilter3.indexOf(filterValue) != -1 || valueToFilter4.indexOf(filterValue) != -1 || valueToFilter5.indexOf(filterValue) != -1 || valueToFilter6.indexOf('value="' + filterValue) != -1){
            return true;
          }
          return false;
        }
    );
    
  • As you might notice if you scroll to the right I also added a sixth column with selects (which was asked for in the original question). It is now filterable from the search box through an ugly hack, but it works. I put the selected option's value in the select tag and then set the filter condition to valueToFilter6.indexOf('value="' + filterValue) != -1in order to avoid the not selected options. You probably want to change the select element's value each time you change selected option while using this method, it is not implemented in the fiddle.

Further improvement would be to apply this to the sorting functions too and to override the default search input with our new one (an example of using goseib's replaceChild() method?).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.