Telerik Forums
UI for ASP.NET Core Forum
0 answers
532 views

In our UI for ASP.NET Core R3 2020 (2020.3.915) release, the Column menu message of unsticking a column is "null".

This bug will be resolved in our next official release.

In the meantime, as a workaround, manually set the Unstick Column menu message:

.ColumnMenu(c => c.Messages(m => m.Unstick("Unstick Column")))
Kendo UI
Top achievements
Rank 1
 asked on 16 Sep 2020
2 answers
7 views

Hi all,

 

Going nuts over this problem. Should be simple, and for other technologies telerik shows solutions, but can not get it to work for razor pages .net core. 

 

What i want is:

I have a grid that opens in a popup when editting. In the editortemplate i have a childgrid showing all possible children that can be added to this record. That is working. However, i want to multiselect in this grid without having my customers to hold down  ctrl or use a textbox. Main reason: When using a textbox, you really have to click in the textbox, clicking outsisde of it won't work. So i removed the select column (the checkboxes) and just want people to click somewhere on a row to select it and be able to click on another row without the fiorst one loosing it's selected status. The only hook i can find is the onchange event. This indeed allows me to catch the slection process. However, the previously selected items are not available any more, so i oose them. 

Anyone an idea how to do this quite simple trick?

Alexander
Top achievements
Rank 1
Veteran
Iron
 answered on 28 Jun 2025
1 answer
9 views
I am trying to perform like this drag item from kendo Treelist to Drop in Kendo grid but not working in .net code using 
But when I doing drag from treelist to grid I am not event getitng debug 
Please help me asap if anyone has solution 

Razor page code:

<div style="height: 100%;">
    <!-- Parent Grid -->
    <div style="width: 60%; height: 100%; float: left;">
        <h2>{_ParentItem_}s</h2>
        @(Html.Kendo().TreeList<ParentChildModel>()
            .Name("ParentGrid")
            .Columns(columns =>
            {
                columns.Add().Field(p => p.Id).Width(80).Hidden(false);
                columns.Add().Field(p => p.ItemId).Width(80).Hidden(true);
                columns.Add().Field(c => c.Name).Title("Name").Width(140).Template("#= getIndentedName(Name, Id) #");
                columns.Add().Field(e => e.AssetCode).Title("{_AssetCode_}").Width(60);
                columns.Add().Field(e => e.Weight).Title("Weight").Format("{0:n3}").Width(40).Hidden(false);
                columns.Add().Field(e => e.Dimension).Title("Dimension").Width(100).Hidden(false);
                columns.Add().Command(c => 
                { 
                    c.Edit().Text("Edit").ClassName("k-grid-edit");
                    c.Destroy().Text("Delete").ClassName("k-grid-delete");
                }).Title("Actions").Width(80);
            })
            .Editable(editable => editable.Move(move => move.Reorderable(true)).Mode(TreeListEditMode.PopUp)
                .TemplateName("ParentPopupEditor"))
            .Toolbar(toolbar =>
            {
                toolbar.Create().Text("Add New {_ParentItem_}");
                toolbar.Custom().Template(
                    "<div>" +
                    "<input id='toolbarComboBox' style='width: 300px;' />" +
                    "</div>"
                );
                toolbar.Search();
            })
            .DataSource(dataSource => dataSource
                .Read(read => read.Action("GetParentAndChildItems", "ParentChild").Data("parentSearchData"))
                .Create(update => update.Action("AddNewRecord", "ParentChild").Type(HttpVerbs.Post))
                .Update(u => u.Action("UpdateRecord", "ParentChild").Type(HttpVerbs.Post))  //.Data("saveFormData"))
                .Destroy(update => update.Action("DeleteRecord", "ParentChild"))
                .ServerOperation(false)
                .PageSize(20)
                .Model(m =>
                {
                    m.Id(f => f.Id);
                    m.ParentId(f => f.ParentId);
                    m.Expanded(true);
                    m.Field(f => f.ItemId);
                    m.Field(f => f.AssetName);
                    m.Field(f => f.AssetCode);
                    m.Field(f => f.Weight);
                    m.Field(f => f.Dimension);
                })
            )
            .Pageable(x => x.PageSizes(new int[] { 20, 50, 100, 200, 500 }).Refresh(true).Input(true))
            .Sortable()
            .Selectable()
            .Events(e => e.DataBound("dataBound").Save("onEditorDataSave").DragEnd("onDragEnd"))//.DragStart("onDragStart").DragEnd("onDragEnd")
        )
    </div>

    <!-- Assignable Assets -->
    <div style="width: 40%; height: 100%; float: right;">
        <h2>Assignable {_Asset_}s</h2>
        @(Html.Kendo().Grid<ItemDto>()
            .Name("AssetGrid")
            .HtmlAttributes(new { style = "height:100%; width:100%;" })
            .Columns(columns =>
            {
                //columns.Template(@<text> </text>).Draggable(true).Width(30);
                columns.Template("").Draggable(true);
                columns.Bound(a => a.Id).Title("Id").Width(60).HtmlAttributes(new { @class = "idColStyle" });
                columns.Bound(a => a.Title).Title("{_AssetName_}").Width(150);
                columns.Bound(a => a.ItemTypeName).Title("{_AssetType_}").Width(100);
                columns.Bound(a => a.LocationName).Title("Destination {_Location_}").Width(110);
            })
            .ToolBar(toolbar =>
            {
                toolbar.Custom().ClientTemplate(Html.Kendo().Template().AddComponent(c => c
                    .TextBox().Name("toolbarTextBox")
                    .Placeholder("Filter by {_AssetName_}/{_AssetType_}...")
                    .HtmlAttributes(new { style = "float: right; width: 300px;" })
                    .Events(ev => ev.Change("toolbarTextBoxChanged"))
                ));
                toolbar.Search();
            })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .ServerOperation(false)
                .Model(m => m.Id("Id")) //Ensure that the Model identifier ("Id") is defined.
                .Read(read => read.Action("GetAssignableAssets", "ParentChild").Data("childrenSearchData"))
            )
            .Pageable()
            .Sortable()
            .Selectable()
            )
    </div>
