This is a migrated thread and some comments may be shown as answers.

Check multiple checkboxes at once

23 Answers 631 Views
ToolTip
This is a migrated thread and some comments may be shown as answers.
Chris
Top achievements
Rank 1
Chris asked on 09 Jul 2013, 09:16 AM
Hi,

Is there a way to check multiple checkboxes at once through the TreeView API? I have a TreeView with a large number of nodes (up to ~10,000) and a requirement to be able to save/reload checkbox selections. At the moment to reload them I'm clicking each of the required checkboxes via javascript, but that fires off the events to re-evaluate the checked/indeterminate/unchecked states of all parent nodes for each checkbox, which is extremely time-consuming.

Ideally I'd like to be able to pass the TreeView a list of checkboxes to check and have them all done in one go, but any pointers on how to make this more efficient would be gratefully received.

Many thanks,
Chris

23 Answers, 1 is accepted

Sort by
0
Alex Gyoshev
Telerik team
answered on 11 Jul 2013, 08:19 AM
Hello Chris,

If you set the checkbox checked property directly, this will not kick off the indeterminate check. Afterwards you can kick off an update of the indeterminate field. At this time, this can be done through the _updateIndeterminateInitial "private" method, as seen in this jsBin. We have opened this method for public use and it will be available in the upcoming 2013.Q2 release next week -- so you will need to call treeview.updateIndeterminate() after upgrading.

Regards,
Alex Gyoshev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Chris
Top achievements
Rank 1
answered on 11 Jul 2013, 09:09 AM
Thanks Alex,

That's considerably faster than clicking all of the nodes!

Regards,
Chris
0
Accepted
Chris
Top achievements
Rank 1
answered on 26 Sep 2013, 01:04 PM
Hi Alex,

I've got a minor issue with this, please see the jsBin here.

If you
  • expand the top-level Node 0 and some nodes underneath that
  • click the 'Check all nodes' button
  • uncheck the top-level Node 0
  • click 'Check all nodes' 
  • uncheck the top-level Node 0
Then the nodes underneath Node 0 don't get checked.

Thanks,
Chris
0
Atanas Korchev
Telerik team
answered on 30 Sep 2013, 02:02 PM
Hello Chris,

 There is indeed a problem with that workaround. The treeview isn't notified that a node is unchecked internally. I would suggest a different approach - to check only the first level nodes and trigger their change events: http://jsbin.com/ITayEWe/5/edit

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Chris
Top achievements
Rank 1
answered on 30 Sep 2013, 02:23 PM
Hi Atanas,

Unfortunately my requirement is to check a predefined selection of leaf node checkboxes (unchecking all of the others) and then to update the indeterminate status of the checkboxes in the tree - checking all of the checkboxes is just the specific instance of this where the problem occurs.

Setting the checkboxes to checked and triggering the change event doesn't give the performance required when dealing with around 10,000 nodes.

Many thanks,
Chris
0
Atanas Korchev
Telerik team
answered on 30 Sep 2013, 02:30 PM
Hello Chris,

 Can you please update the last jsbin to demonstrate the actual problem you are having? Perhaps we can find the proper workaround.

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Accepted
Chris
Top achievements
Rank 1
answered on 30 Sep 2013, 02:41 PM
Hi Atanas,

The jsBin at http://jsbin.com/ITayEWe/8/edit demonstrates the problem.

as before, the steps to reproduce are:
  • expand the top-level Node 0 and some nodes underneath that
  • click the button
  • uncheck the top-level Node 0
  • click the button
  •  uncheck the top-level Node 0
Many thanks,
Chris
0
Atanas Korchev
Telerik team
answered on 30 Sep 2013, 03:06 PM
Hi Chris,

 I think I found a workaround: http://jsbin.com/ITayEWe/11/edit

  $("#tree").on("change", ":checkbox", function(e) {
      var node = $(e.currentTarget).closest(".k-item");
      var dataItem = tree.dataSource.getByUid(node.attr("data-uid"));
      
      dataItem.trigger("change", { field: "checked" });
   });


 The key is to listen to the checkbox check event and update the internal state of the node.

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Chris
Top achievements
Rank 1
answered on 18 Oct 2013, 03:21 PM
Hi Atanas,

