kendo ui, update an array of objects - kendo-ui

I am trying to simply update an object inside of an array, then update that array so that the data goes back to the view. After updating my object, and setting the array I am not seeing changes in the ui. Any thoughts?
sortTableColumn, is a click vent in the view, and thTitles is set using data-bind, I know that both are working because if I change the initial state of thTitles.sortClassName : "something", I will see that something in the ui.
var viewModel = kendo.observable({
sortTableColumn: function(e) {
this.thTitles[1].sortClassName = "icon fa-sort-down";
console.log(this.thTitles);
var titles = this.thTitles;
this.set("thTitles", titles);
},
thTitles: [
{ displayName: "Name", dataName: "name", sortDirection: 0, sortClassName:"" },
{ displayName: "Price", dataName: "price", sortDirection: 0, sortClassName: ""},
{ displayName: "Units", dataName: "unitsInStock", sortDirection: 0, sortClassName: ""}
],
});
kendo.bind($("#tableSortable"), viewModel);

Try this.
var viewModel = kendo.observable({
sortTableColumn: function(e) {
this.get("thTitles")[1].set("sortClassName", "icon fa-sort-down");
},
thTitles: [
{ displayName: "Name", dataName: "name", sortDirection: 0, sortClassName:"" },
{ displayName: "Price", dataName: "price", sortDirection: 0, sortClassName: ""},
{ displayName: "Units", dataName: "unitsInStock", sortDirection: 0, sortClassName: ""}
],
});
kendo.bind($("#tableSortable"), viewModel);

Related

Kendo Grid disable field during Edit mode