</div>


JS Code:

$(document).ready(function () {
    var treeList = $("#ParentGrid").data("kendoTreeList");
    if (treeList) {
        treeList.dataSource.bind("requestEnd", function (e) {
            if (e.response) {
                if (e.type === "create") {
                    console.log("call requestEnd type: create");
                    treeList.dataSource.read(); // Refresh immediately
                } else if (e.type === "update") {
                    console.log("call requestEnd type: update");
                    setTimeout(function () {
                        treeList.dataSource.read(); // Refresh after 1 second
                    }, 200); // 1000 milliseconds = 1 second
                }
            }
        });
    }
});

function onDragEnd(e) {
    var draggedItem = e.source;         // The dragged item
    var newParent = e.destination;      // The new parent (if changed)
    var newOrder = e.position;  // The new order in the parent

    // Prepare data for backend
    var updateData = {
        sourceId: draggedItem.id,
        destId: newParent ? newParent.id : null,
        destParentId: newParent ? newParent.id : null,
        //sourceItemId = draggedItem.ItemId,
        //destItemId = newParent ? newParent.ItemId : null,
        order: newOrder
    };

    // Make an AJAX call to update the hierarchy/order in the backend
    $.ajax({
        url: "/ParentChild/Reorder", //"/ParentChild/Reorder",
        type: "POST",
        data: {           //{destId: updateData.destId, sourceId: updateData.sourceId, order: updateData.order},
            destId: e.destination.Id,
            sourceId: e.source.Id,
            destParentItemId: e.destination.ParentItemId,
            order: e.position
        },
        //contentType: "application/json",
        success: function () {
            // Optionally refresh the TreeList
            $("#ParentGrid").data("kendoTreeList").dataSource.read();
        },
        error: function () {
            $("#ParentGrid").data("kendoTreeList").dataSource.read();
            alert("Reorder failed (Can't make child asset as parent)");
        }
    });
    console.log("Drag operation ended!", e);
}

