How could I disallow a cell in my kendo grid to be 'blank' or 'empty' rather... How could I replace all blank or empties with a 0..
I have a save button grabbing the values from my kendo grid such as below: Everything works fine EXCEPT, it is completely omitting my empty cells.. I want to keep them, just have a 0 value on them...
Save button: want to keep the empties with simply a 0 or N/A..
$('.' + chs).on('click', '#saveChanges', function(e) {
which = $(frm).attr("class");
let dataSource = $("#grid").data("kendoGrid").dataSource,
data = dataSource.data(),
changedModels = [];
if(dataSource.hasChanges) { // only saves cells/row that have been edited/changed, need to keep this
for(var i = 0; i < data.length; i++) {
if(data[i].dirty) { changedModels.push(data[i].toJSON()) }
}
}
let ds = JSON.stringify(changedModels);
$.ajax({
type: "POST",
url: "saveGrid",
dataType: "json",
data: {
id: which,
data: ds
},
success: function(result) {
console.log('yy');
},
error: function(result) {
console.log('nn');
}
});
});
This is my kendo grid initialized:
let dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/popGrid?id=" + which,
dataType: "json"
},
},
batch: true,
schema: {
data: "data",
model: {
id: id,
}
},
});
console.log(id);
$("#grid").kendoGrid({
dataSource: dataSource,
height: 600,
sortable: true,
autoBind: true,
nullable: true,
editable: {
createAt: "top"
},
change: function(e) {
let grid = $("#grid").data("kendoGrid");
let selectedItem = grid.dataItem(grid.select());
let val = selectedItem.id;
console.log(val);
},
selectable: "row",
toolbar: [
{ name: "create" },
{ name: "cancel" }
],
paging: false,
});
I can't understand if you want to POST empty fields as "0" or if you want to SHOW them in the grid as "0", when null or "empty".
But I guess you're talking about posting it as "0". In that case I think you have to do that before posting:
let fieldName = 'myCell';
if (data[i].dirty) {
if (!data[i].hasOwnProperty(fieldName) || // In case field is not present on data
!data[i][fieldName]) { // In case field value is null/undefined/0/false/empty string
data[i][fieldName] = 0;
}
changedModels.push(data[i].toJSON());
}
For multiple field check:
let fieldNames = ['fieldA', 'fieldB', ...],
checkFields = (item) => {
fieldNames.forEach(field => {
if (!item.hasOwnProperty(field) || // In case field is not present on data
!item[field]) { // In case field value is null/undefined/0/false/empty string
item[field] = 0;
}
});
};
Or you can do the same before data is bound to the grid with dataSource.schema.parse.
I'm setting up a file manager, when right clicking on folder it will popup context menu, before popup am disabling some menu item using ajax. But ajax call is not working when I right clicked on folder which arranged in datatable.
This is my code for popup menu item. Getting error when right clicking on folder which arranged in datatable.
webix.js?1.0.0:22356 Uncaught TypeError: Cannot read property 'row' of undefined"
actions: {
config: function () {
var t = this.config.templateName;
return {
view: "contextmenu",
width: 200,
padding: 0,
autofocus: !1,
css: "webix_fmanager_actions",
template: function (e, i) {
var s = t(e, i);
return "<span class='webix_icon fa-" + e.icon + "'></span>" + s
},
data: "actionsData"
}
},
oninit: function () {
this.getMenu().attachEvent("onBeforeShow", function (t) {
var e = this.getContext();
var folderid = e.id;
$.ajax({
url: "<?php echo base_url()?>/Directorylist/directory_activity",
type: "POST",
datatype: 'json',
async: false,
data: {'folderid':folderid},
success: function (data) {
var json = JSON.parse(data);
permission = [];
permission = json;
},
});
if (permission[0] == 1 && permission[1] == 0 && permission[2] == 0) {
$$(this).disableItem('copy');
$$(this).disableItem('cut');
$$(this).disableItem('paste');
$$(this).disableItem('create');
$$(this).disableItem('remove');
$$(this).disableItem('edit');
$$(this).disableItem('upload');
}
})
}
},
actionsData: {
config: function () {
return [{
id: "copy",
method: "markCopy",
icon: "copy",
value: copy
}, {
id: "cut",
method: "markCut",
icon: "cut",
value: cut
}, {
id: "paste",
method: "pasteFile",
icon: "paste",
value: paste
}, {
$template: "Separator"
}, {
id: "create",
method: "createFolder",
icon: "folder-o",
value: create
}, {
id: "remove",
method: "deleteFile",
icon: "times",
value: remove
}, {
id: "edit",
method: "editFile",
icon: "edit",
value: rename
}, {
id: "upload",
method: "uploadFile",
icon: "upload",
value: upload
}]
}
}
But when I removed these two lines and given direct value, it works fine.
var e = this.getContext();
var folderid = e.id;
above 2 lines removed and added
var folderid = '1';
You lost the scope of this after the second function.
Here's a time proven fix:
oninit: function () {
var self = this;
this.getMenu().attachEvent("onBeforeShow", function (t) {
var e = self.getContext();
var folderid = e.id;
See also: Javascript "this" scope
Or if you are using ES6 then you could use an arrow function:
oninit: function () {
this.getMenu().attachEvent("onBeforeShow", (t) => {
var e = this.getContext();
var folderid = e.id;
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
I have DataTable filled with js-switches, here's the code:
$('#bandsTable').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
'type': 'GET',
'url': 'myUrl',
'data': function (d) {
d._token = Laravel.csrfToken;
}
},
columns: [
{
title: "Number",
data: "number"
},
{
title: "Privileged",
data: "privileged"
}
],
columnDefs: [
{
render: function (data) {
var checked = data ? 'checked' : '';
return '' +
'<input type="checkbox" class="js-switch" id="schedule_deactivation" ' +
checked + ' data-switchery="false" style="display: none;"> \n';
},
targets: 1
}
],
order: [[0, 'asc']],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
nRow.className = "band-row";
nRow.setAttribute("data-band", aData.number);
return nRow;
},
responsive: true
});
When I filter result's they're displayed correctly, but I don't see checkboxes generated, I can type JS from the console and it works when I type:
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
but I don't know when I should call this code. I have no idea about DataTable lifecycle and where should I inject the code. Should it be some callback defined by DataTables or something else?
please see the documentation on the below link for more, but the code should work as follows:
$('#bandsTable').on('draw.dt', function () {
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function (html) {
var switchery = new Switchery(html, {
color: '#26B99A',
secondaryColor: '#ff7a77'
});
});
});
Link:
https://datatables.net/reference/event/
I am trying to change the background color of selected row(s) in jquery datatable using my own css class but, the tick mark in the checkbox is not appearing.
If I remove className: 'selected-row' from the below code, then everything works normal but, without the color I want.
Fiddler: https://jsfiddle.net/8f63kmeo/12/
HTML:
<table id="CustomFilterOnTop" class="table table-bordered table-condensed" width="100%"></table>
JS
var Report4Component = (function () {
function Report4Component() {
//contorls
this.customFilterOnTopControl = "CustomFilterOnTop"; //table id
//data table object
this.customFilterOnTopGrid = null;
//variables
this.result = null;
}
Report4Component.prototype.ShowGrid = function () {
var instance = this;
//create the datatable object
instance.customFilterOnTopGrid = $('#' + instance.customFilterOnTopControl).DataTable({
columns: [
{ title: "<input name='SelectOrDeselect' value='1' id='ChkBoxSelectAllOrDeselect' type='checkbox'/>" },
{ data: "Description", title: "Desc" },
{ data: "Status", title: "Status" },
{ data: "Count", title: "Count" }
],
"paging": true,
scrollCollapse: true,
"scrollX": true,
scrollY: "300px",
deferRender: true,
scroller: true,
dom: '<"top"Bf<"clear">>rt <"bottom"<"Notes">i<"clear">>',
buttons: [
{
text: 'Load All',
action: function (e, dt, node, config) {
instance.ShowData(10000);
}
}
],
columnDefs: [{
orderable: false,
className: 'select-checkbox text-center',
targets: 0,
render: function (data, type, row) {
return '';
}
}],
select: {
style: 'multi',
selector: 'td:first-child',
className: 'selected-row'
}
});
};
Report4Component.prototype.ShowData = function (limit) {
if (limit === void 0) { limit = 100; }
var instance = this;
instance.customFilterOnTopGrid.clear(); //latest api function
instance.result = instance.GetData(limit);
instance.customFilterOnTopGrid.rows.add(instance.result.RecordList);
instance.customFilterOnTopGrid.draw();
};
Report4Component.prototype.GetData = function (limit) {
//structure of the response from controller method
var resultObj = {};
resultObj.Total = 0;
resultObj.RecordList = [];
for (var i = 1; i <= limit; i++) {
resultObj.Total += i;
var record = {};
record.Description = "This is a test description of record " + i;
record.Status = ["A", "B", "C", "D"][Math.floor(Math.random() * 4)] + 'name text ' + i;
record.Count = i;
resultObj.RecordList.push(record);
}
return resultObj;
};
return Report4Component;
}());
$(function () {
var report4Component = new Report4Component();
report4Component.ShowGrid();
report4Component.ShowData();
});
function StopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
}
else {
evt.cancelBubble = true;
}
}
Issue:
Any suggestion / help will be greatly appreciated.
It's the class selected that sets the checkbox tick etc. and by using a different class the selected class is no longer added.
You can just add both those classes instead, and it should work
select: {
style: 'multi',
selector: 'td:first-child',
className: 'selected-row selected'
}
FIDDLE
i am using jqGrid with CodeIgniter 2.1.0 .
The thing which is making me harassed is how to assign value to specific column on specific event
Suppose i am entering qty and rate in column value.....and when i loss focus from "rate" field.....the net amount should be calculated and displayed in amount field...
what i need to do here is to assign calculated value to amount field......but i am not getting any idea regarding how do i do it??
what i have done is given below :
var selIRow = 1;
var rowid='';
var iCol='';
$("#purchasedetailsgrid").jqGrid({
url: sitepath + 'purchase/purchase_grid',
datatype: 'json',
mtype: 'POST',
height:220,
width:500,
colNames:["","","Store Name","Item Name","Inner Pkg.","Outer Pkg.","Qty","Rate","Amount"],
colModel:[
{name: 'storeID_hidden_field', index:'storeID_hidden_field',hidden: true, editable: true,edittype: 'text',editrules: {edithidden:true}},
{name: 'itemID_hidden_field', index:'itemID_hidden_field',hidden: true, editable: true,edittype: 'text',editrules: {edithidden:true}},
{name:'store_id', index:'store_id',width:150,search:false,editable:true,editrules:{number:false,maxlength:10}},
{name:'item_id', index:'item_id',width:150,search:false,editable:true,editrules:{number:false,maxlength:10}},
{name:'inner_pkg', index:'inner_pkg',width:150,search:false,editable:true,editrules:{number:true,maxlength:5}},
{name:'outer_pkg', index:'outer_pkg',width:150,search:false,editable:true,editrules:{number:true,maxlength:5}},
{name:'qty', index:'qty',editable:true,width:85,search:false,editrules:{number:true,maxlength:5}},
{name:'rate', index:'rate',width:100,editable:true,search:false,editrules:{number:true,maxlength:10},
editoptions: {
dataInit: function (elem) { $(elem).focus(function () { this.select(); }) },
dataEvents: [
{
type: 'keydown',
fn: function (e) {
var key = e.charCode || e.keyCode;
if (key == 9)//tab
{
$('#amount').val();//here in val() i need to write the value of qty and rate field
}
}
}
]
}
},
{name:'amount', index:'amount',width:100,editable:true,search:false,editrules:{number:true,maxlength:10},
editoptions: {
dataInit: function (elem) { $(elem).focus(function () { this.select(); }) },
dataEvents: [
{
type: 'keydown',
fn: function (e) {
var key = e.charCode || e.keyCode;
if (key == 13)//enter
{
var grid = $('#purchasedetailsgrid');
//Save editing for current row
grid.jqGrid('saveRow', selIRow, false, sitepath + 'purchase/purchase_grid');
selIRow++;
//If at bottom of grid, create new row
//if (selIRow++ == grid.getDataIDs().length) {
grid.addRowData(selIRow, {});
//}
//Enter edit row for next row in grid
grid.jqGrid('editRow', selIRow, false, sitepath + 'purchase/purchase_grid');
}
}
}
]
}
}
],
pager: '#purchasedetailstoolbar',
rowNum:10,
rowList:[10,20,30],
sortname: 'inventory_id',
sortorder: 'desc',
viewrecords: true,
rownumbers: true,
gridview: true,
multiselect: false,
autoresize:true,
autowidth: true,
editurl: sitepath + 'purchase/purchase_grid',
toolbar: [true,"top"],
gridComplete: function ()
{
var grid = jQuery("#purchasedetailsgrid");
var ids = grid.jqGrid('getDataIDs');
if(ids == '')
{
grid.addRowData(selIRow, {});
grid.jqGrid('editRow', selIRow, false, sitepath + 'purchase/purchase_grid');
}
for (var i = 0; i < ids.length; i++)
{
}
},
caption: 'Purchase List',
});
jQuery("#purchasedetailsgrid").jqGrid('navGrid','#purchasedetailstoolbar',{view:false,edit:false,add:false,del:false,search: false});
jQuery("#purchasedetailsgrid").jqGrid('inlineNav','#purchasedetailstoolbar');
jQuery("#purchasedetailsgrid").jqGrid('filterToolbar',{stringResult:false,searchOnEnter : false},{autosearch: true});
var temp_purchase = $("#purchasedetailsgrid_header").html();
$("#t_purchasedetailsgrid").html(temp_purchase);
$("#refresh_purchasedetailsgrid").attr('title',"Reload Grid");
Now can anyone suggest me how will i get value from one column and assign it another?
Any suggestions will be appreciated.
Thnx in advance
You current code have many problems. For example you wrote that you need that amount will be calculated based on qty and rate, but you defined some dataEvents in 'rate' and 'amount' columns instead of 'qty' and 'rate' columns. The next problem that you use editRow method directly inside of gridComplete. So the buttons from the inlineNav toolbar will stay in the wrong status. One more problem is that you need to recompute the 'amount' based on 'qty' and 'rate' not only on the loss of focus from 'qty' and 'rate', but also on saving the values on Enter.
To make solving of above problems easier I wrote the demo which you can modify corresponds your exact requirements. The most important part of the demo you can find below:
var editingRowId = undefined,
recomputeAmount = function () {
var rate = $("#" + editingRowId + "_rate").val(),
qty = $("#" + editingRowId + "_qty").val(),
newAmount = parseFloat(rate) * parseFloat(qty);
$("#" + editingRowId + "_amount").val(isFinite(newAmount) ? newAmount : 0);
},
myEditParam = {
keys: true,
oneditfunc: function (id) {
editingRowId = id;
},
afterrestorefunc: function (id) {
editingRowId = undefined;
},
aftersavefunc: function (id) {
var $this = $(this),
rate = $this.jqGrid("getCell", id, "rate"),
qty = $this.jqGrid("getCell", id, "qty"),
newAmount = parseFloat(rate) * parseFloat(qty);
$this.jqGrid("setCell", id, "amount", newAmount);
editingRowId = undefined;
}
},
numInput = {
type: 'keydown',
fn: function (e) {
var key = e.which;
// allow only '0' <= key <= '9' or key = '.', Enter, Tab, Esc
if ((key < 48 || key > 57) && key !== $.ui.keyCode.PERIOD &&
key !== $.ui.keyCode.TAB && key !== $.ui.keyCode.ENTER && key !== $.ui.keyCode.ESCAPE) {
return false;
}
}
},
recompute = {
type: 'focusout',
fn: function (e) {
recomputeAmount();
}
};
$("#purchasedetailsgrid").jqGrid({
colModel: [
...
{name:'qty', index:'qty',editable:true,width:85,search:false,editrules:{number:true,maxlength:5},
editoptions: {
dataInit: function (elem) { $(elem).focus(function () { this.select(); }) },
dataEvents: [ numInput, recompute ]
}
},
{name:'rate', index:'rate',width:100,editable:true,search:false,editrules:{number:true,maxlength:10},
editoptions: {
dataInit: function (elem) { $(elem).focus(function () { this.select(); }) },
dataEvents: [ numInput, recompute ]
}
},
{name:'amount', index:'amount',width:100,editable:true,search:false,editrules:{number:true,maxlength:10}}
],
loadComplete: function () {
var gridIdSelector = '#' + $.jgrid.jqID(this.id);
if (this.rows.length > 1) {
//$(this).jqGrid('editRow', this.rows[1].id, myEditParam);
$(this).jqGrid('setSelection', this.rows[1].id, true);
setTimeout(function() {
// we should simulate click of the button not after the grid is loaded, but
// after the toolbar with the cliked button will be created by inlineNav
$(gridIdSelector + "_iledit").click();
}, 100);
} else {
setTimeout(function() {
// we should simulate click of the button not after the grid is loaded, but
// after the toolbar with the cliked button will be created by inlineNav
$(gridIdSelector + "_iladd").click();
}, 100);
}
}
});
jQuery("#purchasedetailsgrid").jqGrid('navGrid','#purchasedetailstoolbar',
{view:false,edit:false,add:false,del:false,search: false, refreshtitle: "Reload Grid"});
jQuery("#purchasedetailsgrid").jqGrid('inlineNav','#purchasedetailstoolbar',
{edit: true, add: true, editParams: myEditParam, addParams: {addRowParams: myEditParam}});
If it's needed I can comment unclear parts of the code.