Using kendo grid edit event I want to disable field name and id during Edit mode. I manage to disable id by following this example here. But went I try to disable name seem it not working, any thought how to do this?
WORKING DEMO IN DOJO
$("#grid").kendoGrid({
columns: [
{ field: "id" },
{ field: "name" },
{ field: "age" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema: {
model: {
id: "id",
fields: {
"id": { type: "number" },
"name": { type: "string" }
}
}
}
},
editable: "inline",
toolbar:["create"],
edit: function(e) {
if (!e.model.isNew()) {
var numeric = e.container.find("input[name=id]").data("kendoNumericTextBox");
numeric.enable(false);
//var x = e.container.find("input[name=name]").data("kendoTextBox");
//x.enable(false);
//$("input[name=name]").prop("disabled", true).addClass("k-state-disabled");
//$("input[name=name]").editable = false;
}
}
});
by using editable function i created this
function isEditable(e){
var dataSource = $("#grid").data("kendoGrid").dataSource;
return (e.id == null || e.id == '');
}
and add this into the grid > column
columns: [
{ field: "id", editable: isEditable },
{ field: "name", editable: isEditable },
{ field: "age" },
{ command: "edit" }
],
Full working demo is here

Kendo Grid doesn't show any data despite having data within DataSource

So, I'm trying to make a readyonly grid with kendo that shows data, but whatever I do, the data does not get shown.
The grid looks like this
And here's the code:
$("#Materials")
.kendoGrid({
dataSource: {
data: [],
schema: {
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false },
Code: { type: "string", editable: false },
Name: { type: "string", editable: false },
ExtDeviceCode: { type: "string", editable: false , nullable: true },
BaseUomLOVString: { type: "string", editable: false }
}
}
},
pageSize: 20
},
filterable: {
extra: true
},
pageable: true,
columns: [
{ field: "Code", title:"Code"},
{ field: "Name", title: "Name"},
{ field: "ExtDeviceCode", title:"External device code"},
{ field: "BaseUomLOVString", title: "UnitsOfMeasure" }
],
editable: false
});
This makes an empty grid with no data, which I later on fill with an Ajax call. As you can see from above picture, the grid contains the data but does not display it. The data inside the dataSource looks like this. or as Json:
[{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}]
EDIT 1: I'm filling the data with an Ajax call like this:
$.ajax({
url: '#SimpleUrlHelper.UrlObjectToRoot(Url)/FuelPointMaterialTankMask/LookupMaterials',
data: {
//Send list of IDs
'materialIDs': materialList
},
type: "POST",
success: function (response) {
var tmp = [];
if (typeof response !== "undefined" &&
response !== null) {
response.forEach(function(item) {
tmp.push(item);
});
}
grid = $("#Materials").data("kendoGrid");
originalMaterialDataSource = grid.dataSource;
originalMaterialDataSource.data(tmp);
originalMaterialDataSource._destroyed = [];
originalMaterialDataSource.pageSize(pageSize);
originalMaterialDataSource.page(1);
originalMaterialDataSource._total = tmp.length;
grid.pager.refresh();
}
});
You can set your data in your dataSource after your ajax call.
var dataArray = [{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}];
Use .data() to set:
$("#Materials").data('kendoGrid').dataSource.data(dataArray );
Okay so after days of trying to figure out what was wrong I finally found the answer.
Somewhere along the lines I had:
var grids = $('.k-grid');
for (var i = 0; i < grids.length; i++) {
....
grid.dataSource.filter().filters[0] = {
logic: "or",
filters: filters
}
....
So basically I was putting filters on all grids without excluding this one, which was just a bug from my part.

Updating value in jqGrid doesn't work when two columns use same field

I used the solution mentioned in How to update value of data in jqgrid to update data locally. It worked for me as shown in the first fiddle. In the "Action" column, there is button added conditionally, based on the data in "IsActive" column. If it is "true", a "Retire" button gets added as an action. If it is false, "Activate" button gets added. When the javascript function is called, the button changes to "Activate".
Fiddle 1
Now, I added another column to display the status value as text. Now, both "Status" column and "Action" column are utilizing the same data column - IsActive. After adding this column, the javascript function is not changing the button from "Retire" to "Activate".
Fiddle 2
What is the best way to fix this issue?
CODE
$(document).ready(function () {
function updateActiveStatus(rowid, isToActive) {
alert('function');
// first change the cell in the visible part of grid
$("#list").jqGrid('setCell', rowid, 'firstname', 'A');
// now change the internal local data
$("#list").jqGrid('getLocalRow', rowid).firstname = 'A';
$("#list").jqGrid('setCell', rowid, 'IsActive', false);
$("#list").jqGrid('getLocalRow', rowid).IsActive = false;
}
var myData = [
{ "id": "35", "firstname": null, "codeval": "G", "note": "xx7866", "amount": "23", "IsActive": true },
{ "id": "73", "firstname": null, "codeval": "W", "note": "dd1047", "amount": "34", "IsActive": true },
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323", "amount": "56", "IsActive": true },
{ "id": "95", "firstname": "EST", "codeval": "M", "note": "gg574", "amount": "55", "IsActive": true }
],
myGrid = $("#list");
myGrid.jqGrid({
datatype:'local',
data: myData,
colNames: ['ID', 'FirstName', 'Code', 'Amount', 'Note', 'Action'],
colModel:[
{name:'id',width:70,align:'center',sorttype: 'int'},
{name:'firstname',width:80, align:'center'},
{ name: 'codeval', width: 70 },
{name:'amount',width:100, formatter:'number'},
{name:'note',index:'note',width:100,sortable:false},
{
name: 'IsActive',
width: 100,
formatter: function (cellvalue, options, rowObject) {
if (cellvalue == true) {
return '<div style="padding-left:5px;"><button class="ui-button ui-widget ui-state-default app-custom-button-retire" >' +
'<span title="" class="ui-button-icon-primary ui-icon ui-icon-scissors"></span>Retire' +
'</button></div>';
}
else {
return '<div style="padding-left:5px;"><button class="ui-button ui-widget ui-state-default app-custom-button-activate" >' +
'<span title="" class="ui-button-icon-primary ui-icon ui-icon-check"></span>Activate' +
'</button></div>';
}
}
}
],
rowNum:10,
pager: '#pager',
gridview:true,
ignoreCase:true,
rownumbers:true,
viewrecords: true,
sortorder: 'desc',
height: '100%',
beforeSelectRow: function (rowid, e) {
var $self = $(this),
$td = $(e.target).closest("tr.jqgrow>td"),
rowid = $td.parent().attr("id"),
//rowData = $self.jqGrid("getLocalRow", rowid),
rowData = $self.jqGrid("getRowData", rowid)
iCol = $td.length > 0 ? $td[0].cellIndex : -1,
colModel = $self.jqGrid("getGridParam", "colModel");
celValue = $self.jqGrid('getCell', rowid, 'FirstName');
if (iCol >= 0 && colModel[iCol].name === "IsActive") {
if ($(e.target).hasClass("app-custom-button-retire")) {
updateActiveStatus(rowid,false);
return false;
}
if ($(e.target).hasClass("app-custom-button-activate")) {
updateActiveStatus(rowid, true);
return false;
}
}
//Avoid selection of row
return false;
}
});
myGrid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
});
I seem multiple misunderstanding in your code. First of all you have some source data, which are the array of item. Every item is object with multiple properties, like:
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323",
"amount": "56", "IsActive": true }
or, which is the same,
{ id: "75", firstname: "LORA", codeval: "H", note: "rr7323",
amount: "56", IsActive: true }
It should be clear that such item can't have multiple properties with the same name. The object
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323",
"amount": "56", "IsActive": true, "IsActive": true }
would be wrong even if some web browser could ignore the error. Even if you specify the same value true for both "IsActive" properties.
In the same way you can't use colModel with multiple columns with the same name property. Your second demo https://jsfiddle.net/LijoCheeran/rqab1veh/11/ have two columns with the same property name: 'IsActive'. It's wrong. You can fix the code by usage, for example, name: 'IsActive1' in the second column. The formatter of IsActive1 can use rowObject.IsActive instead of cellvalue to access to the required data. The corresponding code will be the follwing
{
name: 'IsActive1',
width: 75,
formatter: function (cellvalue, options, rowObject) {
return rowObject.IsActive == true ? 'Active' : 'Retired';
}
},
{
name: 'IsActive',
width: 100,
formatter: function (cellvalue, options, rowObject) {
return cellvalue == true ? retireButton : activeButton;
}
}
where retireButton and activeButton contains HTML fragments of the buttons.
Now it's important to understand, that jqGrid hold the data array. The method $("#list").jqGrid('getLocalRow', rowid) get you the reference to the data item which corresponds the data of the row. The method getRowData will get the data from HTML representation of the cells (from <td> elements) and unformat there. The type of the fields of returned object will be strings.
Because you need to update not only the data, but the cell content of firstname, IsActive1 and IsActive columns then you have to call setCell on every the field or better call one setRowData:
function updateActiveStatus (rowid, isToActive) {
alert('calling the function');
$("#list").jqGrid('setRowData', rowid, {
firstname: 'A',
IsActive1: false,
IsActive: false
});
var item = $("#list").jqGrid('getLocalRow', rowid);
// delete unneeded IsActive1 property created in the item
delete item.IsActive1;
}
The only small disadvantage of the setRowData call is creating new property IsActive1 in the item of data. Old jqGrid 4.6 have no possibility to save the data "virtually" in some another place as the item.IsActive1. Free jqGrid allows to specify saveLocally callback, which can make custom "saving" of the data of the column in the local item. It's not real large problem in your case and you need just delete unneeded property by delete item.IsActive1
You can see the results on the modified demo https://jsfiddle.net/OlegKi/rqab1veh/12/