Sorry for the delay in replying, took me a while to get round to testing this.

That fix works fine,

Thanks!
Chris
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 05:30 AM
Atanas, On Sep 30 13 you posted a link to jsbin for ITayEWe/11/edit.
then you have some code below the link.
I am trying to use the code you have listed $("#tree....
When I get to the var dataItem = tree.dataSource.getByUid it fails on runtime.
No matter how I try to format the string it comes back as  Cannot call method 'getByUid' of undefined.
The associated jsbin does not have this code in it.
Do you have an example where you actually use this code snip-it?
It is exactly what I need if I could only get it to work.
0
Atanas Korchev
Telerik team
answered on 26 Feb 2014, 07:36 AM
Hi David,

Here is the updated demo: http://jsbin.com/ITayEWe/51/edit

Also here is the code in case something happens to it:

<script>
    
   var tree = $("#tree").kendoTreeView({
     dataSource: {
       data: populate(2)
     },
     loadOnDemand: false,
     checkboxes: {
       checkChildren: true
     }
   }).data("kendoTreeView");
    
   $("#tree").on("change", ":checkbox", function(e) {
     var node = $(e.currentTarget).closest(".k-item");
     var dataItem = tree.dataSource.getByUid(node.attr("data-uid"));
      
     dataItem.trigger("change", { field: "checked" });
  });
 
    
   $("button").click(function(e) {
     var leafCheckboxes = $('.k-item > div:only-child input[type="checkbox"]');
      
     leafCheckboxes = leafCheckboxes.slice(0, leafCheckboxes.length - 1);
      
     leafCheckboxes.prop("checked", true);
      
     tree.updateIndeterminate(tree.wrapper);
   });
    
   // generate 10^(levels+1) items
   function populate(levels) {
     var data = [];
      
     for (var i = 0; i < 2; i++) {
       var node = { text: "Node " + i };
        
       if (levels > 0) {
         node.items = populate(levels - 1);
       }
        
       data.push(node);
     }
      
     return data;
   }
    
 </script>


Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 01:39 PM
Thanks for the reply.
How would this look using MVC and razor?
0
Atanas Korchev
Telerik team
answered on 26 Feb 2014, 01:46 PM
Hi David,

The JavaScript code should be exactly the same. Replace $("#tree") with the Name() of your treeview (don't forget the "#" in the beginning).

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 02:02 PM
That's what I thought.
The line that is holding me up is the line assigning to the dataItem
var dataItem = tree...
In the script you are assigning var tree = $("#tree")...
but tree is always null.
Here is my code

<script type="text/javascript">



function onChange(e) {
window.alert("In Change");

}

function onDataBound(arg) {
window.alert("List view loading "+ nodeType);
}

$("#nodeTypeTree").on("change", ":checkbox", function (e) {
var node = $(e.currentTarget).closest(".k-item");
var dataItem = nodeTypeTree.dataSource.getByUid(node.attr("data_uid"));
alert(node.attr("data_uid"));
dataItem.trigger("change", { field: "checked" });
});


$("showCheckedBtn").click(function (e) {
var checkedList = $(":checkbox");
checkedList.prop("checked", true);
nodeTypeTree.updateIndeterminate(nodeTypeTree.wrapper);
});



</script>
<script type="text/javascript">
function onTreeSelect(e) {
window.alert("In Tree Select " + this.text(e.node));
}


// function that gathers IDs of checked nodes
function checkedNodeIds(nodes, checkedNodes) {
window.alert("In Checked Node Ids");
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].checked) {
checkedNodes.push(nodes[i].id)
}
if (nodes[i].hasChildren) {
checkedNodeIds(nodes[i].children.view(), checkedNodes);
}
}
}

<div id="nodeTypeTree">
@* Kendo TreeView sample gotten from Kendo Samples razor/web/treeview/remote-data*@
@(Html.Kendo().TreeView()
.Name("nodeTypeTree")
.Checkboxes(_chk => _chk
.Name("ckeckedFields")
.CheckChildren(true)
.Template("<input type='checkbox' name='checkedNodes' #= item.isChecked ? 'checked' : '' # value='#= item.id #' />")
)
.DataSource(d => d.Read(r => r.Action("GetNodeTypeForClient","_ClientAttributeMgr")))
.DataTextField("Name")
.Events(events => events
.Select("onTreeSelect").Change("onChange").DataBound("onDataBound")
)

)
</div>
<button id="showCheckedBtn" name="showCheckedBtn">Check State</button>





