l-lin / angular-datatables

DataTables with Angular
https://l-lin.github.io/angular-datatables/
MIT License
1.57k stars 487 forks source link

How can i make select row and selectall using with checkbox? #163

Closed scharf110 closed 9 years ago

scharf110 commented 9 years ago

Hi! I want to create selectall column using with checkbox. But i'm not handle selectrow data. How can i do?

$scope.dtOptions = DTOptionsBuilder.newOptions()
                   .withOption("ajax", {
                       url: "api/ListApiController/GetList",
                       type: "POST"
                   })
                   .withDataProp("data")
                });

$scope.dtColumns = [
                DTColumnBuilder.newColumn("Selected")
                    .withTitle("<input type='checkbox' class='group-checkable' data-set='.checkboxes' />")
                    .notSortable().withOption("searchable", false)
                    .renderWith(function (data) {
                        if (data) {
                            return "<input type='checkbox' checked='checked' class='checkboxes' name='Id' value='" + data + "'/>";
                        } else {
                            return "<input type='checkbox' class='checkboxes' name='Id' value='" + data + "'/>";
                        }
                    }).withClass("text-center"),
                DTColumnBuilder.newColumn("Column2").notSortable().withTitle("Column2"),
l-lin commented 9 years ago

I suppose you meant selecting rows not columns. Here an example on plnklr.

jmelosegui commented 9 years ago

is the sample still working ???

l-lin commented 9 years ago

Use this example instead.

jmelosegui commented 9 years ago

Hi @l-lin,

I don't know if the following is an issue or is the behavior by design.

In your online sample I filter rows with a cell value starting by 8, then I check the checkbox on the header expecting only the rows matching the filter criteria will be checked but in your controller all properties are checked.

See the following image for more info

selectfilteredrows

value 590 should be false, right???

l-lin commented 9 years ago

Nope, indeed, this example is not complete :disappointed: There are still some tweaks to make it work.

l-lin commented 9 years ago

Mmmh...in fact, it all depends on the functionality you seek. In my opinion, when checking the checkbox in the header, I think it should select all rows. Otherwise, I think it will make no sense to not select the rows on page 2, 3 and so on.

If you really need to only check what you filter, you will need to use the search event and search the selectedItems. However, I think it will be so much hassle as you will need to take into account the fact that user could have check other checkboxes or the fact that the user has already checked the checkbox in the header. I think it's not worth it.

bluee commented 9 years ago

It's quite a useful feature only to be able to select all visible rows. I thought I wanted to share how I currently do it. Although it's not a complete code it will hopefully be useful to someone struggling with this.

$scope.toggleAll = function () {
    $scope.selectAll = !$scope.selectAll; 
    $scope.cbox.items = {}; //cbox.items contains all checked checkboxes

    if ($scope.selectAll) {         //If true then select visible
        var oTable = $scope.dtInstance.dataTable;
        var anNodes = $("#dt tbody tr");

        for (var i = 0; i < anNodes.length; ++i) {
            var rowData = oTable.fnGetData(anNodes[i]);
            $scope.cbox.items[rowData.Guid] = true;
        }
    }
}
bluee commented 9 years ago

I also noticed that headerCallback didn't work for me. I learned that it had to be called exactly two times for it to work. If to call $compile only once then ng-click would not work in the header, if call $compile more than twice then ng-click would be called x-number of times.

.withOption('headerCallback', function (header) {

    if (!$scope.dtOpts.counter)
        $scope.dtOpts.counter = 1;
    else
        $scope.dtOpts.counter = $scope.dtOpts.counter + 1;

    if ($scope.dtOpts.counter <= 2)
        $compile(angular.element(header).contents())($scope);
})
anishkvirani commented 8 years ago

Hi Guys,

I have used @bluee's code above to change the toggle all function to make sure only the visible rows are selected when we check the selectAll checkbox. My function is as follows:

function toggleAll (selectAll, selectedItems) {
    //logic to get all visible rows in an array
    var visibleRows = new Array();            
    var oTable = vm.dtInstance.dataTable;
    var anNodes = $("#DataTables_Table_0 tbody tr");
    for (var i = 0; i < anNodes.length; ++i) 
    {
        var rowData = oTable.fnGetData(anNodes[i]);            
        visibleRows.push(rowData.in_user_id);            
    }
    //go through all the selectedItems objects
    for (var id in selectedItems) {
        if (selectedItems.hasOwnProperty(id)) 
        {             
            if(visibleRows.indexOf(parseInt(id)) != -1)
            {
                selectedItems[id] = selectAll;
            }
            else
            {                   
                delete selectedItems[id];
            }
        }
    }        
}

Thanks @bluee for your contribution, I was struggling a lot with this issue and finally found your post and modified it for my use.

eliseguimaraes commented 8 years ago

@bluee and @anishkvirani than you so much for this piece of code. I've been struggling with this for ages. But besides selecting only visible data, I would like to ignore pagination when selecting (i.e., selecting all the filtered data, visible or not). Does anyone know if that is possible? I considered filtering data on my own, on a custom input field, but datatables gives me the "cannot reinitialise datatable" error.

Update

Thanks to this I just found this

So, in bootstrap datatables, all it needs to be done is simply:

var table = $('#myTable').DataTable();
table.rows({page:'all', search: 'applied'} ).data();

That would solve all my problems. But I don't see how this can be done in angular-datatables.

eliseguimaraes commented 8 years ago

OK, I managed to do it.

The selector-modifier can be used in angular-datatables the following way:

var oTable = vm.dtInstance.dataTable;
var filteredRows = oTable._('tr', {"filter": "applied", "page": "all"});

In my case specifically, I wanted to compare the value of the first collumn (the user ID) with my scope user variable's ID, and then select it, so this is the piece of code:

var oTable = vm.dtInstance.dataTable;
var filteredRows = oTable._('tr', {"filter": "applied", "page": "all"});
for (var i = 0; i < filteredRows.length; ++i) {
    angular.forEach(vm.users, function (user, key) {
        if (user.id === parseInt(filteredRows[i][0], 10)) { 
            user.select = vm.selectAll;
        }
    });
}

I don't know whether this is the best way to do it (probably not), but it worked for me and it might help someone in the same situation.

srkdk commented 8 years ago

Hello, can we achieve this "select row" in angular way

eliseguimaraes commented 8 years ago

Hi, @srkdk, my way was implemented on angular! It works.

atulgirishkumar commented 7 years ago

Hi, @eliseguimaraes i want to select all checkboxes across all pages in angular datatable, any suggestions on how i can do it. I tried your above code but it is throwing error. Thank you.

saeedjassani commented 6 years ago

@l-lin, is there any Angular 4 example of this?

l-lin commented 6 years ago

Not yet.