I have Add Child/Update/Delete functionality in the columns of my TreeList. However, I don't want to display Update or Delete on my root node. I expected to do this using the Hidden attribute but my attempt doesn't work. How do I accomplish this?
My failed attempt:
@(Html.Kendo().TreeList<
GsiPortal.Models.Group
>()
.Name("treelist")
.Columns(columns =>
{
columns.Add().Field(e => e.Name).Width(220).TemplateId("icon-template");
columns.Add().Field(e => e.Description);
columns.Add().Field(e => e.CurrentStatus.Name).Title(nameof(Group.Status));
columns.Add().Field(e => e.AddTimestamp).Width(220).Title("Timestamp").Format("{0:MMMM d, yyyy}");
columns.Add().Command(c => { c.CreateChild().Text("Add"); }).HtmlAttributes(new { style = "text-align: center;" });
columns.Add().Command(c => { c.Edit(); }).HtmlAttributes(new { style = "text-align: center;" }).Hidden(x => x.CustomerInfo != null);
columns.Add().Command(c => { c.Destroy(); }).HtmlAttributes(new { style = "text-align: center;" }).Hidden(x => x.CustomerInfo != null);
})
.Editable(e => e.Mode(TreeListEditMode.PopUp).TemplateName("GroupEdit"))
.Selectable(selectable => selectable.Mode(TreeListSelectionMode.Single))
.DataSource(dataSource => dataSource
.ServerOperation(false)
.Create(create => create.Action("CreateJson", "Groups"))
.Read(read => read.Action("AllJson", "Groups").Data("groupsRead"))
.Update(update => update.Action("UpdateJson", "Groups"))
.Destroy(delete => delete.Action("DestroyJson", "Groups"))
.Model(m =>
{
m.Id(f => f.Id);
m.ParentId(f => f.ParentId);
m.Expanded(true);
m.Field(f => f.Name);
m.Field(f => f.Description);
m.Field(f => f.AddTimestamp).Editable(false);
})
.Events(events =>
{
events.Error("onError");
})
))
6 Answers, 1 is accepted
You can achieve this requirement by setting a className to this button using the HtmlAttributes (@class):
https://docs.telerik.com/kendo-ui/api/javascript/ui/treelist/configuration/columns.command#columnscommandclassname
And the use the dataBound event handler to hide the buttons via script, similar to this implementation:
https://dojo.telerik.com/efawEcil/17
I hope this will prove helpful.
Regards,
Eyup
Progress Telerik

