DataTables Column Filter

DataTable is a jQuery plugin with advanced interaction controls to any HTML table. It is a highly flexible tool which provides pagination, multi-column ordering and instant search.

The DataTable search filter works for an entire table. But if you wish to add search filter for a particular column, then it’s also possible with a small tweak. Let’s take a look on adding column filter.

Add Column Filter in DataTables

HTML:

<form action="{{{action('Controller@selectedCourses')}}}" method="POST">    
    <table id="courses">
        <thead>
            <tr>
                <th>Course Code</th>
                <th>Course Name</th>
                <th>Duration</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody>
            @foreach($courses as $key => $value)
                <tr>
                    <td>
                        <label>
                            <input type="checkbox"
                            name="selected_courses[]"
                            value="{{$value['course_id']}}">
                        </label>
                        {{$value['course_code']}}
                    </td>
                    <td>{{$value['course_name']}}</td>
                    <td>{{$value['duration']}}</td>
                    <td>{{$value['status']}}</td>
                </tr>
            @endforeach
        </tbody>
        <tfoot>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </tfoot>
    </table>
    <input type="hidden" id ="total_selected_courses" name="total_selected_courses">
    <button type="button" class="submit_button">
        Submit
    </button>
</form>

Laravel blade template is used here.

The js code to implement column filter in DataTables:

$(document).ready(function(){
    
	// Add DataTable for courses
    var courses = $('table#courses').DataTable({
        "bJQueryUI": false,
        "sPaginationType": "bootstrap",
        "bProcessing": true,
        "bServerSide": false,
        "bPaginate": true
    });
    
	// Add textbox in footer with header text in placeholder
    $('table#courses tfoot th').each( function () {
		var title = $('table#courses thead th').eq($(this).index()).text();
		$(this).html('<input type="text" placeholder="'+title+'" />');
	});
	
    // Column Filter Search
	courses.columns().eq(0).each(function(colIdx) {
	    $('input', courses.column(colIdx).footer()).on('keyup', function () {
		courses
		    .column(colIdx)
		    .search(this.value)
		    .draw();
	    });
	});

	// If no checkbox is checked then alert message else submit
	$('.submit_button').click(function(){
		var checked_courses = courses.$('input[name="selected_courses[]"]:checked').length;
		
		if (checked_courses != 0) {
			$('form').submit();
		} else {
			alert("Select atleast one course");
		}
	});
});

Now we retrieve the data for checkboxes checked in Controller.

// Retrieve data for checkboxes checked
public function selectedCourses() {
    $courses = Input::get('selected_courses');
}

Suppose user checks 3 checkboxes and click “Submit” button.

datatable

This works fine and the values for 3 checkboxes are retrieved.

The issue comes when user use column filter after checkbox is checked. Suppose user search for a course using “Course Code” column filter.

columnFilter

The searched course will be displayed to the user and other checked courses will be hidden. Now if user submits the form, the hidden checked values will not be posted.

Get hidden checkbox values from DataTables

To fix this we can use jQuery serialize() method. We will get all the checked values in serialized string format, store this in a hidden field and retrieve the hidden field value in Controller.

To accomplish this we will change the code for button click event.

// Serialize the checked values
// If no checkbox is checked then alert message
// else store serialized string in hidden field and submit
$('.submit_button').click(function(){
    var checked_courses = courses.$('input[name="selected_courses[]"]:checked').serialize();
    
    if(checked_courses != "") {
        $('#total_selected_courses').val(checked_courses);
        $('form').submit();
    } else {
        alert("Select atleast one course");
    }
});

The Controller code will be changed to:

public function selectedCourses() {    
    $total_courses_string = Input::get('total_selected_courses');
    
    // jQuery serialized string to PHP array format
    parse_str($total_courses_string, $total_courses);
    
    // Get selected courses
    $courses = $total_courses['selected_courses'];    
}

Now we can get all the 3 checked values even if some of the checked courses are hidden.

Advertisements

4 thoughts on “DataTables Column Filter

  1. Pingback: DataTables Column Filter in Header | Sabih Ahmad Khan

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s