kendo grid how to set the schema.model with a foreign key field

need help about adding a new recort in a kendo grid.
I have a grid with a foreign key field. The grid is populated by a json data with subobject, returned from a webmethod. it looks like this:
[
{
"classe_iva": {
"id_classe_iva": 5,
"desc_classe_iva": "Esente",
"note_classe_iva": null
},
"id_iva": 37,
"desc_iva": "bbb",
"codice_iva": "bbb",
"imposta": 2,
"indetr": 2,
"id_classe_iva": 5,
"note": "dddddfsf",
"predefinito": false,
"id_company": 4
},
{
"classe_iva": {
"id_classe_iva": 6,
"desc_classe_iva": "Escluso",
"note_classe_iva": null
},
"id_iva": 52,
"desc_iva": "o",
"codice_iva": "jj",
"imposta": 1,
"indetr": 1,
"id_classe_iva": 6,
"note": "l",
"predefinito": false,
"id_company": 4
}
]
and this is the schema.model used in the kendo datasource:
model = {
id: "id_iva",
fields: {
id_iva: { type: "string", editable: false },
desc_iva: { type: "string" },
codice_iva: { type: "string" },
imposta: { type: "number" },
indetr: { type: "number" },
id_classe_iva: {type: "string"},
note: { type: "string" },
predefinito: { type: "boolean" },
id_company: { type: "number" }
}
}
.. and below is shown the grid columns format:
toolbar = [{
name: "create",
text: "Aggiungi nuova aliquota IVA"
}];
columns = [
{ field: "desc_iva", title: "Descrizione", width: 45 },
{ field: "codice_iva", title: "Codice", width: 45 },
{ field: "imposta", title: "Imposta", width: 45 },
{ field: "indetr", title: "Indetr", width: 45 },
{ field: "classe_iva.desc_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= classe_iva ? classe_iva.desc_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
{ field: "note", title: "Note", width: 45 },
{
command: [{
name: "destroy",
text: "Elimina",
confirmation: "Sei sicuro di voler eliminare questa voce?"
} ,
{
name: "edit",
text: {
edit: "Modifica",
update: "Aggiorna",
cancel: "Cancella"
}
}
]
}
];
Theese settings works fine when i edit a row, and the grid shows the right content into the combobox field.
The problem is when i click on the "add new record" button, because when it tries to add a new row, it doesn't find the subobjects field "classe_iva".
if i change the column.field into this
{ field: "id_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= id_classe_iva ? id_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
{ field: "note", title: "Note", width: 45 }
the add button works fine, but when the grid is loaded, the column id_classe_iva doesn't shows me the classe_iva.desc_classe_iva field...
how can i fix the issue??^?
thanks in advance.
to fix this issue, i used a workaround:
the error was thrown because, in the declaration of the field.template there where a not declared variable (classe_iva):
{ field: "id_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= classe_iva ? classe_iva.desc_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
then, i declared a global variable
var classe_iva;
in this way, when i add a new record, the code doesn't throw any errors, and by the ternary if, the default value is set.
hope it will help someone.

kendo ui: no Data in Subgrid

i'm working with kendo ui to create rich user interface, but i'm stuck t the following:
I want a Grid with a subgrid, the first one displays customer info, like name, etc the second shows the available shipping-adresses, the customer saved. Now my problem is, that in the subgrid is not data, although firebug shows, that the data was returned. This is my source:
$(function() {
var main = $("#customer-grid").kendoGrid({
dataSource: {
transport:{
read :"data/users.php",
update :{
url :"data/users.php?action=update",
type:"POST",
data: function (data) {
data.birthday = kendo.toString(data.birthday, "yyyy-MM-dd");
return data;
}
},
destroy:{
url :"data/users.php?action=destroy",
type:"POST"
}
},
schema: {
data: "data",
model: {
id: "id",
fields: {
id: {editable: false},
activated: { type: "boolean" },
birthday: {type: "date"},
gender: {defaultValue: "W"}
}
}
}
},
height: 250,
filterable: true,
sortable: true,
pageable: true,
detailInit: detailInit,
dataBound: function() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [{
field: "id",
title: "ID",
width: "50px"
}, {
field: "gender",
title: "Geschlecht",
width: "100px",
values: data
}, {
field: "firstname",
title: "Vorname"
}, {
field: "lastname",
title: "Nachname"
}, {
field: "birthday",
title: "Geburtstag",
width: "100px",
format: "{0:dd.MM.yyyy}"
},{
field: "mail",
title: "E-Mail"
},{
field: "activated",
title: "Aktiviert",
width: "100px",
values: actval
}, {
command: ["edit", "destroy"],
title: " ",
width: "210px"
}],
editable:{
mode: "popup"
}
});
});
function detailInit(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
transport: {
read: "data/adress.php?uid="+e.data.id
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize:6
},
scrollable: false,
sortable: true,
pageable: true,
columns: [
{ field: "id", width: 70 },
{ field: "zipcode", title:"Ship Country", width: 100 },
{ field: "city", title:"Ship Address" },
{ field: "street", title: "Ship Name", width: 200 }
]
});
}
The function gets its data from a php page, which does a mysql-query and then gives back the data as application/json. But nothing is shown.
Hopefully you guys can help me.
Regards
I tested your code and it works fine.
Check:
e parameter format. I've used: detailInit({ detailCell : $("#grid"), data : { id : 1}});
JSON returned by data/adress.php. I've returned:
[
{"city":"Madrid", "id":"1", "zipcode":"31000", "street":"my street 1", "number":5},
{"city":"Sofia", "id":"2", "zipcode":"32000", "street":"my street 2", "number":4},
{"city":"London", "id":"3", "zipcode":"33000", "street":"my street 3", "number":3},
{"city":"San Francisco", "id":"4", "zipcode":"34000", "street":"my street 4", "number":2},
{"city":"Berlin", "id":"5", "zipcode":"35000", "street":"my street 5", "number":1}
]
Using the following (hardcoded) php response:
<?php
header('Content-type: application/json');
$named_array = array(
array("city" => "Madrid", "id" => "1", "zipcode" => "31000", "street" => "my street 1", "number" => 5),
array("city" => "Sofia", "id" => "2", "zipcode" => "32000", "street" => "my street 2", "number" => 4),
array("city" => "London", "id" => "3", "zipcode" => "33000", "street" => "my street 3", "number" => 3),
array("city" => "San Francisco", "id" => "4", "zipcode" => "34000", "street" => "my street 4", "number" => 2),
array("city" => "Berlin", "id" => "5", "zipcode" => "35000", "street" => "my street 5", "number" => 1)
);
echo json_encode($named_array);
?>
EDIT: This is the definition of the grid containing the subgrid.
var outer = $("#outer").kendoGrid({
dataSource:{
type:"json",
transport:{
read:"names.php"
},
pageSize:5
},
sortable:true,
columns:[
{ field:"id", width:70 },
{ field:"name", title:"Name", width:100 },
{ field:"lastname", title:"LastName", width:100 },
{ title:"Address", width:300, attributes:{ class:"ob-address"}}
]
}).data("kendoGrid");
and then on a button click, I run:
$(".ob-address", outer.tbody).each(function (idx, elem) {
detailInit({ detailCell:elem, data:{ id:1}});
});
As you can see I marked a column in the outer grid with a CSS class named ob-address and the function selects all the cell in the body of the outer table for inserting the inner table (subgrid).

Resources