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

treeview and checkboxes: a Solution

1 Answer 543 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Greg
Top achievements
Rank 1
Greg asked on 20 Nov 2012, 05:30 AM
Folks
I have been working thru some issues converting from telerik treeview with checkboxes to KendoUI treeview with check boxes.
Firstly, you need to be on the latest version of KendoUI. For Trial customers that is , 2012.2.913.340 or later. For paying customers you will need 2012.3.1114 of later.
Secondly, I am being guided by a Telerik expert, John, and he has point me to this site :
 http://demos.kendoui.com/web/treeview/remote-data.html
Now you will need to decide what is the best way to populate the treeview. That link gives you some different ways.
I am using the "Binding to remote data" option. So my html looks like this
@(Html.Kendo().TreeView()
    .Name("CategoryTreeView")
    .Events(e=>e.DataBound("onDataBound"))
    .Checkboxes(true)
    .DataTextField("Name")
    .DataSource(dataSource => dataSource
              .Read(read => read
            .Action("CategoryLoadNodes","Category")
                     )
                            )
              )
and my Controller method looks like this
public JsonResult CategoryLoadNodes(int? id)
        {
            IList<Category> categoryList = null;
            if (id.HasValue)
            {
                categoryList = CachedCategoryOnDemand().ChildCategoryList;
            }
            else
            {
                categoryList = CachedCategoryOnDemand().ParentCategoryList;
            }
 
            var nodes = from item in categoryList.Where(s=> id.HasValue ? s.ParentCategoryID == id : s.ParentCategoryID == null)
                                select new
                                {
                                    id = item.CategoryID,
                                    Name = item.CategoryDetails.FirstOrDefault().Name,
                                    hasChildren =  item.CategoryChild.Any()
                                };
            return Json(nodes, JsonRequestBehavior.AllowGet);
        }
You will need to populate your own list. Mine is quite big(6000+ categories) and comes from a self-joined table that is at least 10 levels deep.
Therefore I wish to populate the Parent when drawing the treeview and only those child nodes when I expand the parent node. It does one level at a time.
The lines between nodes didn't just appear and there is no treeview methods to turn them on. You need to use CSS for that. Here is what I am using
<style>
 
    .k-group .k-top,
    .k-group .k-mid,
    .k-group .k-bot
    {
    }
     
    .k-group .k-item { background-image: url('http://aspnet-skins.telerikstatic.com/mvc/2012.2.607/Default/treeview-line.png'); }
    .k-group .k-last { background-image: none; }
     
     
    .k-group .k-top,
    .k-group .k-mid,
    .k-group .k-bot
    {
        background-repeat: no-repeat;
        margin-left: -16px;
        padding-left: 16px;
    }
     
    .k-group .k-top { background-position: -91px 0; }
    .k-group .k-bot { background-position: -69px -22px; }
    .k-group .k-mid { background-position: -47px -44px; }
    .k-group .k-last .k-top { background-position: -25px -66px; }
    .k-group .k-group .k-last .k-bot { background-position: -69px -22px; }
     
    .k-group .k-item
    {
        background-repeat: no-repeat;
    }
     
    .k-group .k-first
    {
        background-repeat: no-repeat;
        background-position: 0 16px;
    }
 
  </style>

The other aspect is the checkbox. It is easy to display the check box, just add the CheckBoxs(true) and they will appear.
But there is no event handler for the checkbox click event. The Select event won't work, it is fired when the list item of the treeview is selected, not when the checkbox is checked.
To overcome this I use the DataBound event handler, which fires after the call to the controller method that populates the nodes.
You create a javascript function and use its name in the DataBound event handler.
In that function you bind the click event to each of the checkboxes. I have used jQuery's .on() function
Here is an example:
<script type="text/javascript">
    function onDataBound() {
        $("input:checkbox[name=checkedNodes]").on('click', function () {
            var catDesc = '';
            var catId = 0;
            if ($(this).is(':checked')) {
                catId = $(this).attr('value');
                $(this).parent().siblings().each(function () {
                    var text = $(this).text();
                    if (text && text != undefined) {
                        catDesc = text.replace(/&/g, '&');
                        return false;
                    }
                });
                //uncheck all checked checkboxes
                $("input:checked[name=checkedNodes]").each(function () {
                    $(this).attr('checked', false);
                });
                //recheck this
                $(this).attr('checked', true);
            }
            $('#CategoryID').val(catId);
            $('#CategoryName').val(catDesc);
        });
    }  
</script>
The value can be got from the checkbox element, but the name in the list is in a span that is a sibling of the parent of the checkbox element.
I am also only allowing one checkbox to be checked at a time, but is just a customised condition. You can do what you want.
I hope that this helps.
BTW, this is geared for client side operation and the only Web server side activity is the populating of treeview nodes .

Regards

Greg


1 Answer, 1 is accepted

Sort by
0
Greg
Top achievements
Rank 1
answered on 21 Nov 2012, 05:30 AM
Folks

there is another post that shows another solution that loads all items and allows MORE than 1 treeview on a HTML form and separates out the different check boxes lists when you post back the form.

http://www.kendoui.com/forums/mvc/treeview/treeview-with-checkboxes-2-or-more-treeviews-another-solution.aspx

Greg
Tags
TreeView
Asked by
Greg
Top achievements
Rank 1
Answers by
Greg
Top achievements
Rank 1
Share this question
or