Kendo UI Grid : Drag and Drop Hierarchy not working - javascript
I want to drag and drop in different Grid with hierarchical data.
The Drag and drop is working fine but the row is not dropping in Detail item in destination grid.
I have created the sample here. here is the sample for the same..
The following code shows how i built this, but getting some issues in the same. Please help me out what mistake i am doing in this?
function convert(array) {
var map = {};
for (var i = 0; i < array.length; i++) {
var obj = array[i];
obj.items = [];
map[obj.DemographicId] = obj;
var parent = obj.ParentId || '-';
if (!map[parent]) {
map[parent] = {
items: []
};
}
map[parent].items.push(obj);
}
return map['-'].items;
}
var arr = [{"Level":1,"DemographicId":13,"ParentId":null,"Name":"Bewitched General","Description":0.335336528},{"Level":2,"DemographicId":349,"ParentId":13,"Name":"Unacceptable Experience","Description":0.335336528},{"Level":1,"DemographicId":14,"ParentId":null,"Name":"Trained Trust","Description":29.17427794},{"Level":2,"DemographicId":329,"ParentId":14,"Name":"Concerned Rest","Description":0.335336528},{"Level":2,"DemographicId":331,"ParentId":14,"Name":"Tough Sleep","Description":2.012019168},{"Level":3,"DemographicId":346,"ParentId":331,"Name":"Icy Coffee","Description":0.335336528},{"Level":3,"DemographicId":347,"ParentId":331,"Name":"Big Fix","Description":0.335336528},{"Level":3,"DemographicId":348,"ParentId":331,"Name":"Total Worry","Description":0.335336528},{"Level":3,"DemographicId":431,"ParentId":331,"Name":"Fast Discipline","Description":0.335336528},{"Level":3,"DemographicId":586,"ParentId":331,"Name":"Intrepid Sister","Description":0.335336528},{"Level":2,"DemographicId":376,"ParentId":14,"Name":"Hasty Ordinary","Description":0.335336528},{"Level":2,"DemographicId":428,"ParentId":14,"Name":"Unnatural Native","Description":1.006009584},{"Level":3,"DemographicId":442,"ParentId":428,"Name":"Tan Celebration","Description":0.335336528},{"Level":3,"DemographicId":492,"ParentId":428,"Name":"Wise Repair","Description":0.335336528},{"Level":2,"DemographicId":443,"ParentId":14,"Name":"Frightening Historian","Description":3.018028753},{"Level":3,"DemographicId":328,"ParentId":443,"Name":"Improbable Stage","Description":0.335336528},{"Level":3,"DemographicId":517,"ParentId":443,"Name":"Heavenly Debt","Description":0.335336528},{"Level":3,"DemographicId":526,"ParentId":443,"Name":"That Art","Description":2.012019168},{"Level":4,"DemographicId":524,"ParentId":526,"Name":"Vivacious Competition","Description":0.670673056},{"Level":5,"DemographicId":445,"ParentId":524,"Name":"Dependable Potato","Description":0.335336528},{"Level":4,"DemographicId":525,"ParentId":526,"Name":"Watchful Tough","Description":1.006009584},{"Level":5,"DemographicId":432,"ParentId":525,"Name":"Lovable Sing","Description":0.670673056},{"Level":6,"DemographicId":435,"ParentId":432,"Name":"Vengeful Cigarette","Description":0.335336528},{"Level":2,"DemographicId":522,"ParentId":14,"Name":"Insistent Offer","Description":0.335336528},{"Level":2,"DemographicId":590,"ParentId":14,"Name":"Oddball Airline","Description":0.335336528},{"Level":2,"DemographicId":591,"ParentId":14,"Name":"Back Outcome","Description":20.79086474},{"Level":3,"DemographicId":330,"ParentId":591,"Name":"Mushy Active","Description":0.335336528},{"Level":3,"DemographicId":427,"ParentId":591,"Name":"Immaterial Safety","Description":1.341346112},{"Level":4,"DemographicId":437,"ParentId":427,"Name":"Same Restaurant","Description":0.335336528},{"Level":4,"DemographicId":438,"ParentId":427,"Name":"Imaginary Brother","Description":0.335336528},{"Level":4,"DemographicId":613,"ParentId":427,"Name":"Bubbly Hole","Description":0.335336528},{"Level":3,"DemographicId":433,"ParentId":591,"Name":"Several Weird","Description":2.682692225},{"Level":4,"DemographicId":426,"ParentId":433,"Name":"Deadly Potato","Description":0.335336528},{"Level":4,"DemographicId":436,"ParentId":433,"Name":"Ornery Race","Description":0.335336528},{"Level":4,"DemographicId":440,"ParentId":433,"Name":"Trusting Native","Description":0.335336528},{"Level":4,"DemographicId":441,"ParentId":433,"Name":"Flowery Tower","Description":0.335336528},{"Level":4,"DemographicId":479,"ParentId":433,"Name":"Downright Fall","Description":0.335336528},{"Level":4,"DemographicId":480,"ParentId":433,"Name":"Unique Career","Description":0.335336528},{"Level":4,"DemographicId":614,"ParentId":433,"Name":"Unknown Thomas","Description":0.335336528},{"Level":3,"DemographicId":592,"ParentId":591,"Name":"Judicious Analyst","Description":0.335336528},{"Level":3,"DemographicId":593,"ParentId":591,"Name":"Hard Major","Description":0.335336528},{"Level":3,"DemographicId":595,"ParentId":591,"Name":"Naughty Temporary","Description":0.335336528},{"Level":3,"DemographicId":596,"ParentId":591,"Name":"Crisp Commission","Description":0.335336528},{"Level":3,"DemographicId":597,"ParentId":591,"Name":"Valid Funny","Description":0.335336528},{"Level":3,"DemographicId":598,"ParentId":591,"Name":"Luminous Log","Description":0.335336528},{"Level":3,"DemographicId":599,"ParentId":591,"Name":"Sour Introduction","Description":0.335336528},{"Level":3,"DemographicId":600,"ParentId":591,"Name":"Elegant Player","Description":0.335336528},{"Level":3,"DemographicId":601,"ParentId":591,"Name":"Wilted Scheme","Description":1.006009584},{"Level":4,"DemographicId":444,"ParentId":601,"Name":"That Research","Description":0.335336528},{"Level":4,"DemographicId":609,"ParentId":601,"Name":"Overcooked Message","Description":0.335336528},{"Level":3,"DemographicId":602,"ParentId":591,"Name":"Good-natured Responsibility","Description":3.688701809},{"Level":4,"DemographicId":478,"ParentId":602,"Name":"Cumbersome Battle","Description":0.335336528},{"Level":4,"DemographicId":515,"ParentId":602,"Name":"Unsightly Contest","Description":2.682692225},{"Level":5,"DemographicId":439,"ParentId":515,"Name":"Mushy Explanation","Description":0.335336528},{"Level":5,"DemographicId":508,"ParentId":515,"Name":"Obvious Pride","Description":0.670673056},{"Level":6,"DemographicId":509,"ParentId":508,"Name":"Negligible Ask","Description":0.335336528},{"Level":5,"DemographicId":514,"ParentId":515,"Name":"Concerned Classic","Description":1.341346112},{"Level":6,"DemographicId":510,"ParentId":514,"Name":"Greedy Double","Description":0.335336528},{"Level":6,"DemographicId":511,"ParentId":514,"Name":"Reflecting Poem","Description":0.335336528},{"Level":6,"DemographicId":512,"ParentId":514,"Name":"Every Finish","Description":0.335336528},{"Level":4,"DemographicId":610,"ParentId":602,"Name":"Zigzag Meet","Description":0.335336528},{"Level":3,"DemographicId":603,"ParentId":591,"Name":"Esteemed Satisfaction","Description":0.335336528},{"Level":3,"DemographicId":604,"ParentId":591,"Name":"Normal Trouble","Description":1.341346112},{"Level":4,"DemographicId":485,"ParentId":604,"Name":"Hot Fish","Description":0.335336528},{"Level":4,"DemographicId":611,"ParentId":604,"Name":"Eager Perception","Description":0.335336528},{"Level":4,"DemographicId":612,"ParentId":604,"Name":"Shocking Aside","Description":0.335336528},{"Level":3,"DemographicId":605,"ParentId":591,"Name":"Terrific King","Description":0.335336528},{"Level":3,"DemographicId":606,"ParentId":591,"Name":"Humiliating Suit","Description":0.335336528},{"Level":3,"DemographicId":607,"ParentId":591,"Name":"Serious Smile","Description":0.335336528},{"Level":3,"DemographicId":608,"ParentId":591,"Name":"Memorable Ship","Description":3.353365281},{"Level":4,"DemographicId":430,"ParentId":608,"Name":"Wan Science","Description":0.335336528},{"Level":4,"DemographicId":434,"ParentId":608,"Name":"Hard Rule","Description":0.335336528},{"Level":4,"DemographicId":473,"ParentId":608,"Name":"Marvelous Radio","Description":0.335336528},{"Level":4,"DemographicId":477,"ParentId":608,"Name":"Visible Personality","Description":0.335336528},{"Level":4,"DemographicId":481,"ParentId":608,"Name":"Scrawny Shine","Description":0.335336528},{"Level":4,"DemographicId":507,"ParentId":608,"Name":"Descriptive Pride","Description":0.335336528},{"Level":4,"DemographicId":516,"ParentId":608,"Name":"Pleased Private","Description":0.335336528},{"Level":4,"DemographicId":548,"ParentId":608,"Name":"Frizzy District","Description":0.335336528},{"Level":4,"DemographicId":615,"ParentId":608,"Name":"Juicy Organization","Description":0.335336528},{"Level":3,"DemographicId":616,"ParentId":591,"Name":"Sweaty Equal","Description":0.335336528},{"Level":3,"DemographicId":621,"ParentId":591,"Name":"Sweltering Cigarette","Description":0.335336528},{"Level":3,"DemographicId":623,"ParentId":591,"Name":"Buoyant Rule","Description":0.335336528},{"Level":3,"DemographicId":625,"ParentId":591,"Name":"Whimsical Remote","Description":0.335336528},{"Level":3,"DemographicId":633,"ParentId":591,"Name":"Notable Feed","Description":0.335336528},{"Level":3,"DemographicId":635,"ParentId":591,"Name":"Puzzled Pin","Description":1.006009584},{"Level":4,"DemographicId":594,"ParentId":635,"Name":"Plump Member","Description":0.335336528},{"Level":4,"DemographicId":636,"ParentId":635,"Name":"Colorless Service","Description":0.335336528},{"Level":2,"DemographicId":618,"ParentId":14,"Name":"Extroverted Excuse","Description":0.335336528},{"Level":2,"DemographicId":622,"ParentId":14,"Name":"Definite Sector","Description":0.335336528},{"Level":2,"DemographicId":631,"ParentId":14,"Name":"Dear Blue","Description":0.335336528},{"Level":1,"DemographicId":15,"ParentId":null,"Name":"Weird Rush","Description":3.688701809},{"Level":2,"DemographicId":461,"ParentId":15,"Name":"Vigilant Mine","Description":0.335336528},{"Level":2,"DemographicId":527,"ParentId":15,"Name":"Darling Cousin","Description":2.682692225},{"Level":3,"DemographicId":504,"ParentId":527,"Name":"Courteous Knife","Description":0.335336528},{"Level":3,"DemographicId":528,"ParentId":527,"Name":"Constant Window","Description":2.012019168},{"Level":4,"DemographicId":6,"ParentId":528,"Name":"Serene Personal","Description":0.335336528},{"Level":4,"DemographicId":518,"ParentId":528,"Name":"Cooperative Marketing","Description":0.335336528},{"Level":4,"DemographicId":530,"ParentId":528,"Name":"Likely Car","Description":0.335336528},{"Level":4,"DemographicId":531,"ParentId":528,"Name":"Worst Lip","Description":0.335336528},{"Level":4,"DemographicId":550,"ParentId":528,"Name":"Quintessential Evening","Description":0.335336528},{"Level":2,"DemographicId":529,"ParentId":15,"Name":"Knowing Debt","Description":0.335336528},{"Level":2,"DemographicId":587,"ParentId":15,"Name":"Harmless Weight","Description":0.335336528},{"Level":1,"DemographicId":16,"ParentId":null,"Name":"Tidy Mouse","Description":2.012019168},{"Level":2,"DemographicId":5,"ParentId":16,"Name":"Useless Chemistry","Description":0.335336528},{"Level":2,"DemographicId":254,"ParentId":16,"Name":"Several Expert","Description":0.335336528},{"Level":2,"DemographicId":486,"ParentId":16,"Name":"Young String","Description":0.335336528},{"Level":2,"DemographicId":519,"ParentId":16,"Name":"Ideal Army","Description":1.006009584},{"Level":3,"DemographicId":520,"ParentId":519,"Name":"Tart Text","Description":0.335336528},{"Level":3,"DemographicId":521,"ParentId":519,"Name":"Tiny Church","Description":0.335336528}]
var myData = convert(arr)
var dataSource1 = new kendo.data.DataSource({
data: myData
});
$(document).ready(function () {
var originalGrid = $("#originalGrid").kendoGrid({
dataSource: dataSource1,
sortable: false,
pageable: false,
detailInit: detailInit1,
dataBound: function () {
//this.expandRow(this.tbody.find("tr.k-master-row").last());
},
columns: [
{
field: "Name",
title: "Name",
width: "80px"
},
{
field: "Description",
title: "Amount",
width: "30px",
aggregates: ["sum"],
groupFooterTemplate: "Sum: #= sum # "
}
]
});
});
function detailInit1(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
data: e.data.items //data is the current position item, items is its child items
},
scrollable: false,
sortable: false,
pageable: false,
detailInit: detailInit1,
columns: [
{
field: "Name",
title: "Name",
width: "80px"
},
{
field: "Description",
title: "Amount",
width: "30px",
aggregates: ["sum"],
groupFooterTemplate: "Sum: #= sum # "
}
]
});
}
$(document).ready(function () {
var dataSource2 = new kendo.data.DataSource({
data: []
});
var grid2 = $("#grid2").kendoGrid({
dataSource: dataSource2,
width: 400,
sortable: false,
pageable: false,
detailInit: detailInit11,
schema: {
model: {
id: "DemographicId"
}
},
columns: [
{
field: "Name",
title: "Name",
width: "40px"
},
{
field: "Description",
title: "Amount",
width: "110px",
aggregates: ["sum"],
groupFooterTemplate: "Sum: #= sum # "
}
]
});
function detailInit11(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
data: e.data.items
},
scrollable: false,
sortable: false,
pageable: false,
detailInit: detailInit11,
columns: [
{
field: "Name",
title: "Name",
width: "110px"
},
{
field: "Description",
title: "Amount",
width: "110px",
aggregates: ["sum"],
groupFooterTemplate: "Sum: #= sum # "
}
]
});
}
$(originalGrid).kendoDraggable({
filter: "tr",
hint: function (e) {
var item = $('<div class="k-grid k-widget" style="background-color: DarkOrange; color: black;"><table><tbody><tr>' + e.html() + '</tr></tbody></table></div>');
return item;
},
group: "gridGroup1",
});
var currentDataItem = null;
function getItemByUid(uid, currentUid, data) {
for (let index = 0; index < data.length; index++) {
const element = data[index];
if (element.uid == currentUid) {
currentDataItem = element;
return false;
} else {
if (element.items) {
getItemByUid(element.uid, currentUid, element.items);
}
}
}
}
grid2.kendoDropTarget({
drop: function (e) {
var uid = e.draggable.currentTarget.data("uid");
var dataItem = getItemByUid(uid, uid, dataSource1.data());
dataSource2.add(currentDataItem);
},
group: "gridGroup1",
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.rtl.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.silver.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.mobile.all.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.1.221/js/kendo.all.min.js"></script>
</head>
<body>
<div>
<div style="width:50%;float:left" class="dragGrid">
<div id="originalGrid"></div>
</div>
<div style="width:50%;float:right" >
<div id="grid2"></div>
</div>
</div>
</body>
</html>
You need to handle the drop target for the detail grids as well. Use the - almost - same code for kendoDropTarget to your detail grid:
gridDetail.kendoDropTarget({
drop: function (e) {
var uid = e.draggable.currentTarget.data("uid");
var dataItem = getItemByUid(uid, uid, dataSource1.data());
$(e.dropTarget).data("kendoGrid").dataSource.add(currentDataItem);
},
group: "gridGroup1",
});
Demo
Related
Kendo grid loosing selected row
I'm using Kendo UI for my grid everything works find with that. I can select one or many rows using scroll and shift. The problem is that if I select row 3 and then some event refresh the grid and after that I want to select row 4 too Kendo is selecting all the above rows, in this case from row 1-4. So my question is how can I solve this issue? Desired result in the demo: Select Germany, refresh grid, then select until Belgium. The demo is going to select from row 1 to Belgium. Here is a demo <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Kendo UI Snippet</title> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css"/> <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script> </head> <body> <button id="refresh">Refresh</button> <div id="grid"></div> <script> $(function () { var selectedOrders = []; var idField = "OrderID"; $('#refresh').click(() => { $("#grid").getKendoGrid().dataSource.read(); }) $("#grid").kendoGrid({ dataSource: { type: "odata", transport: { read: "http://demos.kendoui.com/service/Northwind.svc/Orders" }, schema: { model: { id: "OrderID", fields: { OrderID: { type: "number" }, Freight: { type: "number" }, ShipName: { type: "string" }, OrderDate: { type: "date" }, ShipCity: { type: "string" } } } }, pageSize: 10, serverPaging: true, serverFiltering: true, serverSorting: true }, height: 400, selectable: "multiple", pageable: { buttonCount: 5 }, sortable: true, filterable: true, navigatable: true, columns: [ { field: "ShipCountry", title: "Ship Country", width: 300 }, { field: "Freight", width: 300 }, { field: "OrderDate", title: "Order Date", format: "{0:dd/MM/yyyy}" } ], change: function (e, args) { var grid = e.sender; var items = grid.items(); items.each(function (idx, row) { var idValue = grid.dataItem(row).get(idField); if (row.className.indexOf("k-state-selected") >= 0) { selectedOrders[idValue] = true; } else if (selectedOrders[idValue]) { delete selectedOrders[idValue]; } }); }, dataBound: function (e) { var grid = e.sender; var items = grid.items(); var itemsToSelect = []; items.each(function (idx, row) { var dataItem = grid.dataItem(row); if (selectedOrders[dataItem[idField]]) { itemsToSelect.push(row); } }); e.sender.select(itemsToSelect); } }); }); </script> </body> </html>
This problem is so similar to the problem I had which I wrote about here, Kendo Grid Persist Row Example. In the example I wrote, I used persistSelection which is recommended. This behaviour is happening because after the refresh event the grid no longer knows which row was focused previously. So on dataBound, we need to set that focus back. Here's a snippet that might help you. <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Kendo UI Snippet</title> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css"/> <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script> </head> <body> <button id="refresh">Refresh</button> <div id="grid"></div> <script> $(function() { var selectedOrders = []; var idField = "OrderID"; $('#refresh').click(() => { $("#grid").getKendoGrid().dataSource.read(); }); $("#grid").kendoGrid({ dataSource: { type: "odata", transport: { read: "http://demos.kendoui.com/service/Northwind.svc/Orders" }, schema: { model: { id: "OrderID", fields: { OrderID: { type: "number" }, Freight: { type: "number" }, ShipName: { type: "string" }, OrderDate: { type: "date" }, ShipCity: { type: "string" } } } }, pageSize: 10, serverPaging: true, serverFiltering: true, serverSorting: true }, height: 400, selectable: "multiple", pageable: { buttonCount: 5 }, sortable: true, filterable: true, navigatable: true, columns: [ { field: "ShipCountry", title: "Ship Country", width: 300 }, { field: "Freight", width: 300 }, { field: "OrderDate", title: "Order Date", format: "{0:dd/MM/yyyy}" } ], change: function (e, args) { var grid = e.sender; var items = grid.items(); items.each(function (idx, row) { var idValue = grid.dataItem(row).get(idField); if (row.className.indexOf("k-state-selected") >= 0) { selectedOrders[idValue] = true; } else if (selectedOrders[idValue]) { delete selectedOrders[idValue]; } }); }, dataBound: function (e) { var grid = e.sender; var items = grid.items(); var itemsToSelect = []; items.each(function (idx, row) { var dataItem = grid.dataItem(row); if (selectedOrders[dataItem[idField]]) { itemsToSelect.push(row); } }); if (itemsToSelect.length > 0) { var lastRow = itemsToSelect[itemsToSelect.length - 1]; grid.selectable._lastActive = lastRow; grid.current($(lastRow).find("td:first")); } e.sender.select(itemsToSelect); } }); }); </script> </body> </html>
you can get and persist selected row on a specific page after edit or paging in change and databound events like this: Grid_OnRowSelect = function (e) { this.currentPageNum = grid.dataSource.page(); //Save index of selected row this.selectedIndex = grid.select().index(); } .Events(e => e.DataBound( #<text> function(e) { //جهت نمایش صحیح پیجینگ var grid = $("#Grid").data("kendoGrid"); grid.pager.resize(); //در صورت تغییر صفحه، سطر را انتخاب نکند if(this.currentPageNum == grid.dataSource.page()) { //انتخاب مجدد سطر انتخاب شده قبل از ویرایش var row = grid.table.find("tr:eq(" + this.selectedIndex + ")"); grid.select(row); } } </text>) ) in your case you can set rows in a list and use in databound
Why does KendoUI grid add a row to the beginning of the grid and not give the User a choice using rowindex?
Im using KendoUi grids everywhere now and need some help .. When my Kendo grid first loads I want the user to have the rows and an empty row at the BOTTOM not the top to indicate that they can add data . I dont want to use the in built "Add Row Button". I have the following Try1 $(document).ready(function () { var grid = $("#grid").data("kendoGrid"); grid.addRow(); $(".k-grid-edit-row").appendTo("#grid tbody"); } This is supposed to move the row to the bottom of the grid , but it doesnt, it remans on top ? Try 2 I also tried to do something like var newRow = { field: "FirstName", Value: "" }; var grid = $("#grid").data("kendoGrid"); grid.dataSource.add(newRow); This did not work either. Try 3 But with this try , im not sure if there is a 'load' with the Kendoui Grid, i know there is a keydown , etc grid.tbody.on('load', function (e) { if ($(e.target).closest('tr').is(':last-child')) { setTimeout(function () { var totalrows = grid.dataSource.total(); var data = grid.dataSource.data(); var lastItem = data[data.length - 1]; if (typeof lastItem !== 'undefined') { if (lastItem.FirstName.trim() != "") grid.addRow(); } }) } } any help would be great. The full implementation details is below: First i add the datasource, this is a simple implementation. var data = $scope.userdetails; var dataSource = new kendo.data.DataSource({ transport: { read: function (e) { e.success(data); }, update: function (e) { e.success(); }, create: function (e) { var item = e.data; item.Id = data.length + 1; e.success(item); } }, schema: { model: { id: "Id", fields: { FirstName: { type: "string" } } } } }); Then i define the grid let grid = $("#grid").kendoGrid({ dataSource: dataSource, scrollable: false, navigatable: true, editable: { createAt: "bottom" }, dataBound: function (e) { e.sender.tbody.find(".k-grid-Delete").each(function (idx, element) { $(element).removeClass("k-button"); }); }, columns: [ { field: "FirstName", title: "First Name" }, { command: [{ name: "Delete", text: "", click: $scope.delete, className: "far fa-trash-alt fa-fw" }], title: " ", width: "100px", attributes: { class: "k-grid-column-text-centre" } } ] }).data("kendoGrid"); I do the below process to add a blank row only when the user clicks tab on the last cell of the last row, but also want to add a blank when the page first loads with the grid. grid.tbody.on('keydown', function (e) { i`enter code here`f (e.keyCode == 9) { if ($(e.target).closest('tr').is(':last-child')) { setTimeout(function () { var totalrows = grid.dataSource.total(); var data = grid.dataSource.data(); var lastItem = data[data.length - 1]; if (typeof lastItem !== 'undefined') { if (lastItem.FirstName.trim() == "") return; } grid.addRow(); }) } } }); This code still adds the row at the top of the grid not the bottom. $(document).ready(function () { var newRow = { field: "FirstName", Value: "" }; grid.dataSource.add(newRow); grid.editRow($("#grid tr").last()); } There is no other place that i add a row
You try #2 is the right way to go. It probably added a row at the bottom, right? So you just need to programatically edit it: var newRow = { field: "FirstName", Value: "" }; var grid = $("#grid").data("kendoGrid"); grid.dataSource.add(newRow); grid.editRow($("#grid tr").last()); Demo: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Kendo UI Snippet</title> <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.2.513/styles/kendo.default-v2.min.css"/> <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="https://kendo.cdn.telerik.com/2020.2.513/js/kendo.all.min.js"></script> </head> <body> <div id="grid"></div> <script> let grid = $("#grid").kendoGrid({ toolbar: ["save"], columns: [ { field: "name" }, { field: "age" } ], dataSource: { data: [ { id: 1, name: "Jane Doe", age: 30 }, { id: 2, name: "John Doe", age: 33 } ], schema:{ model: { id: "id", fields: { age: { type: "number"} } } } }, editable: true }).data('kendoGrid'); grid.dataSource.add({}); grid.editRow($("#grid tr").last()); </script> </body> </html> Dojo If someone is using the built-in method, just use editable.createAt parameter.
Tabulator - Set data
I'm using a multi step form, "https://www.jqueryscript.net/demo/Signup-Form-Wizard-jQuery-multiStepForm/"this is the link that ı use. while multi step form page is opening, I call the load function and I also call data in my database with ajax. When I called the data I created a tableData object and I set this object to the tabuator table that I have specified. Jquery Version:3.4.1; Tabulator Version:4.5; HTML <script src="~/Content/js/jquery-3.4.1.min.js"></script> <script src="~/Content/js/jquery-ui.min.js"></script> <script src="~/Content/js/tabulator.min.js"></script> <script src="~/Content/js/jquery_wrapper.min.js"></script> JavaScript var table; // Define Date Editor var dateEditor = function (cell, onRendered, success, cancel, editorParams) { var cellValue = cell.getValue(), var input = document.createElement("input"); input.setAttribute("type", "text"); input.style.padding = "4px"; input.style.width = "100%"; input.style.boxSizing = "border-box"; input.value = typeof cellValue !== "undefined" ? cellValue : ""; onRendered(function () { $(input).datepicker({ dateFormat: "dd-mm-yy", altFormat: "dd-mm-yy", changeMonth: true, changeYear: true, yearRange: '-119:+119', monthNames: ["Ocak", "Şubat", "Mart", "Nisan", "Mayis", "Haziran", "Temmuz", "A?ustos", "Eylul", "Ekim", "Kasım", "Aralık"], monthNamesShort: ["Ock", "Şub", "Mart", "Nis", "May", "Haz", "Tem", "Agst", "Eyl", "Ekm", "Kas", "Ar"], dayNamesMin: ["Pa", "Pt", "Sl", "Ca", "Pe", "Cu", "Ct"], firstDay: 1, onSelect: function (dateStr) { var dateselected = $(this).datepicker('getDate'); var cleandate = (moment(dateselected, "DD-MM-YYYY").format("DD-MM-YYYY")); $(input).datepicker("destroy"); cell.setValue(cleandate, true); cancel(); }, }); input.style.height = "100%"; }); return input; }; //Create Table var table = new Tabulator("#example-table", { columns: [ { title: "Davalı Türü", field: "davalitur", editor: "select", editorParams: { values: { "Seçiniz": "Seçiniz", "Kişi": "Kişi", "Kurum": "Kurum" } } }, { title: "Davalı", field: "adsoyadkurum", editor: "input" }, { title: "Kusur Oranı", field: "kusuroran", editor: "input" }, { title: "Sigorta Şirket Ünvanı", field: "unvan", editor: "input" }, { title: "İhbar Tarihi", field: "sit", align: "center", sorter: "date", editor: dateEditor }, { title: "Temerrüte Düşme Tarihi", field: "tdt", align: "center", sorter: "date", editor: dateEditor }, { title: "Faiz Oranı", field: "faizorani", editor: "select", editorParams: { values: { "Kanuni Faiz Oranı": "Kanuni Faiz Oranı", "Ticari Faiz Oranı": "Ticari Faiz Oranı" } } }, { title: "Ödemeyi Yapan", field: "odemeyapanselectval", editor: "select", editorParams: { values: { "Seçiniz": "Seçiniz", "Davalı": "Davalı", "Sigortacı": "Sigortacı" } } }, { title: "Ödeme Yapılan", field: "odemeyapilandavaci", editor: "select", editorParams: { values: { "Eşi": "Eşi", "Çocuk": "Çocuk", "Anne-Baba": "Anne-Baba", "Diğer": "Diğer" } } }, { title: "Ödeme Tarihi", field: "odemetarih", align: "center", sorter: "date", editor: dateEditor }, { title: "Ödeme Tutarı", field: "odemetutar", editor: "input" }, { title: "Güvence Ödeme Tarihi", field: "guvenceodemetarih", align: "center", sorter: "date", editor: dateEditor }, { title: "Güvence Ödeme Tutarı", field: "guvenceodemetutar", editor: "input" }, {title: "Durum", formatter: "buttonCross", align: "center", cellClick: function (e, cell) { cell.getRow().delete(); //if (confirm('İlgili davalı silinecekt')) cell.getRow().delete();//Dialog Eklenicek } }, ], }); // Step 4 load function function dykstep4Yukle() { $.ajax({ type: 'POST', dataType: 'json', cache: 'false', url: '../Client2DB/DykStepGetir', data: { projeid: projeId, stepNo: 4 }, success: function (data) { counterloaddyk++; if (counterloaddyk == 5) { $('#pre-load').fadeOut(); } var obj = JSON.parse(data.json); $('#pre-load').fadeOut(); $.each(obj.DavaliTabloListe, function (key, value) { tableData = [{ id: value.id, davalitur: value.davalitur, adsoyadkurum: value.AdSoyadKurum, kusuroran: value.KusurOranı, unvan: value.SigortaSirketUnvan, sit: value.SigortaIhbarTarih, tdt: value.TemerruteDusmeTarihi, faizorani: value.faizorani , odemeyapanselectval: value.OdemeyiYapanKurum, odemeyapilandavaci: value.davaciturstring, odemetarih: value.loadOdemeTarihi, odemetutar: value.loadOdemeTutari , guvenceodemetarih: value.loadGuvenceOdemeTarihi, guvenceodemetutar: value.loadGuvenceOdemeTutar }]; }); createTable(tableData); }, error: function () { alert("DYKT step 4 error"); } }); } //Set Data function createTable(tableData) { if (tableData.length>0) { table.setData(tableData); } } When I call table.setData(tableData) , data is on success but table shows empty. when I click on any title of the table, data displays.(so it is the trigger) but normally table comes out as empty. enter image description here enter image description here 2
This is happening because the table was not visible when the data was loaded into the table. You need to call the redraw function on the table when you make it visible. table.redraw();
Populate an iggrid combo box column on demand inside Editor dialog
I am attempting to load an editor dialog that contains a combo box. The combo box should be populated onload. the problem is that the combobox datasource doesn't get loaded the same time as the grid and when the data is finally fully populated from service the data is not intialized and displays an empty drop down list. I want to update the combobox columnSettings datasource when my data is returned from service. I tried populating the combo box on the editRowStarted event? This worked but not for the initial display of the combo box. <script> var userDirectoryViewModel = #Html.Raw(Json.Encode(#Model)); </script> <script id="dialogTemplate" type="text/html"> <div class="row-edit-dialog-container-head"><strong>${Name}</strong></div> <div class="row-edit-dialog-container-cols"> <div style="float: left;"> <table> <colgroup> <col style="width: 30%;" /> <col style="width: 70%;" /> </colgroup> <tbody data-render-tmpl="true"></tbody> </table> <button>Select</button> </div> #*<div style="width: 160px; float: right;"> <img width="100" height="90" src="${ImageUrl}" alt="${Name}" title="${Name}" style="float:right;" /> </div>*# </div> </script> <script id="editorsTemplate" type="text/html"> <tr> <td style="text-align:right;color:#777;"><strong>${headerText}</strong></td> <td><input data-editor-for-${key}="true" /></td> </tr> </script> <script type="text/javascript"> var mappingTypeList = [ { Name: "GrantAdministratorRole", Number: "0" }, { Name: "GrantSupervisorRole", Number: "1" }, { Name: "MapToUserGroup", Number: "2" }, { Name: "MapToTeam", Number: "3" } ]; //load on demand. var mapToTeamList = []; var mapToUserGroupList = []; //Formatting for igGrid cells to display igCombo text as opposed to igCombo value function formatMappingTypeCombo(val) { var i, mappingType; for (i = 0; i < mappingTypeList.length; i++) { mappingType = mappingTypeList[i]; if (mappingType.Number == val) { val = mappingType.Name; } } return val; } function formatMapToUserGroupCombo(val) { var i, userGroup; for (i = 0; i < mapToUserGroupList.length; i++) { userGroup = mapToUserGroupList[i]; if (userGroup.UserGroupID == val) { val = userGroup.Name; } } return val; } function formatMapToTeamCombo(val) { var i, team; for (i = 0; i < mapToTeamList.length; i++) { team = mapToTeamList[i]; if (team.Number == val) { val = team.Name; } } return val; } function populateUserDirectoryMappings() { console.log("calling populateUserDirectoryMappings()"); $.ajax({ type: "GET", url: '/userdirectory/GetUserDirectoryMappings', dataType: "json", success: function (childData) { mapToUserGroupList = childData.UserGroups; mapToTeamList = childData.Teams; return childData; }, error:function() { alert("error"); } }).done(function(data) { mapToUserGroupList = data.UserGroups; }); } function getUserGroups() { var data = populateUserDirectoryMappings(); return data.UserGroups; } $( function () { $("#groupMappingTable") .igGrid({ dataSource: userDirectoryViewModel.GroupMappings, primaryKey: "UserDirectoryGroupID", width: "85%", autoCommit: true, autoGenerateColumns: false, localSchemaTransform: false, columns: [ { headerText: "UserDirectoryGroupID", key: "UserDirectoryGroupID", dataType: "number", hidden: true }, { headerText: "UserDirectoryID", key: "UserDirectoryID", dataType: "number", hidden: true }, { headerText: "OrganizationID", key: "OrganizationID", dataType: "number", hidden: true }, { headerText: "ExternalGroup", key: "Name", dataType: "string" }, { headerText: "MappingType", key: "MappingType",formatter: formatMappingTypeCombo,width: "20%" }, { headerText: "MapToUserGroup", key: "MapToUserGroup",formatter: formatMapToUserGroupCombo,width: "20%" }, { headerText: "MapToTeam", key: "MapToTeam",formatter: formatMapToTeamCombo,width: "20%" } ], rendered: function (evt, ui) { }, features: [ { name: "Updating", enableAddRow: true, enableDeleteRow: true, editMode: "dialog", columnSettings: [ { columnKey: "OrganizationID", readOnly: true }, { columnKey: "MappingType", required:true, editorType:"combo", editorOptions: { mode:"dropdown", dataSource:mappingTypeList, textKey:"Name", valueKey:"Number" } }, { columnKey: "MapToUserGroup", required:false, editorType:"combo", editorOptions: { mode:"dropdown", id: 'mapToUserGroupComboID', dataSource: mapToUserGroupList, textKey:"Name", valueKey:"UserGroupID" } }, { columnKey: "UserDirectoryID", readOnly: true }, { columnKey: "UserDirectoryGroupID", readOnly: true } ], rowEditDialogOptions: { width: "530px", height: "410px", dialogTemplateSelector: "#dialogTemplate", editorsTemplateSelector: "#editorsTemplate", showReadonlyEditors: false }, rowAdding: function (evt, ui) { ui.values["OrganizationID"] = userDirectoryViewModel.OrganizationID; ui.values["UserDirectoryID"] = userDirectoryViewModel.UserDirectoryID; }, rowAdded: function (evt, ui) { console.log("row added event"); var ds = $("#groupMappingTable").igGrid("option", "dataSource"); }, editRowStarted: function(evt, ui) { }, editRowEnded: function (evt, ui) { //alert(ui.rowId); } } ] }); }); </script>
I found the answer here api documentation and I was then able to call into the grid and get the columnSettings object upon successfully retrieving the combo box data from the server. function populateUserDirectoryMappings() { console.log("calling populateUserDirectoryMappings()"); $.ajax({ type: "GET", url: '/userdirectory/GetUserDirectoryMappings', dataType: "json", success: function(childData) { mapToUserGroupList = childData.UserGroups; mapToTeamList = childData.Teams; return childData; }, error: function() { alert("error"); } }).done(function(data) { console.log("done"); console.log(data); mapToUserGroupList = data.UserGroups; var grid = $('#groupMappingTable').data('igGridUpdating'); var updating = grid.options.columnSettings; console.log(updating); console.log("map to user group list"); console.log(mapToUserGroupList); $.each(updating, function(index, data) { console.log("column"); console.log(data); if (data.columnKey == "MapToUserGroup") { data.editorOptions.dataSource = mapToUserGroupList; } }); }); }
JqGrid - Rendering Issue
I'm using JqGrid in my ASP.NET MVC application using VS2010.My Grid does not seem to render properly on my view and does not allow me to access other controls(including entire page) on the view. See the screen blow: Grid With Rows in it: Grid Without Any Row: But once I modify and submit data back to controller inline editing enter page becomes accessible. My Script: var last_selected_row; $(function () { var outerwidth = $('#studentList').width() - 10; ////Keep Grid 10 pixel smaller than its parent container $('#studentGrid').jqGrid({ // Ajax related configurations //url to send request to url: "/Registration/LoadStudents", datatype: "json", mtype: "POST", // Specify the column names colNames: ["StudentID", "StudentName", "Status", "Grades", "StartDate", "EndDate", "EarnedDate", "DroppedDate"], // Configure the columns colModel: [ { name: "StudentID", index: "StudentID", width: 0, align: "left", key: true }, { name: "StudentName", index: "StudentName", editrules: { required: true, integer: false }, width: 100, title: "Name", align: "left", editable: true, stype: 'text', sortable: true }, { name: "Status", index: "Status", width: 70, align: "left", editable: true, edittype: "checkbox", editoptions: { value: "true:false"} }, { name: "Grades", index: "Grades", width: 80, align: "left", editable: true, edittype: "select", editoptions: { dataUrl: "/Registration/GetAllGrades", buildSelect: function (data) { //var d = $.parseJSON(data); var jqGridAssemblyTypes = $.parseJSON(data); var s = '<select>'; if (jqGridAssemblyTypes && jqGridAssemblyTypes.length) { for (var i = 0, l = jqGridAssemblyTypes.length; i < l; i++) { var ri = jqGridAssemblyTypes[i]; s += '<option value="' + ri.Value + '">' + ri.Text + '</option>'; } } return s + "</select>"; }, dataInit: function (elem) { var v = $(elem).val(); ////Set other column value here }, dataEvents: [{ type: 'change', fn: function (e) { var assemblyType = $(e.target).val(); //var rowId = getRowId($(this)); } }] } }, { name: "StartDate", editable: true, editrules: { edithidden: false }, editoptions: { dataInit: function (element) { SetFieldReadOnly(element); } } , index: "StartDate", width: 100, align: "left", formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' } }, { name: "EndDate", editable: true, editrules: { edithidden: false }, editoptions: { dataInit: function (element) { $(element).attr("readonly", "readonly"); } }, index: "EndDate", title: "Ended", width: 100, align: "left", formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' } }, { name: "EarnedDate", editable: true, editrules: { edithidden: false }, editoptions: { dataInit: function (element) { $(element).attr("readonly", "readonly"); } }, index: "EarnedDate", title: "Earned", width: 100, align: "left", formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' } }, { name: "DroppedDate", editable: true, editrules: { edithidden: false }, editoptions: { dataInit: function (element) { $(element).attr("readonly", "readonly"); } }, index: "DroppedDate", title: "Dropped", width: 100, align: "left", formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' } }], // Grid total width and height //width: 300, //height: 200, //autowidth: true, height: '100%', altRows: true, shrinkToFit: false, //forceFit: true, gridview: true, //width: 600, // Paging toppager: false, pager: $("#studentGridPager"), rowNum: 5, rowList: [5, 10, 20], viewrecords: true, // Default sorting sortname: "StudentID", sortorder: "asc", ajaxRowOptions: { contentType: "application/json", dataType: "json" }, serializeRowData: function (data) { return JSON.stringify({ registrationModel: data }); }, ondblClickRow: function (StudentId) { StudentDoubleClicked(StudentId); }, // Grid caption editurl: "/Registration/EditStudents", jsonReader: { repeatitems: false }, caption: "Students" }).setGridWidth(outerwidth); function bindAllGrades() { var dataString = ''; var grades = new Array(); $.getJSON("/Registration/GetAllGrades", null, function (data) { if (data != null) { $.each(data, function (i, item) { grades.push("{\"Text\":\"" + item.Text + "\",\"Value\":\"" + item.Value + "\"}"); dataString += "{\"Text\":\"" + item.Text + "\",\"Value\":\"" + item.Value + "\"},"; }); dataString = dataString.slice(0, -1); } }); var jstrin = JSON.stringify(grades); return grades; } function StudentDoubleClicked(StudentId) { var $myGrid = $("#studentGrid"); if (StudentId && StudentId != last_selected_row) { $myGrid.jqGrid('restoreRow', last_selected_row); $myGrid.jqGrid('saveRow', StudentId, { successfunc: function (response) { alert('Row is Saved !!!'); return true; } }, '/Registration/EditStudents', { extraparam: { StudentID: function () { var sel_id = $myGrid.jqGrid('getGridParam', 'selrow'); var value = $myGrid.jqGrid('getCell', sel_id, 'StudentID'); return stId; }, StudentName: getSavedMathValue(StudentId), Status: function () { var sel_id = $myGrid.jqGrid('getGridParam', 'selrow'); var value = $myGrid.jqGrid('getCell', sel_id, 'Status'); return value; } } }, function () { alert('This is After save.') }, function () { alert('Error while saving data.') }, reload); $myGrid.jqGrid('editRow', StudentId, true); last_selected_row = StudentId; } } function getSavedMathValue(stId) { var mval = $('#' + stId + "_StudentName"); return mval.val(); } function SetFieldReadOnly(Ele) { $(Ele).attr("readonly", "readonly"); } }) function reload(rowid, result) { alert("This is Reload " + Result); $("#studentGrid").trigger("reloadGrid"); } My View: <%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SISShsmMvc.Models.RegistrationModel>" %> <!DOCTYPE html> <html> <head runat="server"> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> <script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> <script type="text/javascript" src="../../Scripts/jquery.jqGrid.js"></script> <script type="text/javascript" src="../../Scripts/jquery.jqGrid.locale-en.js"></script> <%: Scripts.Render("~/bundles/autocomplete")%> <script type="text/javascript" src="../../Scripts/Registration.js"></script> </head> <body> <div> <fieldset> <legend>Search Student By</legend> <div id="studentSearch"> <span>Name:</span><br /> <%= Html.TextBoxFor(m => m.StudentName, new { ID = "StudentName" })%><br /> <span>Grade:</span><br /> <%= Html.DropDownListFor(m => m.SelectedGrade, Model.AvailableGrades) %><br /> </div> </fieldset> <div id="studentList"> <table id="studentGrid"> </table> <div id="studentGridPager" /> </div> </div> </body> </html> My Controller: public ActionResult Index() { PopulateUserContextViewBags(); List<string> grades = new List<string>(); grades.Add("Grades 11 and 12"); grades.Add("Grades 12"); grades.Add("Grades 11"); grades.Add("Grades 10"); grades.Add("All Grades"); // TODO: Models.RegistrationModel model = new Models.RegistrationModel() { AvailableGrades = new SelectList(grades, "Grades 11 and 12") }; return View(model); } public ActionResult LoadStudents() { var objmodel = Models.RegistrationRepository.GetStudents(); return Json(objmodel, JsonRequestBehavior.AllowGet); //return Json(null, JsonRequestBehavior.AllowGet); } public JsonResult EditStudents(Models.RegistrationModel registrationModel) { // registrationModel.StudentID = id; return Json(null, JsonRequestBehavior.AllowGet); } I'm using JqGrid 4.5.1. I've tested this code in IE9 and Firefox 22.0. Any help ??
I solved it by adding ui.jqgrid.css to my view: This is how my view looks now: " %> <!DOCTYPE html> <html> <head runat="server"> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> <script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> <script type="text/javascript" src="../../Scripts/jquery.jqGrid.js"></script> <script type="text/javascript" src="../../Scripts/jquery.jqGrid.locale-en.js"></script> <!-- Newly added .css solved the problem --> <link rel="Stylesheet" type="text/css" href="../../Content/ui.jqgrid.css" /> <%: Scripts.Render("~/bundles/autocomplete")%> <script type="text/javascript" src="../../Scripts/Registration.js"></script> </head> <body> <div> <fieldset> <legend>Search Student By</legend> <div id="studentSearch"> <span>Name:</span><br /> <%= Html.TextBoxFor(m => m.StudentName, new { ID = "StudentName" })%><br /> <span>Grade:</span><br /> <%= Html.DropDownListFor(m => m.SelectedGrade, Model.AvailableGrades) %><br /> </div> </fieldset> <div id="studentList"> <table id="studentGrid"> </table> <div id="studentGridPager" /> </div> </div> </body> </html> Hope this will help someone in future!