Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

i am trying to add a custom filter to angular-DataTables with server side processing, which works perfectly with sorting and built in search of datatables.

I was following example Angular-DataTables, to build the server side processing and setup the DataTable, in searching around i have found some info but haven't been able to make it work.

What i am trying to get is to redraw the table with filtered data once the checkbox [Player] has been triggered.

Does anyone know a solution for this or has a working example for this?

have found this example Custom Table Filter, but it seems it doesn't work either.

HTML:

<div ng-app="showcase"><div ng-controller="ServerSideProcessingCtrl">
<label><input type="checkbox" id="customFilter" value="player"> Player</label>
<table datatable="" dt-options="dtOptions" dt-columns="dtColumns" class="row-border hover"></table>

JS part:

 'use strict';

    angular.module('showcase', ['datatables'])
            //.controller('ServerSideProcessingCtrl', ServerSideProcessingCtrl);
    .controller('ServerSideProcessingCtrl',["$scope", "DTOptionsBuilder", "DTColumnBuilder", function($scope, DTOptionsBuilder, DTColumnBuilder) {

    //function ServerSideProcessingCtrl(DTOptionsBuilder, DTColumnBuilder) {
        console.log($scope);
        $scope.dtOptions = DTOptionsBuilder.newOptions()
                .withOption('ajax', {
                    // Either you specify the AjaxDataProp here
                    // dataSrc: 'data',
                    url: 'getTableData.php',
                    type: 'POST'
                })
            // or here
                .withDataProp('data')
                .withOption('serverSide', true)
                .withPaginationType('full_numbers');
        $scope.dtColumns = [
            DTColumnBuilder.newColumn('id').withTitle('ID'),
            DTColumnBuilder.newColumn('name').withTitle('First name'),
            DTColumnBuilder.newColumn('position').withTitle('Position'),
            DTColumnBuilder.newColumn('type').withTitle('Type')
        ];

        $scope.$on('event:dataTableLoaded', function(event, loadedDT) {
            console.log(event);
            console.log(loadedDT);
            $('#customFilter').on('change', function() {
                loadedDT.DataTable.draw();
            } );


        });

    }]);

JSON on load:

{"draw":"1","recordsTotal":8,"recordsFiltered":8,"data":[{"id":"1","name":"Raul","position":"front","type":"player"},{"id":"2","name":"Crespo","position":"front","type":"player"},{"id":"3","name":"Nesta","position":"back","type":"player"},{"id":"4","name":"Costacurta","position":"back","type":"player"},{"id":"5","name":"Doc Brown","position":"staff","type":"medic"},{"id":"6","name":"Jose","position":"staff","type":"manager"},{"id":"7","name":"Ferguson","position":"staff","type":"manager"},{"id":"8","name":"Zinedine","position":"staff","type":"director"}]}
share|improve this question
    
I followed your code. But always its shows all records. No pagination for me. How did you fixed that? – blacmoon Mar 16 at 6:57
up vote 0 down vote accepted

After searching and browsing, combined few examples and came up with this.

HTML :

 <label><input type="checkbox" id="customFilter" value="player" ng-click="reload()" > Player</label>

JS:

 'use strict';

    angular.module('showcase', ['datatables'])
            //.controller('ServerSideProcessingCtrl', ServerSideProcessingCtrl);
    .controller('ServerSideProcessingCtrl',["$scope", "DTOptionsBuilder", "DTColumnBuilder","DTInstances",  function ($scope, DTOptionsBuilder, DTColumnBuilder, DTInstances) {

    //function ServerSideProcessingCtrl(DTOptionsBuilder, DTColumnBuilder) {
        console.log($scope);

        $scope.dtOptions = DTOptionsBuilder.newOptions()
                .withOption('ajax', {
                    // Either you specify the AjaxDataProp here
                    // dataSrc: 'data',
                    url: 'getTableData.php',
                    type: 'POST',
                    // CUSTOM FILTERS
                    data: function (data) {
                        data.customFilter = $('#customFilter').is(':checked');
                    }
                })
            // or here
                .withDataProp('data')
                .withOption('serverSide', true)
                .withPaginationType('full_numbers');
        $scope.dtColumns = [
            DTColumnBuilder.newColumn('id').withTitle('ID'),
            DTColumnBuilder.newColumn('name').withTitle('First name'),
            DTColumnBuilder.newColumn('position').withTitle('Position'),
            DTColumnBuilder.newColumn('type').withTitle('Type')
        ];

        DTInstances.getLast().then(function (dtInstance) {
            $scope.dtInstance = dtInstance;
        });

        $scope.reload = function(event, loadedDT) {
            $scope.dtInstance.reloadData();
        };

    }]);

and on the backend just go through the $_POST and check for custom filter, hopefully this will help someone

share|improve this answer
    
hey I am trying to use this plugin but getting errors DO you have any sample live page where I can find where I am missing – Pankaj Badukale Sep 11 '15 at 7:30

You can use withFnServerData with fromSource functions instead of withOption:

This API allows you to override the default function to retrieve the data (which is $.getJSON according to DataTables documentation) to something more suitable for you application.

It's mainly used for Datatables v1.9.4. See DataTable documentation.

$scope.dtOptions = DTOptionsBuilder.fromSource('data.json')
    .withFnServerData(serverData);

function serverData (sSource, aoData, fnCallback, oSettings) {
    oSettings.jqXHR = $.ajax({
        'dataType': 'json',
        'type': 'POST',
        'url': sSource,
        'data': aoData,
        'success': fnCallback
    });

:)

share|improve this answer

Ok sorry its not a full blown example. This only works with angular and datatables, if you do a filter on the ng-repeat eg | aFilter:this The this transfers the scope. The filtering applied can now be quite complex. Within the ng-controller <div> you can have an html partial containing drop downs or input texts, all having an ng-model value.

When these change they kick off the filter routineaFilter an angular.filter('aFilter'.... js routine. The records are piped through the afilter routine allowing the ones wanted to be pushed onto an array and this is what is returned with the return. It doesn't work with breeze, yet. Be aware it is unlikely to be server side. To deal with server side maybe an SQL call in the service....another day.

eg in the ng-table id="test" :

<tr ng-repeat="edRec in aSetOfJSonRecords | aFilter:this | orderBy:'summat'">
{{edRec.enCode}} etc
</tr>

in the aFilter, the fltEnCode represents the ng-model values, the test variable allows freedom from nulls causing issues upon comparison, good idea to test for undefined first:

   app.filter('aFilter', [function () {
        return function (items, $scope) {

            var countItems = 0;
            var filtered = [];
            var isOK = 0;

            angular.forEach(items, function (item) {
                isOK = 1;
                // some conditions
                if ($scope.fltEnCode !== "") {
                    if (item.enCode === null) { test = ""; } else { test = item.enCode; }
                if (test.indexOf($scope.fltEnCode) < 0) isOK = 0;
                }
                // end of conditions
                if (isOK > 0) {
                    filtered.push(item);
                    countItems++;
                }
            });
           // alert(countItems);
            return filtered;
        };
    }]);

Hope its of some use. I've avoided boolean variables as they have given grief before. Odd occasions have needed an ng-change in the html items pointing to an angular function resetting the data by calling the getTheItemsForTest() in the controller. This redraws the list. Having

$scope.dtOptions = {
     stateSave: false, .......

in your controller, keeps the sorting columns correct.

$(document).ready(function() {
    var table = $('#test').DataTable();
    table.draw();
};

might also be useful if its recalcitrant. I need to know how to make it work for breeze??? Enjoy..

share|improve this answer

here is what I really missed after I searched alot

bower install datatables-light-columnfilter

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.