// Initialize ParentGrid rows as drop targets
window.initializeDropTargets = function () {
    var draggedItem = null;

    // Make Rows Draggable
    $("#AssetGrid").on("mousedown", "tr", function () {
        var grid = $("#AssetGrid").data("kendoGrid");
        var dataItem = grid.dataItem($(this));
        draggedItem = dataItem; // Track the dragged item's data
        console.log("AssetGrid -> mousedown", draggedItem);
    });

    // Track dragged item from ParentGrid
    $("#ParentGrid").on("mousedown", "tr", function () {
        var parentGrid = $("#ParentGrid").data("kendoTreeList");
        draggedItem = parentGrid.dataItem($(this));
        console.log("ParentGrid -> mousedown", draggedItem);
    });

    $("#ParentGrid").kendoDropTargetArea({
        filter: "tbody tr",
        group: "assetGroup", // Match the draggable group
        drop: function (e) {
            var parentGrid = $("#ParentGrid").data("kendoTreeList"); // Get the Kendo Grid instance
            var dropTargetRow = $(e.dropTarget);    //.closest("#ParentGrid tr.k-table-row.k-master-row"); // The row where the item was dropped
            var targetItem = parentGrid.dataItem(dropTargetRow); // Target row data

            console.log("Dragged Item:", draggedItem.Id);
            console.log("Drop Target:", e.dropTarget);
            console.log("Drop Target Row:", dropTargetRow);
            console.log("Target Item:", targetItem.Id);

            if (targetItem && draggedItem) {
                //alert("Item '" + draggedItem.Title + "' dropped on Parent '" + targetItem.Name + "'");

                // Add AJAX call here to save assignment in the database
                $.ajax({
                    url: "/ParentChild/AssignAsset",
                    method: "POST",
                    data: { parentId: targetItem.Id, itemId: draggedItem.Id, parentItemId: targetItem.ParentItemId },
                    success: function (response) {
                        parentGrid.dataSource.read();
                        $("#AssetGrid").data("kendoGrid").dataSource.read();
                        console.log("AssignAsset ended from kendoDropTargetArea -> drop");
                        //parentGrid.refresh();
                        //alert("Assignment successful!");
                    },
                    error: function () {
                        alert("Error while assigning asset (Can't assign children to child asset).");
                    }
                });
            }
        },
        dragend: function (e) {
            var draggedItem = e.source; // The dragged item
            var newParent = e.destination; // The new parent (if changed)
            var newOrder = e.destinationIndex; // The new order in the parent

            // Prepare data for backend
            var updateData = {
                id: draggedItem.id,
                parentId: newParent ? newParent.id : null,
                order: newOrder
            };

            // Make an AJAX call to update the hierarchy/order in the backend
            $.ajax({
                url: "/ParentChild/Reorder",
                type: "POST",
                data: JSON.stringify(updateData),
                contentType: "application/json",
                success: function () {
                    // Optionally refresh the TreeList
                    $("#TreeList").data("kendoTreeList").dataSource.read();
                    console.log("AssignAsset ended from kendoDropTargetArea -> dragend -> Reorder");
                },
                error: function () {
                    alert("Reorder failed");
                }
            });
        }
    });

    $("#AssetGrid").kendoDropTarget({
        filter: "tbody tr",
        group: "gridGroup", // Match the draggable group
        drop: function (e) {
            var parentGrid = $("#ParentGrid").data("kendoTreeList"); // Get the Kendo Grid instance
            var dropTargetRow = $(e.dropTarget);    //.closest("#ParentGrid tr.k-table-row.k-master-row"); // The row where the item was dropped
            var targetItem = parentGrid.dataItem(dropTargetRow); // Target row data

            console.log("Dragged Item:", draggedItem.Id);
            console.log("Drop Target:", e.dropTarget);
            console.log("Drop Target Row:", dropTargetRow);
            console.log("Target Item:", targetItem.Id);

            if (targetItem && draggedItem) {
                //alert("Item '" + draggedItem.Title + "' dropped on Parent '" + targetItem.Name + "'");

                // Add AJAX call here to save assignment in the database
                $.ajax({
                    url: "/ParentChild/UnAssignAsset",
                    method: "POST",
                    data: { parentId: targetItem.Id, itemId: draggedItem.Id, parentItemId: targetItem.ParentItemId },
                    success: function (response) {
                        parentGrid.dataSource.read();
                        $("#AssetGrid").data("kendoGrid").dataSource.read();
                        console.log("AssignAsset ended from kendoDropTargetArea -> drop");
                        //parentGrid.refresh();
                        //alert("Assignment successful!");
                    },
                    error: function () {
                        alert("Error while assigning asset (Can't assign children to child asset).");
                    }
                });
            }
        }
    });
};


$(document).ready(function () {
    // Make rows in the AssetGrid draggable
    $("#AssetGrid").kendoDraggable({
        filter: "tbody > tr", // Target rows in the grid
        hint: function (element) {
            return $("<div class='k-card k-card-type'><b>" + $(element).find("td:nth-child(2)").text() + "</b></div>");
        },
        group: "assetGroup"
    });

    var treeList = $("#ParentGrid").data("kendoTreeList");
    // Configure drag-and-drop from TreeList to Grid
    treeList.wrapper.kendoDraggable({
        filter: "tr",
        hint: function (element) {
            var item = treeList.dataItem(element);
            console.log("treeList.wrapper.kendoDraggable -> ", item);
            return element;
        },
        group: "gridGroup"         
    });
    window.initializeDropTargets();
});

