Dataitem selection undefined for multiple grids on the same page - javascript

I am trying to double click, in onChange function, on the in progress grid to open a kendoWindow share on two grids on the same page but it does not open. When looking at the console, it gives error below relating to my inprogress grid, however, i can see data items in the actual grid. How should I go about to fix?
Uncaught TypeError: dataItem is undefined
Declaration
$(document).ready(function () {
getdata(que = 0);
$('#subform').hide(); $('#upd').hide();
getdata(que = 1);
});
GetData function
function getdata(que) {
//console.log('que is:',que);
if(que==0){
// console.log('your in queue 0');
var remoteDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "triage_inv/get?id=0",
dataType: "json"
},
sort: { field: "open_dt_tm", dir: "asc"},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return {
models: kendo.stringify(options.models)
};
}
}
},
pageSize: 20,
page: 1
});
}else if(que==1){
//console.log('your in queue 1');
var remoteDataSource1 = new kendo.data.DataSource({
transport: {
read: {
url: "triage_inv/get?id=1",
dataType: "json"
},
sort: { field: "open_dt_tm", dir: "asc"},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return {
models: kendo.stringify(options.models)
};
}
}
},
pageSize: 20,
page: 1
});
}
InProgress grid object
$('#inprogress').kendoGrid({
dataSource: remoteDataSource,
height: 300,
editable: "popup",
change: onChange,
sortable: true,
resizable: true,
selectable: true,
toolbar: ["excel"],
excel: {
...
Backlog grid object
$('#backlog').kendoGrid({
dataSource: remoteDataSource1,
height: 400,
editable: "popup",
change: onChanger,
sortable: true,
resizable: true,
selectable: true,
toolbar: ["excel"],
excel: {
onChanger function
function onChanger(e) {
var rows1 = e.sender.select();
rows1.each(function (e) {
var grid1 = $("#backlog").data("kendoGrid");
grid1.tbody.find("tr").unbind().dblclick(function(e) {
var dataItem1 = grid1.dataItem(this);
//getsimilarscripts(searchData);
var sr_num1 = dataItem1.ticket_number;
myWindow.data("kendoWindow").open();
onChange function
function onChange(e) {
var rows = e.sender.select();
rows.each(function (e) {
var grid = $("#inprogress").data("kendoGrid");
// Double click to retrieve ticket detail
grid.tbody.find("tr").unbind().dblclick(function(e) {
console.log('inprogress grid >',grid.currentRow().dataItem(this));
var dataItem = grid.dataItem(this);
//getsimilarscripts(searchData);
var sr_num = dataItem.ticket_number;
myWindow.data("kendoWindow").open();

I removed the following if/else if conditions and it is working like a champ.
...
if(que==0){
...
}else if(que==1){

Related

How can i define databound in KendoUI Grid , syntax is very confusing?

I have a Kedno-Grid , with details below:
This is the data source:
var data = $scope.salesgroups;
var dataSource = new kendo.data.DataSource({
//data: data,
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: {
Name: { type: "string" }
}
}
}
});
Var grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
navigatable: true,
editable: {
createAt: "bottom"
},
toolbar: ["save", "cancel", "create"],
columns: ["Name"]
}).data("kendoGrid")
The below code is for adding a new row when the user clicks on tab on the last row of the grid.
grid.tbody.on('keydown', function (e)
{
if (e.keyCode == 9)
{
if ($(e.target).closest('td').is(':last-child') && $(e.target).closest('tr').is(':last-
child')) {
setTimeout(function () {
grid.addRow();
})
}
}
});
Now where do I define the "databound" ? I want to add the following below code which will replace the buttons with font awesome icons instead of create and delete buttons
dataBound: function (e) {
e.sender.tbody.find(".k-grid-edit").each(function (idx, element) {
if (!$scope.validateDisabled)
$(element).remove();
else {
$(element).removeClass("k-button");
$(element).removeClass("k-button-icontext");
}
});
e.sender.tbody.find(".k-grid-Delete").each(function (idx, element) {
if (!$scope.validateDisabled)
$(element).remove();
else {
$(element).removeClass("k-button");
$(element).removeClass("k-button-icontext");
}
});
dataBound is a root property of grid parameters:
var grid = $("#grid").kendoGrid({
dataSource: ...,
scrollable: ...,
navigatable: ...,
editable: ...,
toolbar: ...,
columns: ...,
dataBound: function() {
}
}).data("kendoGrid")

How to set cutom template for kendo grid columns

I need to set Kendo grid action button Icon based on value. My code as follows,
function InitProductServicesGrid() {
var prodServiceDataSource = new kendo.data.DataSource({
transport: {
type: "json",
read:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/GetProductServiceDetailsList",
type: "POST",
contentType: 'application/json',
data: GetAdditonalData,
datatype: "json"
},
update:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/SaveProductService",
type: "POST",
contentType: 'application/json',
datatype: "json"
}
},
schema: {
data: function (result) {
return JSON.parse(result.d);
},
model: {
id: "Id",
fields: {
Id: { type: "int" },
ServiceTime: { type: "string" },
IsActive: { type: "boolean"}
}
}
},
requestEnd: function (e) {
if (e.type === "destroy") {
var grid = $("#productServicesGrid").data("kendoGrid");
grid.dataSource.read();
}
},
error: function (e) {
e.preventDefault();
if (e.xhr !== undefined && e.xhr !== null) {
var messageBody = e.xhr.responseJSON.Message;
ShowGritterMessage("Errors", messageBody, false, '../App_Themes/Default/LtsImages/errorMessageIcon_large.png');
var grid = $("#productServicesGrid").data("kendoGrid");
grid.cancelChanges();
}
},
pageSize: 20,
});
$("#productServicesGrid").kendoGrid({
dataSource: prodServiceDataSource,
sortable: true,
filterable: false,
pageable: true,
dataBound: gridDataBound,
editable: {
mode: "inline",
confirmation: false
},
columns: [
{ field: "Id", title: "", hidden: true },
{
field: "ServiceTime",
title: "Time Standard",
sortable: false,
editor: function (container, options) {
var serviceTimeTxtBox = RenderServiceTime();
$(serviceTimeTxtBox).appendTo(container);
},
headerTemplate: '<a class="k-link" href="#" title="Time Standard">Time Standard</a>'
},
{
title: "Action", command: [
{
name: "hideRow",
click: hideRow,
template: comandTemplate
}
],
width: "150px"
}
]
});
}
I wrote a custom template function as follows,
function comandTemplate(model) {
if (model.IsActive == true) {
return '<a title="Hide" class="k-grid-hideRow k-button"><span class="k-icon k-i-lock"></span></a><a title="Hide"></a>';
}
else {
return '<a title="Show" class="k-grid-hideRow k-button"><span class="k-icon k-i-unlock"></span></a><a title="Show"></a>';
}
}
But when I debug the I saw the following value for model value.
I followed this sample code as well. here you can see, I also set the custom template like the sample code. Please help me to solve this. Why I can't access model IsActive value from comandTemplate function.
Updated
When clicking hideRow action, I access the dataItem as follows.
function hideRow(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if (dataItem.IsActive == true) {
dataItem.IsActive = false;
}
else {
dataItem.IsActive = true;
}
}
Is there any possible way to access data from template function as above or any other way?
I would suggest a different approach because you can't access grid data while rendering and populating grid.
My suggestion is to use two actions and hide it based on the flag (in your case IsActive).
Something like this: Custom command
NOTE: in visible function you can access item!
EDIT: you can access it and change it on dataBound traversing through all data.
Check this example: Data bound
I don't see the advantage of relying on the grid commands. You can render any button you want yourself and and use the dataBound event to bind a click handler:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{
template: function(dataItem) {
const isActive = dataItem.isActive;
return `<a title=${isActive ? "Hide": "Show"} class="k-grid-hideRow k-button"><span class="k-icon k-i-${isActive ? 'lock' : 'unlock'}"></span></a>`
}
}
],
dataBound: function(e) {
e.sender.tbody.find(".k-grid-hideRow").click(evt => {
const row = evt.target.closest("tr")
const dataItem = e.sender.dataItem(row)
dataItem.set("isActive", !dataItem.isActive)
})
},
dataSource: [{ name: "Jane Doe", isActive: false }, { name: "Jane Doe", isActive: true }]
});
Runnable Dojo: https://dojo.telerik.com/#GaloisGirl/eTiyeCiJ

Handsontable Select2 Dynamic Options

I am using handsontable with the select2 editor but I cannot seem to make dynamic options work with the dropdown menu, i.e. the options set at the the time of the handsontable initialisation are the only options that ever seem to show.
I have tried using a global variable as the source of the options and updating that at various points in my code and also using a function to return the same variable but neither attempt seems to work.
e.g.
var hot;
var data = [];
function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) {
if (instance.getCell(row, col)) {
$(instance.getCell(row,col)).addClass('select2dropdown');
}
var selectedId;
var colOptions = cellProperties.select2Options.data;
if (colOptions != undefined) {
for (var index = 0; index < colOptions.length; index++) {
if (parseInt(value) === colOptions[index].id) {
selectedId = colOptions[index].id;
value = colOptions[index].text;
}
}
Handsontable.TextCell.renderer.apply(this, arguments);
}
}
var requiredText = /([^\s])/;
$(document).ready(function(){
var
$container = $("#example1"),
$parent = $container.parent(),
autosaveNotification;
hot = new Handsontable($container[0], {
columnSorting: true,
stretchH: 'all',
startRows: 8,
startCols: 5,
rowHeaders: true,
colHeaders: ['Description', 'Cost', 'Remarks'],
columns: [
{ data: 'description' },
{
data: 'cost',
editor: 'select2',
renderer: customDropdownRenderer,
select2Options: { data: getData(), dropdownAutoWidth: true }
},
{ data: 'remarks' },
],
minSpareCols: 0,
minSpareRows: 1,
contextMenu: true,
data: []
});
data = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
});
function getData() {
return data;
}
http://jsfiddle.net/zfmdu4wt/27/
You have defined data multiple times and it is causing contention.
The following changes will fix it:
Define the following immediately after the .ready() function:
var source = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
and update the select2Options to the following:
select2Options : { data: source, dropdownAutoWidth: true }
I managed to get it working by re-using some code I had used to solve the same problem with the xeditable plugin.
Here's the updated code:
var hot;
var data = [];
function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) {
if (instance.getCell(row, col)) {
$(instance.getCell(row,col)).addClass('select2dropdown');
}
var selectedId;
var colOptions = cellProperties.select2Options.data;
if (colOptions != undefined) {
for (var index = 0; index < colOptions.length; index++) {
if (parseInt(value) === colOptions[index].id) {
selectedId = colOptions[index].id;
value = colOptions[index].text;
}
}
Handsontable.TextCell.renderer.apply(this, arguments);
}
}
var requiredText = /([^\s])/;
$(document).ready(function(){
var
$container = $("#example1"),
$parent = $container.parent(),
autosaveNotification;
hot = new Handsontable($container[0], {
columnSorting: true,
stretchH: 'all',
startRows: 8,
startCols: 5,
rowHeaders: true,
colHeaders: ['Description', 'Cost', 'Remarks'],
columns: [
{ data: 'description' },
{
data: 'cost',
editor: 'select2',
renderer: customDropdownRenderer,
// select2Options: { data: getData(), dropdownAutoWidth: true }
select2Options: { data: getSource(), dropdownAutoWidth: true, width: 'resolve', initSelection: getInitSel(false), query: getQuery }
},
{ data: 'remarks' },
],
minSpareCols: 0,
minSpareRows: 1,
contextMenu: true,
data: []
});
data = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
});
/*
function getData() {
return data;
}
*/
// New Code
function getSource() {
return data;
};
function getQuery(options) {
options.callback({ results : getSource() });
};
function getInitSel(multiple) {
return function(el, cb) {
var t, toSet = [], sc = getSource();
el[0].value.split(',').forEach(function(a) {
for (var i = 0; i < sc.length; i++) {
if (sc[i].id == Number(a.trim())) {
t = sc[i];
}
}
// or, if you are using underscore.js
// t = _.findWhere(sc, { id : Number(a.trim()) });
if(t) toSet.push(t);
});
cb(multiple ? toSet : (toSet.length ? toSet[0] : null));
};
};
and a fiddle for demonstration - http://jsfiddle.net/zfmdu4wt/38/

Kendo UI Grid with custom resize event won't display detail template in Internet Explorer

I have a Kendo UI Grid that displays n-child records, that I also have a custom resize function that keeps the grid sized for the browser window height. If I remove that resizeListener, the child records display as appropriate. If I have the resizeListener bound, the child records do not display.
This issue is specific to Internet Explorer 8 (sorry, it's a company policy limitation). The grid functions normally in Firefox.
I have tried using $(window).off("resize") when I activate the child template, in the databound, and in really a variety of random places that I thought might possibly work - but nothing so far.
I'm looking for a solution or a work-around for IE.
Here is the function:
function resizeGrid() {
var gridElement = $("#boxesgrid");
var dataArea = gridElement.find(".k-grid-content");
var newGridHeight = $(document).height() > 850 ? 850 : $(document).height() * .75;
var newDataAreaHeight = newGridHeight * .7;
dataArea.height(newDataAreaHeight);
gridElement.height(newGridHeight);
gridElement.data("kendoGrid").refresh();
}
var resizeListener = function () {
$(window).one("resize", function () {
resizeGrid();
setTimeout(resizeListener, 500);
});
};
Here is the html:
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">Line of Business</div>
<div class="panel-body" id="lobnav"></div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Application</div>
<div class="panel-body" id="lobapp"></div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Filter</div>
<div class="panel-body" id="jobfilter">
</div>
</div>
</div>
<div class="col-md-10">
<div id="boxesgrid"></div>
</div>
Here is the rest of the javascript/kendo code:
$(document).ready(function () {
resizeListener();
var isParent, appId, lobId, boxId;
var apiUrl = '#ViewBag.ApiUrl';
var lobDataSource = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl + "Lob"
}
},
schema: {
model: {
id: "LobId",
hasChildren: "HasChildren"
}
}
});
var appsDataSource = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl + "App"
},
parameterMap: function (data, action) {
if (action === "read") {
data.lobid = lobId;
data.parent = isParent;
return data;
} else {
return data;
}
}
}
});
var filterDataSource = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl + "Theme"
}
},
schema: {
model: { id: "FilterId" }
}
});
var boxesDataSource = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl + "Process"
},
parameterMap: function (data) {
data.appid = appId;
data.parent = isParent;
data.lobid = lobId;
return kendo.stringify(data);
}
},
schema: {
data: "Data",
total: "Total",
model: { id: "JobId" }
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
var lobnav = $("#lobnav").kendoTreeView({
select: function (e) {
var tree = this;
var src = tree.dataItem(e.node);
lobId = src.LobId;
isParent = src.HasChildren;
},
change: function (e) {
appsDataSource.read();
},
dataSource: {
transport: {
read: {
url: apiUrl + "Lob"
}
},
schema: {
model: {
id: "LobId",
hasChildren: "HasChildren"
}
}
},
loadOnDemand: false,
dataTextField: "LobName"
});
var appnav = $("#lobapp").kendoListView({
selectable: "single",
autoBind: false,
change: function () {
var idx = this.select().index();
var itm = this.dataSource.view()[idx];
appId = itm.AppId;
boxesDataSource.query({
page: 1,
pageSize: 35
});
},
template: "<div class='pointercursor'>${AppName}</div>",
dataSource: appsDataSource
});
var jobsfilter = $("#jobfilter").kendoListView({
selectable: "single",
loadOnDemand: false,
template: "<div class='pointercursor' id=${FilterId}>${FilterName}</div>",
dataSource: filterDataSource,
dataBound: function () {
var dsource = $("#jobfilter").data("kendoListView").dataSource;
if (dsource.at(0).FilterName !== "All") {
dsource.insert(0, { FilterId: 0, FilterName: "All" });
}
},
change: function () {
var itm = this.select().index(), dataItem = this.dataSource.view()[itm];
var appDs = appsDataSource.view(), apps = $("#lobapp").data("kendoListView"),
selected = $.map(apps.select(), function (item) {
return appDs[$(item).index()].AppName;
});
if (selected.length > 0) {
if (dataItem.FilterId !== 0) {
var $filter = new Array();
$filter.push({ field: "JobStatusId", operator: "eq", value: dataItem.FilterId });
jgrid.dataSource.filter($filter);
} else {
jgrid.dataSource.filter({});
}
}
}
});
var jgrid = $("#boxesgrid").kendoGrid({
columns: [
{
field: "AppName",
title: "App"
},
{
field: "JobId",
title: "Job Id"
},
{
field: "JobName",
title: "Job Name",
},
{
field: "JobStatus",
title: "Status"
},
{
field: "JobStatusId",
title: "Status Code"
},
{
field: "HasChildren",
title: "Has Children"
},
{
field: "ChildrenCount",
title: "Child Jobs"
}
],
sortable: {
mode: "single",
allowUnsort: true
},
pageable: {
pageSizes: [35],
numeric: true,
refresh: true,
pageSize: 35
},
autoBind: false,
scrollable: true,
resizable: true,
detailInit: detailInit,
dataSource: boxesDataSource
}).data("kendoGrid");
function detailInit(e) {
var eventData = e;
$.ajax({
url: apiUrl + "ProcessJobs",
type: "POST",
data: {BoxId: e.data.JobId, AppId: e.data.AppId},
dataType: "json",
success: function(data, status, xhr) {
initializeDetailGrid(eventData, data);
}
});
};
function initializeDetailGrid(e, result) {
var moreChildren = result[0].HasChildren;
var gridBaseOptions = {
dataSource: result,
scrollable: false,
sortable: true,
columns: [
{
field: "ParentJobId",
title: "Parent Job"
},
{
field: "JobId",
title: "Job Id"
},
{
field: "JobName",
title: "Job Name",
},
{
field: "JobStatus",
title: "Status"
},
{
field: "JobStatusId",
title: "Status Code"
},
{
field: "HasChildren",
title: "Has Children"
},
{
field: "ChildrenCount",
title: "Child Jobs"
}
]
};
var gridOptions = {};
if (moreChildren) {
gridOptions = $.extend({}, gridBaseOptions, { detailInit: detailInit });
} else {
gridOptions = gridBaseOptions;
};
$("<div/>").appendTo(e.detailCell).kendoGrid(gridOptions);
};
});
The resize function needed to be changed. The error was calling refresh on the grid, rather than resize. The corrected function looks like:
function resizeGrid() {
var gridElement = $("#boxesgrid");
var newGridHeight = $(window).height() > 800 ? 800 : $(document).height() * .75;
gridElement.height(newGridHeight);
gridElement.data("kendoGrid").resize();
}
Setting the data area separately was incorrect, as well.