0
Atanas Korchev
Telerik team
answered on 26 Feb 2014, 02:25 PM
Hello David,

This happens because the Name() of your treeview is not "tree" as in the original topic. Please replace $("#tree") with $("#your_treeview_name").

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 02:33 PM
Please look at the code I included again.
I did use the name of my tree view. I don't have a var called nodeTypeTree but isn't that where you are defining your TreeView? I have a div called nodeTypeTree.

 $("#nodeTypeTree").on("change", ":checkbox", function (e) {
var node = $(e.currentTarget).closest(".k-item");
var dataItem = nodeTypeTree.dataSource.getByUid(node.attr("data_uid"));
alert(node.attr("data_uid"));
dataItem.trigger("change", { field: "checked" });
});
0
Atanas Korchev
Telerik team
answered on 26 Feb 2014, 02:42 PM
Hi David,

The code is executed before the treeview is rendered and this is why $("#nodeTypeTree") returns null - the element doesn't exist yet. You need to put this code after the treeview is rendered:

@(Html.Kendo().TreeView())

<script>
$(function() {
$("#nodeTypeTree").on("change", ":checkbox", function (e) {
var node = $(e.currentTarget).closest(".k-item");
var nodeTypeTree = $("#nodeTypeTree").data("kendoTreeView");
var dataItem = nodeTypeTree.dataSource.getByUid(node.attr("data_uid"));
alert(node.attr("data_uid"));
dataItem.trigger("change", { field: "checked" });
});
});
</script>

You also need to initialize the nodeTypeTree variable before using it.

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 03:36 PM
We are making some progress.
I now see an object for the nodeTypeTree and for the node.
however nodeTypeTree.dataSource.getByUid(node.attr("data_uid")) is still undefined.
Maybe I am heading down the wrong rode here.
Ultimately I want to capture all the items that have been checked.
0
Atanas Korchev
Telerik team
answered on 26 Feb 2014, 03:53 PM
Hello David,

The original thread was for a problem caused by programmatically checking the nodes. Are experiencing the same issue?

You can review the checkboxes demo which shows how to get the checked nodes. You could check both the HTML and ASP.NET MVC versions to see the JavaScript and server-side solutions. 

If you need further assistance please start a new forum or support thread.

Regards,
Atanas Korchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
David
Top achievements
Rank 1
answered on 26 Feb 2014, 04:07 PM
I checked those before replying on this thread for I need to programmatically check the state of the nodes.
I will start a new thread non the less Stating my issue. There might be a different solution.
0
Colin
Top achievements
Rank 1
answered on 08 Jan 2015, 11:04 AM
Hi Alex

I need to do something similar, but while using a remote data source. This means that I do not necessarily have all the checked nodes loaded in the tree, but I do have the full path of all the checked nodes, i.e. the id of all the checked nodes ancestors.

How can I set a node to show as indeterminate if I know that one of its descendants will be checked when it is loaded?

Thanks

Colin
0
Alex Gyoshev
Telerik team
answered on 08 Jan 2015, 01:30 PM

Hello Colin,

Since the TreeView does not have a way of knowing this, you may need to manually update the checkbox state after the TreeView has been rendered. You can set the checkbox indeterminate property via jQuery, like this:

$(":checkbox").filter( /* filter out checkboxes that need to be indeterminate */ ).prop("indeterminate", true);

Regards,
Alex Gyoshev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Colin
Top achievements
Rank 1
answered on 09 Jan 2015, 12:32 AM
Hi Alex

Thanks for that it is exactly what I needed.

Colin
Tags
ToolTip
Asked by
Chris
Top achievements
Rank 1
Answers by
Alex Gyoshev
Telerik team
Chris
Top achievements
Rank 1
Atanas Korchev
Telerik team
David
Top achievements
Rank 1
Colin
Top achievements
Rank 1
Share this question
or