KendoUI Treeview Select Node On Databound - kendo-ui

I have a list view I want the user to be able to double click which will change a treeview's datasource and select a treeview node. While I get the ID of the item I want to select, execute the code I think should select the node on the treeview, it does not select. Any thoughts would be appreciated
Listview Double Click Event:
function setItemDoubleClickEvent() {
$(".machineInstances").on("dblclick", function () {
var listView = $("#listView").data("kendoListView");
var idx = $(this).index();
var item = listView.dataSource.view()[idx];
$('#selectedNodeId').val(item.InstanceId);
// Remove the current datasource to remove any existing filtering
$("#treeview").data("kendoTreeView").setDataSource([]);
// Set the hidden input so OnData knows what to highlight
$('#selectedNodeId').val(item.InstanceId);
// Set the new datasource for the tree
$("#treeview").data("kendoTreeView").setDataSource(instanceDataSource); });
}
TreeView Declaration:
var treeview = $("#treeview").kendoTreeView({
dataTextField: "Name"
, select: onSelect,
dataBound: ondata
}).data("kendoTreeView"),
DataBound Function:
function ondata() {
//alert($('#selectedNodeId').val());
var selected = $('#selectedNodeId').val();
if (selected != "") {
var node = treeview.findByUid(selected)
$("#treeview").data("kendoTreeView").select(node);
$('#selectedNodeId').val("");
}
}
Thank you,
Drew

Related

Kendo grid checkbox get last selected value

