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>