Type Error when trying to preserve filter state - Kendo UI Grid

I'm working with Kendo UI's Grid and attempting to add some code which preserves the grid's filter/grouping/etc by way of a cookie. It works in the example, but not at all in my code.
Example: http://www.kendoui.com/code-library/web/grid/preserve-grid-state-in-a-cookie.aspx
My Code: http://jsfiddle.net/PwajE/
For whatever reason (I'm sure it's a simple one) I keep getting type errors. Two hours later... here I am.
As always, any help is appreciated.
#RRfive
<script>
var data = [{"name":"John Smith","email":"test#test.com","permission":"admin","costRate":"60","dt":"2013-02-02 10:26:29","memberID":"M0000001"},{"name":"Test Simple","email":"test#jones.com","permission":"user","costRate":"40","dt":"2013-02-02 00:00:00","memberID":"M0000002"}];
$(document).ready(function() {
$("#grid").kendoGrid({
dataSource: {
data: data,
//transport: {
// read: "assets/data/data.users.php",
//},
schema: {
data: function(result) {
return result.data || result;
},
total: function(result) {
var data = this.data(result);
return data ? data.length : 0;
},
model:{
id:"memberID",
fields:{
dt:{ type:"date" },
costRate:{ type:"number" }
}
}
},
pageSize: 10,
},
sortable: {
mode: "single",
allowUnsort: true,
},
pageable: {
input: true,
numeric: false
},
reorderable: true,
resizable: true,
filterable: {
extra:false,
operators: {
string:{
contains: "Contains",
}
}
},
columnMenu: false,
groupable: true,
dataBound: function(e){
var grid = this;
var dataSource = this.dataSource;
var state = kendo.stringify({
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort(),
group: dataSource.group(),
filter: dataSource.filter()
});
$.cookie("employeesState",state);
if($.cookie('empRows')){
$.each(JSON.parse($.cookie('empRows')),function(){
var item = dataSource.get(this);
var row = grid.tbody.find('[data-uid='+item.uid+']');
row.addClass('k-state-selected');
})
}
},
change:function(){
var grid = this;
var ids = grid.select().map(function(){
return grid.dataItem($(this)).Id
}).toArray();
$.cookie('empRows',JSON.stringify(ids));
},
columns: [
{ field: "name", title:"Name" },
{ field: "email", title:"Email/Username" },
{ field: "costRate", title:"Cost Rate (p/hr)", template: '#= kendo.toString(costRate, "c") #', },
{ field: "permission", title:"Permission", template: "#= (permission == 'admin') ? 'Administrator' : 'User' #" },
{ field: "dt", title:"Registered", template: '#= kendo.toString(dt,"d-M-yyyy") #' },
{ field: "memberID", title:" ", width: "83px", filterable: false, sortable: false, template: '<a class="k-button k-button-icontext k-grid-edit" href="manage_admin.php?form=editMember&ID=#= kendo.toString(memberID, "n2")#"><span class=\"k-icon k-edit\"></span>Edit</a>'},
]
});
var state = JSON.parse($.cookie("employeesState"));
if(state){
if(state.filter){
parseFilterDates(state.filter, grid.dataSource.options.schema.model.fields);
}
grid.dataSource.query(state);
}
else{
grid.dataSource.read();
}
});
function parseFilterDates(filter, fields){
if(filter.filters){
for(var i = 0; i < filter.filters.length; i++){
parseFilterDates(filter.filters[i], fields);
}
}
else{
if(fields[filter.field].type == "date"){
filter.value = kendo.parseDate(filter.value);
}
}
}
</script>
If you debug that fiddle you would see that the following line throws the error:
grid.dataSource.query(state);
The reason for this is that grid is not an instance of Kendo Grid but the div elemen with id='grid'. The fix is simple - initialize the grid variable prior to using it:
var grid = $("#grid").data('kendoGrid');
grid.dataSource.query(state);

Categories