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.
Related
i'm pretty new using datatables and amaze with good fiture in datatables for handling a lots of data. i have read the documentation but still don't get the answer, too much example make me confuse which one is fit for my problem.
so, i trying to generated button which can edit value of selected row, but i think to complex for doing a button each row, i made it more simple with hyperlink text generated each button and can edit selected row which taken the ID of selected row.
The problem is when i succeed with generating link each row, the id of row is undefined.
on comment code name try 1, my table not showing and keep processing for long time
and comment code name try 2, my table working but when i hit edit the value is undefined.
here is my code :
$(document).ready(function(){
var dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
var gender = $('#searchByGender').val();
var name = $('#searchByName').val();
data.searchByGender = gender;
data.searchByName = name;
}
},
'columns': [
{ data: 'id' },
{ data: 'nama' },
{ data: 'grade' },
{ data: 'dept' },
{ data: 'id' },
{ data: 'id',
render: function(data, type, row, meta)
{
//try 1 :
//var data = table.row( this ).data().id;
//return 'edit';
//try 2 :
//var i = row[0];
//return 'edit';
}
},
]
});
undefined ID Image, and
normally this should be ID ie:2200085 not undefined.
any help would be appreciated, sorry if the question just hit little scope but i think out there many people have same problem like me. Thankyou.
you are missing one step after columns[].
$(document).ready(function(){
var dataTable = $('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'ajaxfile.php',
'data': function(data){
var gender = $('#searchByGender').val();
var name = $('#searchByName').val();
data.searchByGender = gender;
data.searchByName = name;
}
},
'columns': [
{ data: 'id' },
{ data: 'nama' },
{ data: 'grade' },
{ data: 'dept' },
{ data: 'id' },
{ data: 'id',
render: function(data, type, row, meta)
{
//try 1 :
//var data = table.row( this ).data().id;
//return 'edit';
//try 2 :
//var i = row[0];
//return 'edit';
}
},
],
createdRow: function ( row, data, index ) {
$(row).attr('title','Category ID : '+data[0]);
$(row).attr('id',data[0]);
$(row).click(function(){
alert(this.id+' is clicked');
});
}
});
I have implemented jsGrid and did the Filtering server side.Now i want to send sorting parameter to server side and do the sorting on server side on the click of column.
This is how i implemented the grid -
var db = {
loadData: function(filter) {
var bFilter = [];
var d = $.Deferred();
console.log("sorting:", filter.sortField, filter.sortOrder);
for (var prop in filter) {
if (prop != "sortField" && prop != "sortOrder") {
bFilter.push({
"Name": prop,
"Value": filter[prop]
})
} else{
var sorting ={ "Name": filter["sortField"], "Type": filter["sortOrder"] };
}
}
$.ajax({
url: "http://abc/abc",
dataType: "json",
data: JSON.stringify({
"filter": bFilter,
"sorting": sorting
})
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
},
};
$("#jsGrid").jsGrid({
height: 300,
width: "100%",
filtering: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 2,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete the client?",
controller: db,
fields: [{
name: "Name",
type: "text",
width: 150
},
{
name: "Age",
type: "number",
width: 50
},
{
name: "Address",
type: "text",
width: 200
},
{
type: "control"
}
]
});
How would i call the same loaddata method on click of header for sorting to do the filtering and sorting together on server side.
How to disable the client side sorting and do it on serve side same like filtering.
If i set sorting:false it removes the click from the column headers.I want to keep that as well.
I was able to solve this by changing the sort function -
jsGrid.loadStrategies.DirectLoadingStrategy.prototype.sort = function () {
var filters = $("#tableId").jsGrid("getFilter");
var sorting = $("#tableId").jsGrid("getSorting");
this._grid.controller.loadData(filters, sorting);
}
I am working on JQgrid and trying to achieve some specific functionality. These functionalists are
1)inline update with message shown before update.
2)Multiple update
I tried to read jqgrid and got this code https://jsfiddle.net/OlegKi/byygepy3/11/ . Which is quite approximate to my requirement but it doesn't contain multiple update and message shown before update.
I tried to overwrite these code but maximum i reached is this https://jsfiddle.net/byygepy3/72/ but failed because multiple update only updating half of record and it doesn't show any message before updating either single row or multiple row.
code is inserting just allow me to ask question.
$(function () {
var myData = [
{ id: 10, ParameterName: "Test", ParameterValue: "" },
{ id: 20, ParameterName: "Test 1", ParameterValue: "" },
{ id: 30, ParameterName: "Test 2", ParameterValue: "" },
{ id: 40, ParameterName: "Test 2", ParameterValue: "" },
{ id: 50, ParameterName: "Test 2", ParameterValue: "" },
{ id: 60, ParameterName: "Test 2", ParameterValue: "" }
],
$grid = $("#list");
// change the text displayed on editrules: {required: true }
$.extend(true, $.jgrid.locales["en-US"].edit.msg, {
required: "No value was entered for this parameter!!!"
});
$grid.jqGrid({
datatype: "local",
data: myData,
colNames: ["", "Parameter Name", "Parameter Value"],
colModel: [
{ name: "act", template: "actions" }, // optional feature
{ name: "ParameterName" },
{ name: "ParameterValue", editable: true,
editoptions: { maxlength: 100 }, editrules: {required: true } }
],
cmTemplate: { autoResizable: true },
autoResizing: { compact: true },
pager: true,
pgbuttons: false, // disable page control like next, back button
pgtext: null, // disable pager text like 'Page 0 of 10'
viewrecords: true, // disable current view record text like 'View 1-10 of 100'
sortname: "Name",
iconSet: "fontAwesome",
caption: 'Parameters',
autowidth: true,
hidegrid: false,
inlineEditing: {
keys: true
},
singleSelectClickMode: "selectonly", // prevent unselect once selected rows
beforeSelectRow: function (rowid) {
// allow selection if saving successful
},
onSelectRow: function (rowid) {
$(this).jqGrid("editRow", rowid);
},
afterSetRow: function (options) {
var item = $(this).jqGrid("getLocalRow", options.rowid);
if (item != null) {
item.dirty = true;
}
},
navOptions: {
edit: false,
add: false,
search: false,
deltext: "Delete",
refreshtext: "Refresh"
},
inlineNavOptions: {
save: false,
savetext: "Save",
cancel: false,
restoreAfterSelect: false
},
formDeleting: {
// delete options
url: window.g_baseUrl + 'MfgTransactions_MVC/COA/Delete?',
beforeSubmit: function () {
// get value
var selRowId = $(this).jqGrid('getGridParam', 'selrow');
var parametricValue = $(this).jqGrid('getCell', selRowId, 'ParameterValue');
// check if empty
if (parametricValue === "") {
return [false, "Cannot delete: No value exists for this parameter"];
}
return [true, "Successfully deleted"];
},
delData: {
batchId: function () {
return $("#BatchId").val();
}
},
closeOnEscape: true,
closeAfterDelete: true,
width: 400,
msg: "Are you sure you want to delete the Parameter?",
afterComplete: function (response) {
if (response.responseText) {
alert("response.responseText");
}
//loadBatchListIntoGrid();
}
}
}).jqGrid('navGrid')
.jqGrid('inlineNav')
.jqGrid('navButtonAdd', {
caption: "Save Changed",
buttonicon: "fa-floppy-o",
onClickButton: function () {
var $self = $(this), i,
// savedRows array is not empty if some row is in inline editing mode
savedRows = $self.jqGrid("getGridParam", "savedRow");
for (i = 0; i < savedRows.length; i++) {
$self.jqGrid("saveRow", savedRows[i].id);
}
var localData = $(this).jqGrid("getGridParam", "data"),
dirtyData = $.grep(localData, function (item) {
return item.dirty;
});
alert(dirtyData.length > 0 ? JSON.stringify(dirtyData) : "no dirty data");
}
});
// make more place for navigator buttons be rwducing the width of the right part
var pagerIdSelector = $grid.jqGrid("getGridParam", "pager");
$(pagerIdSelector + "_right").width(100);
// make the grid responsive
$(window).bind("resize", function () {
$grid.jqGrid("setGridWidth", $grid.closest(".container-fluid").width());
}).triggerHandler("resize");
});
Free jqGrid supports a lot of callbacks, which will be used during saving the rows. You can use for example beforeSaveRow callback of inline editing, custom validation via editrules.custom callback function, beforeSelectRow and other. Additionally, your code seems to distinguish the initial empty value "" of ParameterValue column from any other values. The final code you should made yourself. I posted an example
beforeSelectRow: function (rowid) {
// allow selection if saving successful
var $self = $(this), i,
savedRows = $self.jqGrid("getGridParam", "savedRow");
for (i = 0; i < savedRows.length; i++) {
if (rowid !== savedRows[i].id) {
if (allowSaving.call(this, savedRows[i].id)) {
$self.jqGrid("saveRow", savedRows[i].id);
} else {
$self.jqGrid("restoreRow", savedRows[i].id);
}
}
}
return true;
},
with allowSaving function defined as
var allowSaving = function (rowid) {
var item = $(this).jqGrid("getRowData", rowid);
if (item.ParameterValue !== "") {
return confirm("Do you want to save \"" +
item.ParameterValue + "\" value in \"" +
item.ParameterName + "\"?");
} else {
return false;
}
};
It allows to ask the user to confirm the changes of ParameterName. Additionally the code of "Save Changed" button should be adjusted too.
See https://jsfiddle.net/OlegKi/byygepy3/74/
I have two functions that make two combobox with jqwidgets libraries. two functions are mostly like each other. I call them in $(document).ready(function (), but first function is work well and the second not even call. I put the codes those in one function, but the second part never run.
function f1() {
var url2 = "/autosuggest/JsonOrigins.aspx";
var source2 = {
datatype: "json",
datafields: [{
name: 'id'
}, {
name: 'name'
}],
url: url2,
async: false
};
var dataAdapter2 = new $.jqx.dataAdapter(source2);
// Create a jqxComboBox
$("#originsjqxWidget").jqxComboBox({
source: dataAdapter2,
multiSelect: true,
displayMember: "name",
valueMember: "id",
width: 145
});
$("#arrow").jqxButton({});
$("#arrow").click(function () {
$("#originsjqxWidget").jqxComboBox({
showArrow: false
});
});
$("#originsjqxWidget").on('change', function (event) {
var items = $("#originsjqxWidget").jqxComboBox('getSelectedItems');
var selectedItems = "Selected Items: ";
$.each(items, function (index) {
selectedItems += this.label;
if (items.length - 1 != index) {
selectedItems += ", ";
}
});
$("#log").text(selectedItems);
});
};
function f2() {
var url = "/autosuggest/JsonTag.aspx";
var source = {
datatype: "json",
datafields: [{
name: 'id'
}, {
name: 'name'
}],
url: url,
async: false
};
var dataAdapter = new $.jqx.dataAdapter(source);
$("#categoriesjqxWidget").jqxComboBox({
source: dataAdapter,
multiSelect: true,
displayMember: "name",
valueMember: "id",
width: 145
});
$("#arrow").jqxButton({});
$("#arrow").click(function () {
$("#jqxComboBox").jqxComboBox({
showArrow: false
});
});
$("#categoriesjqxWidget").on('change', function (event) {
var items = $("#categoriesjqxWidget").jqxComboBox('getSelectedItems');
var selectedItems = "Selected Items: ";
$.each(items, function (index) {
selectedItems += this.label;
if (items.length - 1 != index) {
selectedItems += ", ";
}
});
$("#log").text(selectedItems);
});
}
$(document).ready(function () {
f1();
f2();
});
Remove the ; after your first function.
try this
var source2 = {
datatype: "json";
datafields: [{
name: 'id'
}, {
name: 'name'
}],
url: url2,
async: false
};
I think you have an extra ; at the end of function f1
function f1(){
...
if (items.length - 1 != index) {
selectedItems += ", ";
}
});
$("#log").text(selectedItems);
});
};
I need to set an array of data after initializing select2. So I want to make something like this:
var select = $('#select').select2({});
select.data([
{id: 1, text: 'value1'},
{id: 1, text: 'value1'}
]);
But I get the following error:
Option 'data' is not allowed for Select2 when attached to a element.;
My HTML:
<select id="select" class="chzn-select"></select>
What should I use instead of a select element?
I need to set the source of items for search
In onload:
$.each(data, function(index, value) {
$('#selectId').append(
'<option value="' + data[index].id + '">' + data[index].value1 + '</option>'
);
});
Make an <input type="hidden"> element and bind select2 to that. Using .select2 on a regular select box doesn't let you play with the data, it just mostly gives you the UI and post-selection methods.
Source:
Select2 Documentation
Source: https://select2.org/programmatic-control/add-select-clear-items
Add item:
var data = {
id: 1,
text: 'Barn owl'
};
var newOption = new Option(data.text, data.id, false, false);
$('#mySelect2').append(newOption).trigger('change');
Clear items:
$('#mySelect2').val(null).trigger('change');
For v4 you'll have to destroy and reconstruct select2 with updated data. Check https://github.com/select2/select2/issues/2830
I've recently had the scenario where changing one select2 object alters the contents of a second (parent - child groupings effectively). I used an ajax call to retrieve a new set of Json data, which was then picked up by the second select2 object. I've included the code below:
$("#group").on('change', function () {
var uri = "/Url/RetrieveNewResults";
$.ajax({
url: uri,
data: {
format: 'json',
Id: $("#group :selected").val()
},
type: "POST",
success: function (data) {
$("#groupchild").html('');
$("#groupchild").select2({
data: data,
theme: 'bootstrap',
placeholder: "Select a Type"
});
},
error: function () {
console.log("Error")
}
});
});
I found that I had to include the $("#groupchild").html('') in order to clear out the previous set of data in the second select2. Hope this helps.
You can rerender and trigger the select2
render select2
$('.select2').select2({
placeholder: 'Slect value',
allowClear: true
});
after need to change the data data
let dataChange = [
{
id: 0,
text: 'enhancement'
},
{
id: 1,
text: 'bug'
},
{
id: 2,
text: 'duplicate'
},
{
id: 3,
text: 'invalid'
},
{
id: 4,
text: 'wontfix'
}
];
rerender the select2
$('.select2').select2('destroy');
$('.select2').empty();
$('.select2').select2({
placeholder: 'Slect value',
allowClear: true,
data: dataChange
});
trigger select2
$('.select2').trigger('change');
Hope this is the answer for you :3
Here's what I did.
1. Extend select2
Select2.prototype.setAjax = function (ajaxOptions)
{
// Set the new ajax properties
var oAjaxOpts = this.options.get('ajax');
if (oAjaxOpts != undefined && oAjaxOpts != null)
{
for (var sKey in ajaxOptions)
{
oAjaxOpts[sKey] = ajaxOptions[sKey];
}
}
var DataAdapter = this.options.get('dataAdapter');
this.dataAdapter = new DataAdapter(this.$element, this.options);
}
2. Initialize as usual (for example --- yours could be different)
jHtmlFrag.select2({
dropdownParent: $(oData.jDiv),
placeholder: "Select Option",
allowClear: true,
minimumInputLength: 2,
ajax: {
url: "",
method: "POST",
dataType: 'json',
delay: 250,
processResults: function (oResults, params)
{
let page = params.page || 1;
// console.log(oResults, (params.page * 10));
return {
results: oResults.data,
pagination: {
more: (page * 10) < oResults.recordsFiltered
}
};
}
}
}).val(null).trigger('change');
3. Set Ajax options dynamically when you feel like by calling the new extension func
jCombo.select2('setAjax', {
url: sUrl,
data: function (params)
{
let query = {
search: params.term,
type: params._type,
page: params.page || 1,
}
return query;
},
});