Error in kendo grid - grid.select is not a function why? - javascript

I have a kendoDropDown list as a cell in my grid. I am calling the kendDropDownList using the editor command of kendo grid ("editor"). I need to pass selected value of selected row to kendoDropDownList as a parameter in order to server reply back only with filtered list as my kendoDropDownList . Please see my below example
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
columnMenu:true,
filterable:true,
height: 550,
reorderable: true,
columnReorder: function(e) {
console.log(e.column.field, e.newIndex, e.oldIndex);
},
toolbar: ["create","excel","save", "cancel" , { template: kendo.template($("#template").html()) } , { template: kendo.template($("#clearFilterTemplate").html()) } , { name: "create", text: "Add New Employee" }],
excel: {
fileName: "Kendo UI Grid Export.xlsx",
proxyURL: "excelExport",
filterable: true,
allPages: true
},
editable: "inline" , //editable: true,
columns: [
{ field: "fileNo" , title:"File No" , width: 80 },
{ field: "jobNo" , title:"Job No" , width: 80 },
{ field: "discipline" , title:"Discipline" , width: 80 },
{ field: "moduleNo" ,title:"Module", width: 100},
{ field: "description",title:"Title",editor: descriptionDropDownEditor, width: 150},
{ field: "documentNo",title:"Document No", width: 150 },
{ field: "remarks",title:"Remarks" , width: 150 } ,
{ command: ["edit","destroy"], title: " ", width: "250px" }
]
});
function descriptionDropDownEditor(container, options) {
// here is the error grid.select is not a function why ?
var selectedItem = grid.dataItem(grid.select());
var selectedJobNo = selectedItem.jobNo ;
alert("selectedJobNo :"+selectedJobNo );
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "text",
dataValueField: "value",
filter: "contains",
dataSource: {
dataType: "json",
transport: {
// I need to pass the selected jobNo in order to get the only aprropriate descrption for that jobNo
// each row job has description and I don't want to show all the description for all jobs , I need only for that row jobNo
read: "getDescriptionForEachDocumentIndex?selectedJobNo"+selectedJobNo
}
}
});
}
once the row of grid in edit mode I need to pass the selected row jobNo to kendoDropDownList in order to respond back with only releated description for that jobNo. The problem is i can not call grid in the edit mode and use the function grid.select() . what to do in this case ?