Ivaylo
Telerik team
 answered on 16 Jun 2025
1 answer
12 views

Hello,

create/update posts an empty model to the controller.

It was working in a very old asp.net mvc project. I setup a new asp.net core project. I spent some hours to fix this, but no luck.

Reading the data source is ok and the data is shown in column 'valuestream'. At the moment for 'Agenda' two values are shown, editable with a mutiselect.

 

 

Controller:

public ActionResult ManagerQuestionnaireCreate([DataSourceRequest] DataSourceRequest request, QuestionnaireViewModel rs)

....

return Json(new[] { rs }.ToDataSourceResult(request, ModelState));
}

Model:

View:

 

Mihaela
Telerik team
 answered on 12 Jun 2025
1 answer
9 views

Prior to the most recent version we could use reflection to get the grid name in this method.

We have changed it to pass the grid name, but was wondering if there is a programmatic way of getting the grid name without passing it

 

        public static GridToolBarCommandFactory<T> SuperSearch<T>(this GridToolBarCommandFactory<T> builder, string gridName, string title = "Super Search...") where T : class
        {
            builder.Spacer();
            builder.Custom().ClientTemplate($"<span class=\"k-input k-input-md k-rounded-md k-input-solid\" style=\"width: 400px;\"><input id=\"superSearch\" name=\"superSearch\" oninput=\"window.top.superSearch('{gridName}')\" class=\"k-input-inner\" autocomplete=\"off\" placeholder=\"{title}\"/></span>");

            return builder;
        }
Eyup
Telerik team
 answered on 03 Jun 2025
1 answer
7 views
I was wondering if it was possible to skip non-editable fields when using Tab to navigate the grid rows?
Eyup
Telerik team
 answered on 26 May 2025
1 answer
25 views
i have sample application. when export to excel using ToXlsxStream date field show as number value instead of date . 
Ivaylo
Telerik team
 answered on 12 May 2025
1 answer
38 views

I have a grid with custom editors and they are bound to the grid as such.

columns.Bound(x => x.Parent).EditorTemplateName("ParentEditor").ClientTemplate("#= Parent === undefined || Parent === null ? '' : parentTemplate(Parent)#");
columns.Bound(x => x.Child).EditorTemplateName("ChildEditor").ClientTemplate("#= Child === undefined || Child === null ? '' : childTemplate(Child)#");

The two editor templates look like this:

@model List<ParentViewModel>  
@(Html.Kendo()  
     .MultiSelectFor(m => m)  
     .DataTextField("Name")  
     .DataValueField("Id")  
     .Placeholder("Select one or more parents")  
     .AutoBind(true)  
     .TagMode(MultiSelectTagMode.Multiple)   
     .DataSource(source =>  
     {  
         source  
         .Read(read =>  
         {  
             read.Action("GetParent", "Lookup");  
         });  
     })  
     .Events(events => events.Change("onParentChange"))  
)  


@model List<ChildViewModel>
@(Html.Kendo()
      .MultiSelectFor(m => m)
      .DataTextField("Name")
      .DataValueField("Id")
      .Placeholder("Select one or more children")
      .AutoBind(true)
      .TagMode(MultiSelectTagMode.Multiple)
      .DataSource(source =>
      {
          source
          .Read(read =>
          {
              read.Action("GetChild", "Lookup").Data("getCurrentParents");
          })
          ;
      })
)

The UI is properly populating when the grid loads and looks like this:

Coumn Parent|Column Child
A           |A1
B           |B1, B2

When the user edits the row and removes item B from Column Parent, this code is invoked (which I got from Kendo UI Snippet | Kendo UI Dojo)

function onParentChange(e) {
    var selectedonParentChange = this.value();
    let dataItems = e.sender.dataItems();

	var multiSelect = $("#Child").data("kendoMultiSelect");
	var value = multiSelect.value();
	multiSelect.dataSource.filter(getFilterObj(dataItems));
	multiSelect.dataSource.filter({});  // Adding or removing has no effect
    multiSelect.refresh();
	multiSelect.value(value);
	console.log("Second value: " + multiSelect.value());
    var dataSource = multiSelect.dataSource;
    dataSource.read();
}