I have kendo grid with a select option. My question is how do I get ProductName from the last selected row? Example like this. I have tried with this but row is null. Appreciate your help.
FULL DEMO IN DOJO
function onChange(e) {
var rows = e.sender.select();
rows.each(function(e) {
var grid = $("#grid").data("kendoGrid");
var row = $(e.target).closest("tr"); //<-- this value capture null
var dataItem = grid.dataItem(row);
var productName = dataItem.ProductName;
alert(productName);
})
};
You have incorrect parameters in the function in each.
This causes name masking: https://en.wikipedia.org/wiki/Name_resolution_(programming_languages)#Name_masking
At the outer level, you have:
function onChange(e) {
Then, in the third line, you have:
rows.each(function(e) {
That's two functions of e. So which e counts? The inner one masks the outer one.
The correct arguments for the inner function are:
rows.each(function(index, row) {
Now, you're already iterating over rows, so you have the row, you don't need to look for it with any closest().
You also have the grid, it's e.sender, because you're in a grid event.
That gives you the following code:
function onChange(e) {
var rows = e.sender.select();
rows.each(function(index, row) {
console.log(row);
var dataItem = e.sender.dataItem(row);
console.log(dataItem);
var productName = dataItem.ProductName;
console.log(productName);
})
};
Demo
In the future, be wary of the difference between Kendo events and jQuery events.
Just use grid.select() inside grids change function:
function onChange(e) {
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
console.log(selectedItem.ProductName)
};
Example: Get last selected item

Kendo grid button click arguments

I have a kendo grid with a button column. When the button is clicked, I want it to call a javascript function with the row's data as parameters. Here's what I have so far
$(grd).kendoGrid({
dataSource: ds,
detailInit: detailInit,
columns: [ {field: "foo", title: "bar" },
{field: "Y" },
{command: { text: "MyButton", click: doStuff } } ]
});
function doStuff(e)
{
//e is click events but I want to pass in data from the row instead
//following is code I found here but item is null for me
var row = $(this).closest("tr");
var item = $(grd).data("kendoGrid").dataItem(row);
}
This will give you the data pertaining to the row which the button was clicked.
function doStuff(e) {
var tr = $(e.target).closest("tr"); // get the current table row (tr)
var item = this.dataItem(tr); // get the date of this row
alert(item.PropertyName);
}

how to expand the parent nodes of a selected child node on kendo treeview

hi there kendo enthusiast.. i have a little problem on kendo treeview, i manage to expand the selected child node of a treeview if it is a parent, but i can expand it's grand parents, here is my little code:
data.forEach(function (entry) {
var treeView = $("#sysfunc_ktreeview").data('kendoTreeView');
var dataSource = treeView.dataSource;
var dataItem = dataSource.get(entry);
var node = treeView.findByUid(dataItem.uid);
var checkbox = $("input[type='checkbox']", node)[0];
checkbox.click();
});
in this case i am getting the array from a database. but here, i cant expand the parent nodes if there child nodes were checked but there id(the parent) where not in the array. any great help will be much appreciated. this little piece of code is from sir OnaBai.. thanks sir
If you want to click all ancestors of items which id are in data, add the following lines of code:
var ancestors = $(node).parents("li[role='treeitem']");
$(">div>span>input", ancestors).click();
This selects all ancestors of current node an for each of them clicks the input.
So your code should look like:
data.forEach(function (entry) {
var treeView = $("#treeview").data('kendoTreeView');
var dataSource = treeView.dataSource;
var dataItem = dataSource.get(entry);
var node = treeView.findByUid(dataItem.uid);
var checkbox = $("input[type='checkbox']", node)[0];
checkbox.click();
var ancestors = $(node).parents("li[role='treeitem']");
$(">div>span>input", ancestors).click();
});
You can see it running here: http://dojo.telerik.com/#OnaBai/IRom
The best solution I came up with was this:
Highlighted code:
dataBound: function(e){
// expands tree to the selected node
var root = e.node ? $(e.node) : this.element;
// expands only selected checkboxes and parents
this.expand(root.find(".k-item input[type=checkbox]:checked").parents());
},
Full code:
$(".locationTree").kendoTreeView({
loadOnDemand: false,
checkboxes: true,
select: function(e){
e.preventDefault();
},
dataSource: {
type: "json",
data: processTable(flatData, "id", "parent", 0)
},
dataBound: function(e){
// expands tree to the selected node
var root = e.node ? $(e.node) : this.element;
//this.expand(root.find(".k-item")); // expands all
// expands only selected checkboxes and parents
this.expand(root.find(".k-item input[type=checkbox]:checked").parents());
},
});
found a better approach sir #OnaBai
success: function (data) {
$.each(data, function (index, entry) {
var dataSource = treeView.dataSource;
var dataItem = dataSource.get(entry);
if (!dataItem.hasChildren)
{
dataItem.set("checked", true);
}
var node = treeView.findByUid(dataItem.uid);
parents.push(treeView.dataItem(treeView.parent(node)).id);
if (index + 1 == data.length) {
setTimeout(function () {
self.expandParents(parents, treeView);
}, 100);
}
});
setTimeout(function () {
self.filterChange(treeView, data);
}, 100);
}

Remote update cell content in kendo grid

Here I have a code to update a cell contet when pressing a button.
It works fine, but it doesn't set the flag, that indicates, that the cell has been changed.
It should look like this with the litle red triangle:
The code:
<a id="button" href="#">Click me</a>
<div id="grid"></div>
<script>
var dataSource, grid;
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
data: [
{ category: "Beverages", name: "Chai", price: 18},
{ category: "Seafood", name: "Konbu", price: 6}
],
})
grid = $("#grid").kendoGrid({
dataSource: dataSource,
editable: true,
}).data("kendoGrid");
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
});
});
</script>
Update:
Here is the update based on #tstancin: Kendo example.
Thank you for the answer - I had thought of it to.
I am wondering if it's possible to do the update in a more clean way with some binding through som MVVM perhaps?
Kind regards from Kenneth
If that's all you want then you should expand your button click code with the following:
$('#button').click(function (e) {
var data = grid.dataItem("tr:eq(1)");
data.set('category', 'Merchandice');
$("#grid tr:eq(1) td:eq(1)").addClass("k-dirty-cell");
$("#grid tr:eq(1) td:eq(0)").prepend("<span class='k-dirty'></span>");
});
But if you, for instance, manually change the value of name column from Chai to something else, and then click the click me button, the dirty marker in the name column will disappear.
You should use flags for every cell and set them before data.set(). Then, in the grid's dataBound event you should inspect every cell's value and assign the dirty marker if it's needed. For manual changes you should handle the save event and set flags there.
I wrote a script that makes it posible to use a call like this:
SetCellData(id, columnName, value);
So with an id, a columnName and a value, I can update a value in a grid and the flag will be set on the cell.
function SetCellData(id, columnName, value) {
var dataItem = grid.dataSource.get(id);
dataItem.set(columnName, value);
var columnIndex = GetColumnIndex(columnName);
if (columnIndex > -1) {
var cell = $('tr[data-uid*="' + dataItem.uid + '"] td:eq(' + columnIndex + ')')
if (!cell.hasClass("k-dirty-cell")){
cell.prepend("<span class='k-dirty'></span>");
cell.addClass("k-dirty-cell");
}
}
}
function GetColumnIndex(columnName) {
var columns = grid.columns;
for (var i = 0; i < columns.length; i++)
if (columns[i].field == columnName)
return i;
return -1;
};
I have the code here : example