I'm just getting back to this. As you can see from my example, I use the HtmlHelper. Do you have an example using this approach? I'm looking for the DataBound event and it is not available to me
When I attempt I get this error message:
SeverityCodeDescriptionProjectPathFileLineSuppression State
ErrorCS1061'DataSourceEventBuilder' does not contain a definition for 'DataBound' and no accessible extension method 'DataBound' accepting a first argument of type 'DataSourceEventBuilder' could be found (are you missing a using directive or an assembly reference?)GsiPortalC:\GSI\Gsi.Amtas.Cloud\GsiPortal\Views\GroupsC:\GSI\Gsi.Amtas.Cloud\GsiPortal\Views\Groups\_Hierarchy.cshtml43Active
My Attempt with Errors:
<
script
id
=
"icon-template"
type
=
"text/x-kendo-template"
>
<
div
class
=
'group-icon'
style
=
'background-image: url(@Url.Content("#: ImageUrl #"));'
></
div
>
<
div
class
=
'group-name'
>#: Name #</
div
>
</
script
>
@(Html.Kendo().TreeList<
GsiPortal.Models.Group
>()
.Name("treelist")
.Columns(columns =>
{
columns.Add().Field(e => e.Name).TemplateId("icon-template");
columns.Add().Field(e => e.Description);
columns.Add().Field(p => p.PersonCount);
columns.Add().Command(c => { c.Custom().Text("Details").Name("detailButton").Click("toDetails"); }).Width(120);
columns.Add().Command(c => { c.Custom().Text("Create").Name("createButton").Click("toCreate"); }).Hidden(@Model.IsHideCreate).Width(120);
})
.DataSource(dataSource => dataSource
.ServerOperation(false)
.Read(read => read.Action("IndexJson", "Groups")
.Data("getData"))
.Model(m =>
{
m.Id(f => f.Id);
m.ParentId(f => f.ParentId);
m.Expanded(true);
m.Field(f => f.Name);
}
)
.Events(events =>
{
events.Error("onError");
events.DataBound("dataBound");
})
)
)
<
script
>
var customerInfoId = Number(@Model.GetValue(Glossary.Keys.CustomerInfo.Id));
var groupId = Number(@Model.GetValue(Glossary.Keys.Group.Id));
function getData() {
return {
customerInfoId: customerInfoId,
groupId: groupId
};
}
function dataBound(e) {
e.preventDefault();
alert("databound");
}
function toDetails(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if (dataItem != null) {
window.location.href = '@Url.Action("Details", "Groups")/' + dataItem.Id;
}
}
function toCreate(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if (dataItem != null) {
window.location.href = '@Url.Action("Create", "Groups")/?parentId=' + dataItem.Id;
}
}
function onError(e) {
alert(e.toString());
}
</
script
>
<
style
>
.group-icon {
display: inline-block;
width: 40px;
height: 40px;
border-radius: 50%;
background-size: 40px 44px;
background-position: center center;
vertical-align: middle;
line-height: 41px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
}
.group-name {
display: inline-block;
vertical-align: middle;
line-height: 41px;
padding-left: 10px;
}
</
style
>
You can resolve this issue by transferring the dataBound event signature from the DataSource to the TreeList definition:
.Events(e => e.DataBound(
"treeListBound"
).
For the column definition you can add the className property:
columns.Add().Command(c =>
{
c.Custom().Text(
"Create"
).Name(
"createButton"
).Click(
"toCreate"
).ClassName(
"createButton"
);
}).Width(120);
And then execute your logic using this class name:
function
treeListBound(e) {
var
treeList = e.sender;
var
items = treeList.items();
for
(i = 0; i < items.length; i++) {
var
dataItem = treeList.dataItem(items[i]);
if
(!dataItem.Name.includes(
"3"
)) {
$(items[i]).find(
".createButton"
).hide();
}
}
}
That should do the trick.
Regards,
Eyup
Progress Telerik

I am attempting to implement your suggestion. However, the DataBound event does not exist:
.Events(e => e.DataBound("treeListBound").
My events list the following:
- Change
- Equal
- Error
- Push
- Request
- End
- Sync

I got this working. My .Events were attached to the .DataSource item and not the Tree. Here is my working example:
@{ Layout = null; }
@*Syntax Help here: https://docs.telerik.com/kendo-ui/framework/templates/overview*@
<
script
id
=
"icon-template"
type
=
"text/x-kendo-template"
>
<
div
class
=
'group-icon'
style
=
'background-image: url(@Url.Content("#: ImageUrl #"));'
></
div
>
<
div
class
=
'group-name'
>#: Name #</
div
>
</
script
>
@(Html.Kendo().TreeList<
GsiPortal.Models.Group
>()
.Name("treelist")
.Columns(columns =>
{
columns.Add().Field(e => e.Name).TemplateId("icon-template");
columns.Add().Field(e => e.Description);
columns.Add().Field(p => p.PersonCount);
columns.Add().Command(c => { c.Custom().Text("Details").Name("detailButton").Click("toDetails"); }).Width(120);
columns.Add().Command(c => { c.Custom().Text("Create").Name("createButton").Click("toCreate").ClassName("createButton"); }).Width(120);
})
.DataSource(dataSource => dataSource
.ServerOperation(false)
.Read(read => read.Action("IndexJson", "Groups").Data("getData"))
.Model(m =>
{
m.Id(f => f.Id);
m.ParentId(f => f.ParentId);
m.Expanded(true);
m.Field(f => f.Name);
})
.Events(events => events.Error("onError"))
).Events(evt => evt.DataBound("treeListBound"))
)
<
script
>
function treeListBound(e) {
var treeList = e.sender;
var items = treeList.items();
for (i = 0; i <
items.length
; i++) {
var
dataItem
=
treeList
.dataItem(items[i]);
if (dataItem.IsHideCreate) {
$(items[i]).find(".createButton").hide();
}
}
}
</script>
<
style
>
.group-icon {
display: inline-block;
width: 40px;
height: 40px;
border-radius: 50%;
background-size: 40px 44px;
background-position: center center;
vertical-align: middle;
line-height: 41px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
}
.group-name {
display: inline-block;
vertical-align: middle;
line-height: 41px;
padding-left: 10px;
}
</
style
>