function getFilterObj(dataItems){
  let filtObj = {
    logic: "or",
    filters: [],
  };

  if(dataItems.length > 0){
    for (var i = 0; i < dataItems.length; i++) {
      filtObj.filters.push({
        field: "ParentId",
        operator: "eq",
        value: dataItems[i].Id
      });
    }
  } else {
    filtObj.filters.push({
        field: "ParentId",
        operator: "eq",
        value: ""
      });
  }

  return filtObj;
}

After the code runs, the UI looks like this:
Coumn Parent|Column Child
A           |A1

So far so good.  The problem is that when the user hits save this ends up on the Network in the form data:

Parent[0].Id: ParentIdA
Parent[0].Name: A
Child[0].Id: ChildId1
Child[0].Name: A1
Child[0].ParentId: ParentIdA
Child[1].Id: ChildId2
Child[1].Name: B1
Child[1].ParentId: ParentIdB
Child[2].Id: ChildId3
Child[2].Name: B2
Child[2].ParentId: ParentIdB
Although B1 and B2 no longer display in the UI, they are still being sent to the controller when the item is saved.  I'm not sure how to prevent them from being sent when they are no longer in the UI.

Kendo Version: 2024.4.1112
Eyup
Telerik team
 answered on 06 May 2025
1 answer
37 views

I'm currently redesigning the filter menus in our MVC ASP.NET Core project. As of now, they all have the default menu:

I would like to customise the menus according to the columns' data types - have date range pickers for dates, a slider from min to max value for numbers, etc. The main point is to make the process simpler - so the users only need to input a few characters/choose a date/slide to the right number, instead of filling out this complicated configuration.

Some of such components are provided by kendo (e.g. DateRangePicker), others aren't (e.g. the above-mentioned slider; at least I didn't find anything like it), but could be implemented with a custom function. Either way, I can't seem to be able to override the default filter menu.

The only promising suggesstion on how to achieve something like this that I found was:

grid.Columns(c => c.Bound(item.Name)
       .Filterable(ftb => ftb.UI("datePickerFilter"))
function datePickerFilter(element) {
    element.kendoDateRangePicker({
        messages: {
            startLabel: "Check-In",
            endLabel: "Check-Out"
        },
        format: "MM/dd/yyyy"
    });
}
Unfortunately, it did not work. So any help, advice or personal experience with a similar issue will be very much appreciated :) Thanks.
Anton Mironov
Telerik team
 answered on 03 Apr 2025
1 answer
39 views

I am getting loading error when using aspnet Core grid with dynamic columns and Filterable option. The grid is loading fine when the Filterable option is not configured. Also, events are not working properly. I am using 2024.4.1112 version.

Here is sample code

 @(
     Html.Kendo().Grid<dynamic>()
     .Name(Model.GridId)
     .Columns(columns =>
     {
         foreach (var col in Model.Columns)
         {
             var kendoColumn = columns.Bound(col.PropertyName);
             kendoColumn.Title(col.Title);
             kendoColumn.Width(col.Width);
             kendoColumn.Filterable(col.Filterable);
             if (!string.IsNullOrEmpty(col.Format))
             {
                 kendoColumn.Format(col.Format);
             }
             if (!string.IsNullOrEmpty(col.Template))
             {
                 kendoColumn.ClientTemplate(col.Template);
             }
             if (col.DataType == "boolean")
             {
                 kendoColumn.HtmlAttributes(new { style = "text-align:center" });
             }
         }
     })
     .Pageable(p =>
     {
         p.ButtonCount(10);
         p.PageSizes(true);
         p.Refresh(true);
     })
     .Filterable(f => f.Mode(GridFilterMode.Menu))
     .Sortable()
     .ColumnMenu(c =>c.Filterable(true))
     .Reorderable(r => r.Columns(true))
     .Resizable(r => r.Columns(true))
     .DataSource(dataSource => dataSource
     .Ajax()
     .Read(read => read.Action("Entity", "History", new { entityName = Model.EntityName, pkValue = Model.PrimaryKeyValue, entityType = Model.EntityType, pkName = Model.PrimaryKeyName }))
     )
     .Events(e => e.Change("ob-select"))
     )
Mihaela
Telerik team
 answered on 19 Mar 2025
Narrow your results
Selected tags
Tags
+? more
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?