Well, that is easy. The second parameter of your editor function has a property called model, which is the dataItem of the current row user is editing. So in your case, I supose this would work:
function descriptionDropDownEditor(container, options) {
var selectedItem = options.model;
But, to answer your question, you can't access the select() method because grid is not a Kendo Grid object, it is in fact the #grid element. You can either add .data("kendoGrid") at the end of the widget initialization:
$("#grid").kendoGrid({ ... }).data("kendoGrid");
Or call it inside the function:
function descriptionDropDownEditor(container, options) {
var gridWidget = $(grid).data("kendoGrid");
var selectedItem = gridWidget.dataItem(gridWidget.select());

Related

Binding array of object to Kendo grid popup multiselect

I'm trying to bind an array of id-value pairs to a kendo grid popup editor.
Got everything to work for creating a new record. Popup editor loads the custom editor and successfully submits the data to the controller.
The problem is when I try to edit records. The records displays properly in the row, but when I try to edit it, the multiselect does not hold the values.
Grid Markup
$("#ProjectSites-SubContract-grid").kendoGrid({
dataSource: {
type: "json",
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
DateOfContract: { type: 'date', editable: true },
DateOfCompletion: { type: 'date', editable: true },
AmountOfContract: { type: 'number', editable: true },
Contractor: { defaultValue: { id: "", name: "" } }
}
}
},
},
columns: [
{
field: "ScopeOfWork",
title: "Scope of Work",
template: "#=parseScopeOfWork(ScopeOfWork)#",
editor: scopeOfWorkEditor
},
]
});
});
Scope of Work editor
function scopeOfWorkEditor(container, options) {
$('<input data-text-field="name" data-value-field="id" data-bind="value:ScopeOfWork"/>')
.appendTo(container)
.kendoMultiSelect({
dataSource: {
data: [
#foreach (var scopeOfWork in Model.AvailableScopeOfWork)
{
<text>{ id : "#scopeOfWork.Value", name : "#scopeOfWork.Text" },</text>
},
]
}
});
parseScopeOfWork -
this method guys iterates through the object list and concats the name.
function parseScopeOfWork(scopeOfWork) {
var result = "";
for (var i = 0; i < scopeOfWork.length; i++) {
result += scopeOfWork[i].Name;
if (i < scopeOfWork.length - 1)
{
result += ", <br/>";
}
}
return result;
}
Here's a screenshot:
You're binding the SpaceOfWork to the new widget, but how that widget knows your Model ? I mean, just using data-bind doens't binds the model to the widget, it can't figure that by itself. I have two suggestions:
Set the value in the widget's initialization:
.kendoMultiSelect({
value: options.model.ScopeOfWork
Demo
Bind the model to the widget for good:
let $multiSelect = $('<input data-text-field="name" data-value-field="id" data-bind="value:ScopeOfWork"/>');
kendo.bind($multiSelect, options.model);
$multiSelect
.appendTo(container)
.kendoMultiSelect({ ...
Demo
Note: Edit the category cell in both demos to see the changes.

How to delete a row in dojo EnhancedGrid using row index not by using selection

Trying to find an answer to remove a row for dojo EnhancedGrid based on the row index.
Please find the EnhancedGrid.
var dataStore = new ObjectStore({objectStore: objectStoreMemory});
// grid
grid = new EnhancedGrid({
selectable: true,
store: dataStore,
structure : [ {
name : "Country",
field : "Country",
width : "150px",
reorderable: false,
editable : true
}, {
name : "Abbreviation",
field : "Abbreviation",
width : "120px",
reorderable: false,
editable : true
}, {
name : "Capital",
field : "Capital",
width : "100%",
reorderable: false,
editable : true
}, {
label: "",
field: "Delete",
formatter: deleteButton
}],
rowSelector: '20px',
plugins: {
pagination: {
pageSizes: ["10", "25", "50", "100"],
description: true,
sizeSwitch: true,
pageStepper: true,
gotoButton: true,
maxPageStep: 5,
position: "bottom"
}
}
}, "grid");
grid.startup();
And the Delete Button Script is here:
function deleteButton(id) {
var dBtn1 = "<div data-dojo-type='dijit/form/Button'>";
var dBtn2 = "<img src='delete.png' onclick='javascript:removeItem()' alt='" + id + "'";
dBtn = dBtn1 + dBtn2 + " width='18' height='18'></div>";
return dBtn;
}
Here is my Question: Each row will have a delete button at the end, On click of this button the same row should be deleted.
Can anybody tell me how to delete a row based on row index?
If you want to add (remove) data programmatically, you just have to
add (remove) it from the underlying data store. Since DataGrid is
“DataStoreAware”, changes made to the store will be reflected
automatically in the DataGrid.
https://dojotoolkit.org/reference-guide/1.10/dojox/grid/example_Adding_and_deleting_data.html
dojox/grid has a property selection and method getSelected() to get selected items. In example from documentation it's implemented in following way:
var items = grid5.selection.getSelected();
if(items.length){
// Iterate through the list of selected items.
// The current item is available in the variable
// "selectedItem" within the following function:
dojo.forEach(items, function(selectedItem){
if(selectedItem !== null){
// Delete the item from the data store:
store3.deleteItem(selectedItem);
} // end if
}); // end forEach
} // end if
Hope it will help.
Here is the solution. The sequence of methods that will run onClick of a button are removeItem() and onRowClick event
1> Set the "deleteButtonFlag" on click of a button.
function removeItem() {
deleteButtonGFlag = true;
}
2> Remove item
dojo.connect(grid, "onRowClick", function(e) {
if (deleteButtonGFlag) {
dataStore.fetch({
query: {},
onComplete: function(items) {
var item = items[e.rowIndex];
dataStore.deleteItem(item);
dataStore.save();
deleteButtonGFlag = false;
}
});
}
});

How to give two indentical combo one on grid headr and one as grid column widget for store filter

I have one widget column header by which I am selecting the value and filtering the grid store. I want exact the same on grid header as well. There for I am giving one combo with same values.
Here is my code for column header
header: {
items: [{
xtype: 'combo',
displayField: "displayName",
fieldLabel: 'Some Label',
valueField: 'title',
displayField: 'title',
hidden : true,
queryMode: 'local',
value : 1,
autoSelect : true,
//dataindex:"MUTST",
store: {
fields: ["id", "displayName"],
data: [
{ "id": "1", "title": "Test1" },
{ "id": "2", "title": "Test2" },
{ "id": "3", "title": "Test3" }
]
},
listeners : {
select : function(combo , record , eOpts){
debugger;
var sg = this.up("MyGrid");
var col = sg.getColumns()[0]; // Getting Header column
var flit =sg.getColumns()[0].filter // Here I am getting object instead of constructor
//this.focus = sg.onComboFilterFocus(combo);
}
},
}]
},
I am creating widget type in column
MyColumn: function(headersXmlDoc) {
var me = this,
gridConfig = {};
gridConfig.columns = [];
Ext.each(headersXmlDoc.getElementsByTagName("HEADER"), function(header) {
var column = {
text: header.getAttribute("L"),
dataIndex: header.getAttribute("DATAINDEX"),
sortable: (header.getAttribute("ISSORTABLE").toLowerCase()=="true"),
widgetType: header.getAttribute("WIDGET"),
filterType: Ext.isEmpty(header.getAttribute("FILTER"))? undefined: header.getAttribute("FILTER"),
};
switch (header.getAttribute("WIDGET")) {
case 'textbox':
if(column.filterType){
if(column.filterType == 'TagData'){
column.filter = {
xtype: 'tagfield',
growMax : 10,
valueField: 'title',
displayField: 'title',
parentGrid : me,
dataIndex:header.getAttribute("DATAINDEX"),
queryMode: 'local',
multiSelect: true,
isFilterDataLoaded: false,
disabled: true,
listeners:{
focus: me.SomeMethod, //
}
};
}
}
break;
}
this.columns.push(column);
}, gridConfig);
return gridConfig.columns;
},
I want if I select in header combo, it will directly select in widget combo as well. Can anyone explain how to get this. Thanks in advance
So you basically need a combo box in your header, that changes record values - the fact that you have a widget column displaying a combo within the grid cells doesn't really matter here.
I think you were fairly close - but you were trying to define a "header" config and add the combo to its items - instead you just define items directly on the column:
columns: [{
text: 'Combo Test',
dataIndex: 'title',
items: [{
xtype: 'combobox',
width: '100%',
editable: false,
valueField: 'title',
displayField: 'title',
queryMode: 'local',
autoSelect: true,
store: {
data: [{
"id": "1",
"title": "Test1"
}, {
"id": "2",
"title": "Test2"
}, {
"id": "3",
"title": "Test3"
}]
},
listeners: {
select: function (combo, selectedRecord) {
//we could just get the value from the combo
var value = combo.getValue();
//or we could use the selectedRecord
//var value = selectedRecord.get('id');
//find the grid and get its store
var store = combo.up('grid').getStore();
//we are going to change many records, we dont want to fire off events for each one
store.beginUpdate();
store.each(function (rec) {
rec.set('title', value);
});
//finish "mass update" - this will now trigger any listeners for saving etc.
store.endUpdate();
//reset the combobox
combo.setValue('');
}
}
}],
},
The actual setting of values happens in the select listener as you were trying - the key is to loop through the records and call set on each one:
//find the grid and get its store
var store = combo.up('grid').getStore();
//we are going to change many records, we dont want to fire off events for each one
store.beginUpdate();
store.each(function (rec) {
rec.set('title', value);
});
//finish "mass update" - this will now trigger any listeners for saving etc.
store.endUpdate();
I have created a fiddle to show this working:
https://fiddle.sencha.com/#view/editor&fiddle/1r01

How to create custom dropdownlist in kendo grid header column?

Actually my requirement is want to create custom dropdownlist in the column header of kendo grid. I don't down like nrwant to use filtler column. I just want to add normal dropdown in header. Please provide any example like that so that i can move forward on my task.
Thanks in advance...
In your column definition add a property like this:
headerTemplate: '<input id="dropdown" />'
Then after your grid initialization do:
$("#dropdown").kendoDropDownList({...init parameters...});
UPDATE: go to dojo.telerik.com and paste in the following code:
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [
{
field: "ProductName",
title: "Product Name",
headerTemplate: '<input id="dropdown" />'
},
{ field: "UnitPrice", title: "Price", template: 'Price: #: kendo.format("{0:c}", UnitPrice)#' }
],
pageable: true,
dataSource: {
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/products",
dataType: "jsonp"
}
},
pageSize: 10
},
excelExport: function(e) {
var sheet = e.workbook.sheets[0];
var template = kendo.template(this.columns[1].template);
for (var i = 1; i < sheet.rows.length; i++) {
var row = sheet.rows[i];
var dataItem = {
UnitPrice: row.cells[1].value
};
row.cells[1].value = template(dataItem);
}
}
});
$("#dropdown").kendoDropDownList({
optionLabel: 'Choose a value...',
dataTextField: 'description',
dataValueField: 'id',
dataSource:{
data: [{id: 1, description: 'One'},{id: 2, description: 'Two'}]
},
change: function(e){
//do whatever you need here, for example:
var theGrid = $("#grid").getKendoGrid();
var theData = theGrid.dataSource.data();
$(theData).each(function(index,item){
item.ProductName = e.sender.text();
});
theGrid.dataSource.data(theData);
}
});

how to delete multiples rows in jqgrid if the method selarrrow returns arrays that has more than 1 index?

I have my grid with multiselect = true, something likes this, you can click each checkbox and then delete, when I delete my first row I know the method selarrrow creates and arrays It just delete, but when I want to delete the second row It just never do the delRowData method, and when I select multiple checkbox It just delete the first. I think my method is looping over and over againg each time and never delete at least visually the other row, how can I fix it?? any advise thanks
this is my method:
onSelectRow:function(id) {
$("#mySelect").change(function (){
if(($("#mySelect option:selected").text()) == 'Deleted') {
var id = $("#list2").getGridParam('selarrrow');
for(var i =0; i<id.length;i++) {
$("#list2").jqGrid('delRowData',id[i]);
}
});
}
html
</head>
<body>
<div>
Move to:
<select id="mySelect">
<option value="1">Select and option</option>
<option value="2">Trash</option>
<option value="3">Deleted</option>
</select>
</div>
<table id="list2"></table>
<div id="pager2"></div>
</body>
</html>
js
$("#Inbox").click(function () {
$.post('../../view/inbox.html', function (data) {
$('#panelCenter_1_1').html(data);
$("#list2").jqGrid({
url: '../..controller/controllerShowInbox.php',
datatype: 'json',
colNames: ['From', 'Date', 'Title', 'Message'],
colModel: [
{ display: 'From', name: 'name', width: 50, sortable: true, align: 'left' },
{ display: 'Date', name: 'date', width: 150, sortable: true, align: 'left' },
{ display: 'Title', name: 'title', width: 150, sortable: true, align: 'left' },
{ display: 'Message', name: 'message', width: 150, sortable: true, align: 'left' },
],
searchitems: [
{ display: 'From', name: 'name' },
{ display: 'Date', name: 'date' },
{ display: 'Title', name: 'title' },
{ display: 'Message', name: 'message' },
],
rowNum: 10,
rowList: [10, 20, 30],
pager: '#pager2',
sortname: 'id_usuario',
viewrecords: true,
sortorder: "desc",
caption: "Inbox",
multiselect: true,
multiboxonly: true,
onSelectRow: function (id) {
$("#mySelect").change(function () {
if (($("#mySelect option:selected").text()) == 'Trash') {
var id = $("#list2").getGridParam('selarrrow');
if (id != '') {
var grid = $("#list2");
grid.trigger("reloadGrid");
$.post('../../controller/controllerChangeStatus.php', { id: id }, function (data) {
$('#panelCenter_2_1').html(data);
grid.trigger("reloadGrid");
});
}
} else if (($("#mySelect option:selected").text()) == 'Deleted') {
id = $("#list2").getGridParam('selarrrow');
if (id != '') {
var grid = $("#list2");
grid.trigger("reloadGrid");
$.post('../../controller/controllerChangeStatus.php', { id: id }, function (data) {
$('#panelCenter_2_1').html(data);
grid.trigger("reloadGrid");
});
}
} else {
}
});
}
});
});
});
You code looks very strange for me. I can't explain the effects which you describe without having the demo code, but I could point you to some places in the code which should be rewrote.
First problem: you use id parameter in the line onSelectRow:function(id) and then use the same variable name id to declare var id = $("#list2").getGridParam('selarrrow');. I don't understand why you do this. If you don't need parameter of onSelectRow you can just use onSelectRow:function() which will make the code more clear.
Second problems: you use binding to change event in $("#mySelect").change, but you use the statement inside of another event onSelectRow. So on every row selection you will have one more event handler to the change event. For example you would replace the body of $("#mySelect").change(function (){ to alert("changed!"). Then you would select two different rows and change the option in the "#mySelect". You will see two alerts. Then you select another row and change the option in the "#mySelect". You will see three alerts. And so on.
So you should rewrote your code in any way. If you will still have the same problem you should include full demo code (including HTML code with <select id="mySelect">...) which can be used to reproduce your problem.
I use a different approach. I build a vector of selected row ids and then process 'em with a single batch statemente server side then reload the grid.
More or less the code is.
var righe = $(nomeGrigliaFiglia).getGridParam("selarrrow");
if ((righe == null) || (righe.length == 0)) {
return false;
}
var chiavi = [];
for (var i = 0; i < righe.length; i++) {
var Id = righe[i];
var data = $(nomeGrigliaFiglia).jqGrid('getRowData', Id);
// Process your data in here
chiavi[i] = new Array(2)
chiavi[i][0] = data.FieldKey;
chiavi[i][1] = data.FieldChildId;
}
Note that I'm using this to actually send a int [][] to a C# Action
multiselect: true,
in your data process php $SQL .= "DELETE FROM ". $table. " WHERE no in ($_POST[id]);" ;

Categories