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

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);
}

Related

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;
}

My kendo chart is not updating

I Have kendo chart and tree-view in my application.I want to to change the value axis dynamically on check-box checked event,example When we check the "KM" check-box in treeview then value axis for Km and data will be displaying in chart.
so I tried some code then my chart is not displaying.
My checked event code is
$("#treeview").on("change", function (e) {
var chart = $("#chart").data("kendoChart");
var checkedSeries = [];
$("#treeview").find(":checked").each(function() {
var nodeText = $(this).parent().parent().text();
$.each(valueAxes, function(index, valueAxes) {
if (valueAxes.field == nodeText) {
checkedSeries.push(valueAxes);
}
});
});
chart.options.valueAxes = checkedSeries;
chart.refresh();
});
What's wrong in my code please help me.
Here is my jsbin http://jsbin.com/eyibar/11/edit
First you need to assign the chart to a variable in on-change event event of tree view,without that the tree-view didn't recognize the chart and it's value axis and in your valueAxes code there is no property of field,so by name of the valueAxes you need to check the treeview node and then push the valueAxes.
$("#treview").on("change", function (e) {
var chart = $("#chart").data("kendoChart");
var checkedSeries = [];
if ($("#treeview").find(":checked").length !== 0) {
$("#treeview").find(":checked").each(function () {
var nodeText = $(this).parent().parent().text();
$.each(valueAxes, function (index, valueAxes) {
if (valueAxes.name == nodeText) {
checkedSeries.push(valueAxes);
checkedSeries.visible = true;
}
});
});
createChart(checkedSeries);
}
else {
createChart(checkedSeries);
}
});

using $.getJSON my links contains %0A+++++ characters

I am try to get the values from the selected row and pass them through $.getJSON as parameters. I can get the value, however, when I click on the link strange characters appear before and after the value. The character in the link appears as %OA++++++++++value+++++++%0A.
Here is my code
var className='';
var Section='';
$('#listsubject tr').click(function () {
var th = $(this);
var td = $(this).find('td');
$.each(td, function (index, item) {
if (index == 2) className = item.innerHTML;
});
$.getJSON('#Url.Action("getStudentList/","Student")',
{ classname: className
}, function (data) {
alert('test');
});
Kindly help me. Am stuck here
Thanks in advance
EDIT
when i try the code
$.getJSON('#Url.Action("getStudentList/","Student")',
{ classname: className,
section:'A'
}, function (data) {
alert('test');
});
in the link the section part shows fine, only problem is with the classname
UPDATE
fiddle link
http://jsfiddle.net/gordon/vzTDc/2/
Try this. I think its OK now.
var className = '',
Section = '';
// you were trying with $('#listsubject tr'), but first tr has no td
// so click should bind with tr from 2nd
// so correct selector will be $('#listsubject tr:gt(0)')
$('#listsubject tr:gt(0)').click(function() {
var th = $(this);
var td = $(this).find('td');
$.each(td, function(index, item) {
// As you have 2 td with in each row, so the index will be 0 and 1
// not 2 and 3
if (index == 0) {
className = $.trim($(item).text()); // $.trim() will remove spaces
}
if (index == 1) {
Section = $.trim($(item).text());
}
});
console.log('ClassName: ' + className + ', Section: ' + Section);
$.getJSON('StudentMarks/getSubjectGrading', {
classname: className,
section: Section
}, function(data) {
alert(data);
});
});
DEMO

How to highlight the last selected row after client-side sorting on jqGrid?

I've a jqGrid-based application, and I use loadonce: true in the grid option and sortable: true, sorttype: 'text in the colModel to allow client-side sorting on the data grid. However, I found that, once the data grid is re-sorted, the last selected row will no longer be highlighted. My question is, how to keep the selected row being highlighted across data resorting?
I prepared for you the small demo which keeps the row selection. In the demo I rewrote the code of selectionPreserver used in case of reloadGrid usage having additional parameters: $("#list").trigger("reloadGrid", [{current:true}]);. See the answer for details.
The demo saves the current selection inside of the onSortCol event handler and restore it inside of the loadComplete:
onSortCol: function () {
saveSelection.call(this);
},
loadComplete: function () {
restoreSelection.call(this);
}
How you see the usage is very simple and you can integrate it in your code. The implementation of the saveSelection and restoreSelection is the following:
var lastSelArrRow = [],
lastScrollLeft = 0,
lastSelRow = null,
saveSelection = function () {
var $grid = $(this);
lastSelRow = $grid.jqGrid('getGridParam', 'selrow');
lastSelArrRow = $grid.jqGrid('getGridParam', 'selrow');
lastSelArrRow = lastSelArrRow ? $.makeArray(lastSelArrRow) : null;
lastScrollLeft = this.grid.bDiv.scrollLeft;
},
restoreSelection = function () {
var p = this.p,
$grid = $(this);
p.selrow = null;
p.selarrrow = [];
if (p.multiselect && lastSelArrRow && lastSelArrRow.length > 0) {
for (i = 0; i < lastSelArrRow.length; i++) {
if (lastSelArrRow[i] !== lastSelRow) {
$grid.jqGrid("setSelection", lastSelArrRow[i], false);
}
}
lastSelArrRow = [];
}
if (lastSelRow) {
$grid.jqGrid("setSelection", lastSelRow, false);
lastSelRow = null;
}
this.grid.bDiv.scrollLeft = lastScrollLeft;
};

Resources