How to programmatically create a new row and put that row in edit mode in Kendo grid

In my Kendo grid I am trying to put the 'create new item' button in the header (title) of the command column instead of the toolbar. Here is part of my grid definition:
var grid = $("#grid").kendoGrid({
columns: [{ command: { name: "edit", title: "Edit", text: { edit: "", cancel: "", update: "" } },
headerTemplate: "<a onclick ='NewItemClick()' class='k-button k-button-icontext k-create-alert' id='new-item-button' title='Click to add a new item'><div>New Item</div></a>"},
My question is: how to create a new row and put that row in edit mode in 'NewItemClick()'
There are some troublesome scope issues when you try to bind the click event in the template definition itself.
Instead, it is easier to assign the link an ID, and then bind the click event later. Notice that I've given it id=create.
headerTemplate: "<a id='create' class='k-button k-button-icontext k-create-alert' id='new-item-button' title='Click to add a new item'><div>New Item</div></a>"
Then in document ready, I bind the click event:
$("#create").click(function () {
var grid = $("#grid").data("kendoGrid");
if (grid) {
//this logic creates a new item in the datasource/datagrid
var dataSource = grid.dataSource;
var total = dataSource.data().length;
dataSource.insert(total, {});
dataSource.page(dataSource.totalPages());
grid.editRow(grid.tbody.children().last());
}
});
The above function creates a new row at the bottom of the grid by manipulating the datasource. Then it treats the new row as a row "edit". The action to create a new row was borrowed from OnaBai's answer here.
Here is a working jsfiddle, hope it helps.
I would like to complete on gisitgo's answer. If your datasource takes some time to update, when calling page(...), then the refresh of the grid will cancel the editor's popup. This is averted by binding the call to editRow to the "change" event :
var grid = $("#grid").data("kendoGrid");
if (grid) {
//this logic creates a new item in the datasource/datagrid
var dataSource = grid.dataSource;
var total = dataSource.data().length;
dataSource.insert(total, {});
dataSource.one("change", function () {
grid.editRow(grid.tbody.children().last());
});
dataSource.page(dataSource.totalPages());
}
NB: This approach will yield problems if your grid is sorted because the new row will not necessarily be at the end
I have found that issues might appear if you have multiple pages, such as the inserted row not opening up for edit.
Here is some code based on the current index of the copied row.
We also edit the row based on UID for more accuracy.
function cloneRow(e) {
var grid = $("#grid").data("kendoGrid");
var row = grid.select();
if (row && row.length == 1) {
var data = grid.dataItem(row);
var indexInArray = $.map(grid.dataSource._data, function (obj, index)
{
if (obj.uid == data.uid)
{
return index;
}
});
var newRowDataItem = grid.dataSource.insert(indexInArray, {
CustomerId: 0,
CustomerName: null,
dirty: true
});
var newGridRow = grid.tbody.find("tr[data-uid='" + newRowDataItem.uid + "']");
grid.select(newGridRow);
grid.editRow(newGridRow);
//grid.editRow($("table[role='grid'] tbody tr:eq(0)"));
} else {
alert("Please select a row");
}
return false;
}

Resources