How to sort time column in jsgrid? - jsgrid

We are binding a table using jqgrid. We have the first column start as a time column with a 12-hour format. We are facing an issue with sorting this data. The data is sorted correctly but it is not taking am/pm into consideration. Below is our code for binding the jqgrid:
var newFieldsArray =
[
{ name: "ID", title: "ID", type: "number", width: "50px", visible: false },
{
name: "TimeStart", title: "Start", type: "customTime", width: "100px", validate: "required",
sorttype: "date",
formatter : {
date : {
AmPm : ["am","pm","AM","PM"],
}
},
// datefmt: "m/d/Y h:i A",
//sorttype: 'datetime', formatter: 'date', formatoptions: {newformat: 'd/m/y', srcformat: 'Y-m-d H:i:s'},
insertTemplate: function () {
var $result = jsGrid.fields.customTime.prototype.insertTemplate.call(this); // original input
$result.val(varendTime);
return $result;
},
itemTemplate: function (value, item) {
return "<b style='display:none'>" + Date.parse(item.StartDate) + "</b><span>" + (item.TimeStart) + "</span>";
}
},
{
name: "TimeEnd", title: "End", type: "customTime", width: "100px", validate: "required",sorttype: "date", datefmt: "h:i"
},
{ name: "TimeTotal", title: "Time", type: "text", width: "50px", readOnly: true },
{
name: "CoilPO", title: "Coil PO", type: "text", width: "50px", validate: "required",
insertTemplate: function () {
var $result = jsGrid.fields.text.prototype.insertTemplate.call(this); // original input
$result.val(varlot);
return $result;
}
},
{ name: "Joints", title: "Joints", type: "integer", width: "60px" },
{ name: "CommercialGrade", title: "Commercial Grade", type: "integer", width: "80px" },
{ name: "QAHold", title: "QA Hold", type: "integer", width: "60px" },
{ name: "Rejected", title: "Reject", type: "integer", width: "60px" },
{ name: "ActionTaken", title: "Reason of Delay / Action Taken", type: "text", width: "120px" },
{
name: "ClassId", title: "Class",
type: "select", items: classDataArr,//classData.filter(function(n){return classdt.indexOf(n.Id) != -1 }),//classData,
valueField: "Id", textField: "Title",
insertTemplate: function () {
debugger;
var taxCategoryField = this._grid.fields[12];
var $insertControl = jsGrid.fields.select.prototype.insertTemplate.call(this);
var classId = 0;
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-insert").empty().append(taxCategoryField.insertTemplate());
$insertControl.on("change", function () {
debugger;
var classId = parseInt($(this).val());
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-insert").empty().append(taxCategoryField.insertTemplate());
});
return $insertControl;
},
editTemplate: function (value) {
var taxCategoryField = this._grid.fields[12];
var $editControl = jsGrid.fields.select.prototype.editTemplate.call(this, value);
var changeCountry = function () {
var classId = parseInt($editControl.val());
var taxCategory = $.grep(voiceData, function (team) {
return (team.ClassId) === classId && (team.StationId) == parseInt($('#ddlEquipmentName').val());
});
taxCategoryField.items = taxCategory;
$(".tax-edit").empty().append(taxCategoryField.editTemplate());
};
debugger;
$editControl.on("change", changeCountry);
changeCountry();
return $editControl;
}
},
{
name: "VoiceId", title: "Voice", type: "select", items: voiceData,
valueField: "Id", textField: "Title", width: "120px", validate: "required",
insertcss: "tax-insert",
editcss: "tax-edit",
itemTemplate: function (teamId) {
var t = $.grep(voiceData, function (team) { return team.Id === teamId; })[0].Title;
return t;
},
},
{ name: "Remarks", title: "Remarks", type: "text", width: "110px" },
{ name: "control", type: "control" }
];
hoursGrid.jsGrid("option", "fields", newFieldsArray);
Below is two screenshots of data that appear when we sort:
Can someone tell me what we are doing wrong?

You're mixing up jsGrid and jqGrid. The way to achieve it in jsGrid is using the built-in sorter jsGrid.sortStrategies.date, I added an example below.
As commented by #Tomy Tomov (the creator of jqGrid), you're using jsGrid, not jqGrid. This is evident both by your code and by the UI in the screenshot.
Specifically, you took the date sorter of jqGrid and used it in your jsGrid code, but (of course) it's not supported there. You can go ahead and look in jsGrid source for AmPm which you used - and see it's not there.
So how to do it in jsGrid?
Just pass the built-in sorter jsGrid.sortStrategies.date to the sorter property. However, it does require Date objects, so if you only got time strings, you'll have to convert those to dates.
Below is a quick demo (jsfiddle), click the date column title to sort:
Note that getData gets a function parameter that is responsible to get all data as Date objects, and that the value of isUTC depends on whether you actually use it
$(document).ready(function () {
const dataFunc = getDataTimes;
$("#jsGrid").jsGrid({
width: "100%",
data: getData(dataFunc),
sorting: true,
fields: [{
name: "name",
type: "text",
width: 50
}, {
name: "date",
type: "date",
width: 50,
sorter: jsGrid.sortStrategies.date,
cellRenderer: (value, item) => {
const withYear = false;
const isUTC = dataFunc == getDataTimes;
return renderDateTime(value, item, withYear, isUTC);
}
}
]
});
});
function getData(getDates) {
const data = [
{name: "a"}, {name: "b"}, {name: "c"},
{name: "d"}, {name: "e"}, {name: "f"},
];
const dates = getDates();
for (let i = 0; i < dates.length; i++) {
data[i].date = dates[i];
}
return data;
}
function getDataDates() {
const date1 = new Date(2022, 10, 1, 4, 50);
const date2 = new Date(2022, 10, 1, 8, 50);
const date3 = new Date(2022, 10, 1, 15, 50);
const date4 = new Date(2021, 10, 1, 4, 50);
const date5 = new Date(2021, 10, 1, 8, 50);
const date6 = new Date(2021, 10, 1, 15, 50);
return [date1, date2, date3, date4, date5, date6];
}
function getDataTimes() {
const time1 = "3:50 AM";
const time2 = "8:50 AM";
const time3 = "4:50 AM";
const time4 = "3:50 PM";
const time5 = "8:50 PM";
const time6 = "4:50 PM";
const times = [time1, time2, time3, time4, time5, time6];
return times.map(t => convertTime12to24(t));
}
function convertTime12to24(time12h) {
const [time, modifier] = time12h.split(' ');
let [hours, minutes] = time.split(':');
if (modifier === 'PM') {
hours = parseInt(hours, 10) + 12;
}
return new Date(Date.UTC(2022,0,1,hours, minutes));
}
function renderDateTime(value, row, withYear, isUTC) {
return `<td>${getDateTimeAsString(value, withYear, isUTC)}</td>`;
}
function getDateTimeAsString(date, withYear, isUTC) {
var options = {
hour: 'numeric',
minute: 'numeric',
hour12: true
};
if (withYear) {
options.withYear = 'numeric';
}
if (isUTC) {
options.timeZone = 'UTC';
}
return date.toLocaleString('en-US', options);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" rel="stylesheet">
<div id="jsGrid" class="jsgrid"></div>

Let me give it a try, we have 2 options to perform Sorting operation in JsGrid:
1.Custom Field (Topic Name you can refer below link)
Reference Link :http://js-grid.com/docs/#grid-fields
In this, you can define custom property in your config and extend it.
You can use sorter property and call your user defined function werein you can logic to sort date with time stamps directly.
2.Sorting Strategies (Topic Name you can refer below link)
Reference Link :http://js-grid.com/docs/#grid-fields
In this, you can create your custom objects and then apply sorting strategies of date directly on to the object to perform sorting operation as per your logic.

Related

jsGrid has 2 headers when inserting is added

Forgive me I am new to using the jsGrid so this might be a stupid problem but...
I have a jsGrid with several columns. One column is a date field. I want to add a date picker instead of the input field for it now.
I added the code for the date picker and ran the code and now the jsGrid has 2 headers. One with the input field for the date and the one below with the date picker. I found that as soon as I add inserting: true that is when the 2 headers show.
Please let me know what I am doing wrong.
Here is my code.
$(function () {
var MyDateField = function (config) {
jsGrid.Field.call(this, config);
};
MyDateField.prototype = new jsGrid.Field({
sorter: function (date1, date2) {
return new Date(date1) - new Date(date2);
},
itemTemplate: function (value) {
return new Date(value).toDateString();
},
insertTemplate: function (value) {
return this._insertPicker = $("<input>").datepicker({ defaultDate: new Date() });
},
editTemplate: function (value) {
return this._editPicker = $("<input>").datepicker().datepicker("setDate", new Date(value));
},
insertValue: function () {
return this._insertPicker.datepicker("getDate").toISOString();
},
editValue: function () {
return this._editPicker.datepicker("getDate").toISOString();
}
});
jsGrid.fields.myDateField = MyDateField
$("#jsGrid").jsGrid({
width: "100%",
inserting: true,
filtering: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
rowClass: function (item, itemIndex) {
if (item.DisplayOrder == 1) {
return 'past-due'
}
if (item.DisplayOrder == 2) {
return 'second-notice'
}
pageButtonCount: 5,
controller: controller,
fields: [{
name: "Task Number",
type: "number",
itemTemplate: function (value, item) {
return $("<a>").attr("href", "TaskDetail.aspx?id=" + value).text(value);
},
align: "center"
}, {
name: "Requirement",
type: "text",
itemTemplate: function (value, item) {
return $("<a>").attr("href", "RequirementDetail.aspx?id=" + item.req_id).text(value);
},
width : "350px"
}, {
name: "MERM",
type: "text",
itemTemplate: function (value, item) {
return $("<a>").attr("href", "MERM_Detail.aspx?id=" + item.merm_id).text(value);
}
}, {
name: "Due Date",
type: "myDateField",
width: 80,
align: "center"
}, {
name: "Action Required",
type: "select",
items: actions,
valueField: "name",
textField: "name"
}, {
name: "Workflow Step",
title: "Workflow Step",
type: "select",
align: "center",
items: workflowsteps2,
valueField: "id",
textField: "DisplayName"
}, {
name: "Status",
type: "select",
align: "center",
items: statii2,
valueField: "id",
textField: "DisplayName"
}, {
name: "Importance",
type: "select",
items: importances,
valueField: "id",
textField: "DisplayName",
itemTemplate: function (value, item) {
return $("<div>").addClass(item.Importance == 1 ? 'critical-importance' : item.Importance == 2 ? 'high-importance' : item.Importance == 3 ? 'low-importance' : '').text(item.Importance == 1 ? 'Critical' : item.Importance == 2 ? 'High' : item.Importance == 3 ? 'Low' : '');
}
}, {
visible:false,
name: "Marked Ready for Review Date",
type: "text",
itemTemplate: function (value, item) {
if (value === "NULL") {
return "";
}
return value;
}
}, {
visible:false,
name: "QA Completed Date",
type: "text",
itemTemplate: function (value, item) {
if (value === "NULL") {
return "";
}
return value;
}
}, {
name: "Completed Date",
type: "text",
itemTemplate: function (value, item) {
if (value === "NULL") {
return "";
}
return value;
}
}],
onDataLoaded: function () {
$('#loading').hide();
}
});
});
}
The "Due Date" is the field I am talking about.
Thank you for the help.

Jqgrid cascading dropdown

Using jqgrid free latest version 4.15.2
I am trying to make cascading drop down from db.
I tried the sample as posted by #Oleg
jqgrid incorrect select drop down option values in edit box
But this is for older version of jqgrid and does not work fully while using latest version of jqgrid.
var countries = { "UsId": "US", "UkId": "UK" },
statesOfUS = { "AlabamaId": "Alabama", "CaliforniaId": "California", "FloridaId": "Florida", "HawaiiId": "Hawaii" },
statesOfUK = { "LondonId": "London", "OxfordId": "Oxford" },
states = $.extend({}, statesOfUS, statesOfUK),
allCountries = $.extend({"": "All"}, countries),
allStates = $.extend({"": "All"}, states),
// the next maps provide the states by ids to the contries
statesOfCountry = {
"": states,
"UsId": statesOfUS,
"UkId": statesOfUK
},
The entire code can be seen in fiddle below
https://jsfiddle.net/svnL4Lsv/
The issue is during the add form the second dropwdown shows all states instead of showing as per country
Secondly during the edit the second dropdown again shows all states and not as per the row value
Its just when I change the first dropdown does the second dropdown filters and works.
----------Updated
editoptions: {
// value: countries,
dataInit: dataInitApp,
dataEvents: dataEventsApp,
dataUrl: '#Url.Action("GetData", "Home")',
}
Controller code:
public enum Countries
{
USA = 1,
UK = 2
}
public enum State
{
Alabama = 1,
Florida = 2
London = 3
}
public JsonResult GetData()
{
var type = typeof(Helpers.UsersEnum.Countries);
var jsonData = Enum.GetNames(type)
.Select(name => new
{
Id = (int)Enum.Parse(type, name),
Name = name
})
.ToArray();
return Json(jsonData);
}
I call the above to populate my dropdown.
Also below is the json that is returned back:
[0]: {Id=1, Name="USA"}
[1]: {Id=2, Name="UK"}
[0]: {Id=1, Name="Alabama "}
[1]: {Id=2, Name="Florida"}
[2]: {Id=3, Name="London"}
In case of usage free jqGrid you can use a little simplified code
$(function () {
"use strict";
var countries = "usId:US;ukId:UK",
allStates = "alabamaId:Alabama;californiaId:California;floridaId:Florida;hawaiiId:Hawaii;londonId:London;oxfordId:Oxford",
// the next maps provide the states by ids to the countries
statesOfCountry = {
"": allStates,
usId: "alabamaId:Alabama;californiaId:California;floridaId:Florida;hawaiiId:Hawaii",
ukId: "londonId:London;oxfordId:Oxford"
},
mydata = [
{ id: "10", country: "usId", state: "alabamaId", name: "Louise Fletcher" },
{ id: "20", country: "usId", state: "floridaId", name: "Jim Morrison" },
{ id: "30", country: "ukId", state: "londonId", name: "Sherlock Holmes" },
{ id: "40", country: "ukId", state: "oxfordId", name: "Oscar Wilde" }
],
$grid = $("#list"),
changeStateSelect = function (countryId, countryElem) {
// build "state" options based on the selected "country" value
var $select, selectedValues,
$countryElem = $(countryElem),
isInSearchToolbar = $countryElem.parent().parent().parent().parent().hasClass("ui-search-table");
// populate the subset of countries
if (isInSearchToolbar) {
// searching toolbar
$select = $countryElem.closest("tr.ui-search-toolbar")
.find(">th.ui-th-column select#gs_list_state");
} else if ($countryElem.is(".FormElement")) {
// form editing
$select = $countryElem.closest("form.FormGrid")
.find("select#state.FormElement");
} else {
// inline editing
$select = $("select#" + $.jgrid.jqID($countryElem.closest("tr.jqgrow").attr("id")) + "_state");
}
if ($select.length > 0) {
selectedValues = $select.val();
if (isInSearchToolbar) {
$select.html("<option value=\"\">All</option>");
} else {
$select.empty();
}
$.jgrid.fillSelectOptions($select[0], statesOfCountry[countryId], ":", ";", false, selectedValues);
}
},
dataInitCountry = function (elem) {
setTimeout(function () {
$(elem).change();
}, 0);
},
dataEventsCountry = [
{ type: "change", fn: function (e) { changeStateSelect($(e.target).val(), e.target); } },
{ type: "keyup", fn: function (e) { $(e.target).trigger("change"); } }
],
cancelInlineEditingOfOtherRows = function (rowid) {
var $self = $(this), savedRows = $self.jqGrid("getGridParam", "savedRow");
if (savedRows.length > 0 && rowid !== savedRows[0].id) {
$self.jqGrid("restoreRow", savedRows[0].id);
}
};
$grid.jqGrid({
data: mydata,
datatype: "local",
colNames: [ "Name", "Country", "State" ],
colModel: [
{ name: "name", width: 180 },
{ name: "country", formatter: "select", stype: "select", edittype: "select",
searchoptions: {
noFilterText: "Any",
dataInit: dataInitCountry,
dataEvents: dataEventsCountry
},
editoptions: {
value: countries,
dataInit: dataInitCountry,
dataEvents: dataEventsCountry
}},
{ name: "state", formatter: "select", stype: "select", edittype: "select",
editoptions: { value: allStates }, searchoptions: { noFilterText: "Any" } }
],
cmTemplate: { width: 100, editable: true },
onSelectRow: cancelInlineEditingOfOtherRows,
ondblClickRow: function (rowid) {
cancelInlineEditingOfOtherRows.call(this, rowid);
$(this).jqGrid("editRow", rowid);
},
inlineEditing: {
keys: true
},
formEditing: {
onclickPgButtons: function (whichButton, $form, rowid) {
var $self = $(this), $row = $($self.jqGrid("getGridRowById", rowid)), countryId;
if (whichButton === "next") {
$row = $row.next();
} else if (whichButton === "prev") {
$row = $row.prev();
}
if ($row.length > 0) {
countryId = $self.jqGrid("getCell", $row.attr("id"), "country");
changeStateSelect(countryId, $form.find("#country")[0]);
}
},
closeOnEscape: true
},
searching: {
searchOnEnter: true,
defaultSearch: "cn"
},
navOptions: {
del: false,
search: false
},
iconSet: "fontAwesome",
sortname: "name",
sortorder: "desc",
viewrecords: true,
rownumbers: true,
pager: true,
pagerRightWidth: 85, // fix wrapping or right part of the pager
caption: "Demonstrate dependent selects (inline editing on double-click)"
})
.jqGrid("navGrid")
.jqGrid("filterToolbar");
});
see https://jsfiddle.net/OlegKi/svnL4Lsv/3/

setData Series Highchart using Ajax and CodeIgniter

I want to redraw and update data Highcart based on click button with ajax. This code still not working.
$('#chartday').on('click', function() {
$('#my_start_date').datepicker();
$('#my_end_date').datepicker();
var p_id_resto = $('#p_id_resto').val();
var start_date = $('#my_start_date').val();
var end_date = $('#my_end_date').val();
var idResto = JSON.stringify(p_id_resto);
var startDate = JSON.stringify(start_date);
var endDate = JSON.stringify(end_date);
var base_url = '<?php echo base_url();?>main2nd/charts_day';
console.log('get Id resto = ' + idResto);
console.log('get Start date = ' + startDate);
console.log('get URL = ' + base_url);
$.ajax({
url: base_url,
type: 'POST',
dataType: "json",
data : {p_id_resto : idResto,
start_date : startDate,
end_date : endDate},
}).done(function(result) {
console.log(result.data_stock);
chart.series[0].setData(['BD', result.data_stock['BD']],
['BDF',result.data_stock['BDF']],
['BP',result.data_stock['BP']],
['BPF',result.data_stock['BPF']],
['AD',result.data_stock['AD']],
['ADF',result.data_stock['ADF']],
['AP',result.data_stock['AP']],
['APF',result.data_stock['APF']],
['SB',result.data_stock['SB']],
['SRW',result.data_stock['SRW']], false
);
});
});
});
This my series highchart:
var chart = Highcharts.chart('reportChart', {
chart: {
type: 'column'
},
title: {
text: ''
},
subtitle: {
text: ''
},
series: [{
name: 'STOCK',
color: "#2a82ff",
data: [],
dataLabels: {
enabled: true,
color: '#045396',
align: 'center',
formatter: function() {
return Highcharts.numberFormat(this.y, 0);
},
y: 0,
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif',
position: 'relative'
}
}
},
{
name: 'SALES',
color: "teal",
data: []
}]
}
This My controller
function charts_day(){
$n_id_resto= json_decode($this->input->post('p_id_resto'));<br/>
$start_date= json_decode($this->input->post('start_date'));<br/>
$end_date= json_decode($this->input->post('end_date'));<br/>
$data1['data_sales'] = $this->Model_All->getSumSales($n_id_resto, $start_date, $end_date);<br/>
$data2['data_stock'] = $this->Model_All->charts_stokCbg($n_id_resto,$start_date, $end_date);<br/>
$dataMerge = array_merge($data1, $data2);$this->output->set_content_type('application/json')->set_output(json_encode($dataMerge),JSON_NUMERIC_CHECK);
}
Data still not display correctly in highchart.
I am sure using comment above
$this->output->set_content_type('application/json')->set_out‌​put(json_encode($dat‌​aMerge,JSON_NURIC_‌​CMEHECK));
you will get
Object { BD: 8, BDF: 10, BP: 10, BPF: 10, AD: 10, ADF: 10, AP: 10, APF: 10, SB: 10, SRW: 10 }
Now you have to process data as required by highcharts
var data={ BD: "8", BDF: "10", BP: "10", BPF: "10", AD: "10", ADF: "10", AP: "10", APF: "10", SB: "10", SRW: "10" }
var series_data=[]; //creating empty array for highcharts series data
Object.keys(data).map(function(item, key) {
series_data.push({name:item,y:Number(data[item])}) ; //Number(data[item]) converts string to number.Not required if already done using JSON_NUMERIC‌​_CHECK
});
console.log(series_data);// check how data is formed. you can do same in php by creating object array in php
Fiddle demonstration

jQGrid - "reloadGrid" - Keep Position

I'm trying to 'refresh' or 'reload' a grid and keep the row which has focus after the grid has been reloaded.
I've tried to do it as follows:-
var rowId = $("#dispatch").jqGrid('getGridParam','selrow');
var thisRow = (parseInt(rowId) + parseInt(1));
$("#dispatch").trigger("reloadGrid");
setTimeout(function(){
$("#dispatch").setSelection(thisRow);
}, 151);
But you can see it just from position #1 to the new position.
Is there any other way of reloading the grid and keeping focus position?
Tried:-
// Display Current Jobs
$('#btn-current').bind('click', function() {
$.ajax({
type: 'GET',
url: 'scripts/php/jobs.controller.php',
data: "id=" + "current",
success: function(data){
allButtons.removeClass('active');
$('#btn-current').addClass('active');
$("#dispatch").trigger("reloadGrid", [{current:true}]);
}
});
});
Grid:-
$(function () {
var lastsel2
var rowsToColor = [];
$("#dispatch").jqGrid({
url: 'scripts/xml/jobs.xml',
datatype: "xml",
xmlReader: {
root:"joblist",
row:"job",
repeatitems:false,
},
colNames: ["Time", "Car", "Status", "P", "Pickup", "Zone", "Destination", "Fare", "Name", "Type", "Tel", "Comments", "Account No", "Allow Time", "Tariff", "Email", "Driver Fare", "Driver Extras", "Customer Extras", "Driver", "Driver Comments", "Reference No", "Payment", "From No", "From Street", "From PostCode", "To No", "To Street", "To PostCode", "Account Name", "Flight No", "From Zone No", "To Zone No"],
colModel: [
{ name: "bookingdatetime", width: 55, editable: true },
{ name: "car", width: 45, editable: true },
{ name: "jbmessage", width: 60 },
{ name: "prebooking", width: 10 },
{ name: "pickup", width: 359, editable: true, classes:"grid-col"},
{ name: "zone", width: 50 },
{ name: "dropoff", width: 359, sortable: false, editable: true },
{ name: "customerfare", width: 76, editable: true },
{ name: "passname", width: 100, editable: true },
{ name: "cartype", width: 50, editable: true, },
{ name: "tel", width: 100, editable: true },
{ name: "comments", width: 150 },
{ name: "accountno", hidden: true },
{ name: "allowtime", hidden: true },
{ name: "tarif", hidden: true },
{ name: "emailaddress", hidden: true },
{ name: "driverfare", hidden: true },
{ name: "driverextras", hidden: true },
{ name: "customerextras", hidden: true },
{ name: "driver", hidden: true },
{ name: "comments1", hidden: true },
{ name: "referenceno", hidden: true },
{ name: "payment", hidden: true },
{ name: "fromno", hidden: true },
{ name: "fromstreet", hidden: true },
{ name: "frompostcode", hidden: true },
{ name: "tono", hidden: true },
{ name: "tostreet", hidden: true },
{ name: "topostcode", hidden: true },
{ name: "customer", hidden: true },
{ name: "flightno", hidden: true },
{ name: "fromzoneno", hidden: true },
{ name: "tozoneno", hidden: true }
],
loadComplete: function (){
var rowIds = $('#dispatch').jqGrid('getDataIDs');
for (i = 1; i <= rowIds.length; i++) {//iterate over each row
rowData = $('#dispatch').jqGrid('getRowData', i);
//set background style if Payment = Account
if (rowData['payment'] == 'Acc') {
$('#dispatch').jqGrid('setRowData', i, false, "yellow");
}
if (rowData['payment'] == 'CC') {
$('#dispatch').jqGrid('setRowData', i, false, "purple");
}
if (rowData['cartype'] == 'Est') {
$('#dispatch').jqGrid('setRowData', i, false, "green");
}
if (rowData['cartype'] == '8B' || rowData['cartype'] == 'Bus') {
$('#dispatch').jqGrid('setRowData', i, false, "red");
}
if (rowData['car'] == '00') {
$('#dispatch').jqGrid('setRowData', i, false, "cancel");
}
}
},
pager: "#pager",
loadui: 'disable',
rowNum: 50,
rowList: [10, 20, 30],
sortname: "invid",
sortorder: "desc",
viewrecords: true,
gridview: true,
autoencode: true,
width: null,
shrinkToFit: false,
height: 647,
scrollOffset: 0,
altRows:true,
altclass:'myAltRowClass',
onSelectRow: function (id, status) {
$('#txt-car-number').focus();
$('body').keyup(function (e) {
if (status && e.keyCode == 66 && $("#booking-docket").dialog("isOpen") === false) {
populateDocket();
$("#booking-docket").dialog('open');
}
});
},
gridComplete: function () {
$("#dispatch").setSelection(0, true);
},
});
$("#dispatch").jqGrid('setGridParam', {ondblClickRow: function(rowid,iRow,iCol,e){
populateDocket();
$("#booking-docket").dialog('open');
}});
$("#dispatch").jqGrid('bindKeys');
function populateDocket() {
var rowId =$("#dispatch").jqGrid('getGridParam','selrow');
var rowData = jQuery("#dispatch").getRowData(rowId);
var bookingdatetime = rowData['bookingdatetime'];
var car = rowData['car'];
var fromno = rowData['fromno'];
var fromstreet = rowData['fromstreet'];
var frompostcode = rowData['frompostcode'];
var tono = rowData['tono'];
var tostreet = rowData['tostreet'];
var topostcode = rowData['topostcode'];
var customerfare = rowData['customerfare'];
var passname = rowData['passname'];
var cartype = rowData['cartype'];
var tel = rowData['tel'];
var comments = rowData['comments'];
var accountno = rowData['accountno'];
var allowtime = rowData['allowtime'];
var tariff = rowData['tarif'];
var email = rowData['emailaddress'];
var driverFare = rowData['driverfare'];
var driverExtras = rowData['driverextras'];
var customerExtras = rowData['customerextras'];
var driver = rowData['driver'];
var commentsdrv = rowData['comments1'];
var referenceno = rowData['referenceno'];
var payment = rowData['payment'];
var accountname = rowData['customer'];
var flightno = rowData['flightno'];
var prebook = rowData['prebooking'];
var bookedby = rowData['bookedby'];
var date = bookingdatetime.split(' ');
var hour = date[1].substr(0,2)
var minute = date[1].substr(6,5)
$('#txt-date').val(date[0]);
$('#txt-hour').val(hour);
$('#txt-min').val(minute);
$('#txt-car').val(car);
$('#txt-pickup-hn').val(fromno);
$('#txt-pickup').val(fromstreet);
$('#txt-destination-hn').val(tono);
$('#txt-destination').val(tostreet);
$('#txt-client-fare').val(customerfare);
$('#txt-passenger').val(passname);
$('#txt-cartype').val(cartype);
$('#txt-telephone').val(tel);
$('#txt-general').val(comments);
$('#txt-account').val(accountno);
$('#txt-lead').val(allowtime);
$('#txt-tariff').val(tariff);
$('#txt-email').val(email);
$('#txt-drv-fare').val(driverFare);
$('#txt-account-name').val(accountname);
$('#txt-driver').val(driver);
$('#txt-office').val(commentsdrv);
$('#p-reference-no').html('-'+referenceno+'-');
$('#txt-payment').val(payment);
$('#txt-flight-no').val(flightno);
$('#txt-prebook').val(prebook);
$('#txt-bookedby').val(bookedby);
}
// Navigate Grids
$(document).keypress(function(e) {
if(e.keyCode == 40) { //down arrow
$('#nextElementId').click();
}
if(e.keyCode == 38) { //up arrow
$('#previousElementId').click();
}
});
$(document).keypress(function(e)
{
if(e.keyCode == 38 || e.keyCode == 40) //up/down arrow override
{
var gridArr = $('#dispatch').getDataIDs();
var selrow = $('#dispatch').getGridParam("selrow");
var curr_index = 0;
for(var i = 0; i < gridArr.length; i++)
{
if(gridArr[i]==selrow)
curr_index = i;
}
if(e.keyCode == 38) //up
{
if((curr_index-1)>=0)
$('#dispatch').resetSelection().setSelection(gridArr[curr_index-1],true);
}
if(e.keyCode == 40) //down
{
if((curr_index+1)<gridArr.length)
$('#dispatch').resetSelection().setSelection(gridArr[curr_index+1],true);
}
}
});
XML DATA:-
<?xml version="1.0"?>
<joblist resultcount="100">
<job id="0">
<pickup>26 CHIPPENHAM MEWS W9 2AN</pickup><dropoff>BREWER STREET W1F 0RJ</dropoff><bookingdatetime>14/05/2014 10:29:19</bookingdatetime><car></car><jbmessage></jbmessage><zone>MOUNTAIN</zone><customerfare>12</customerfare><passname>ele</passname><cartype>Car</cartype><tel>07771764901</tel><comments></comments><accountno></accountno><allowtime>10</allowtime><tarif>1</tarif><emailaddress></emailaddress><driverfare>12</driverfare><driverextras>0</driverextras><customerextras>0</customerextras><driver></driver><comments1></comments1><referenceno>221194</referenceno><payment>Cash</payment><fromno>26</fromno><fromstreet>CHIPPENHAM MEWS</fromstreet><frompostcode>W9 2AN</frompostcode><tono></tono><tostreet>BREWER STREET</tostreet><topostcode>W1F 0RJ</topostcode><prebooking>X</prebooking><customer></customer><flightno></flightno><bookedby>SAJJAD</bookedby><fromzoneno>27</fromzoneno><tozoneno>29</tozoneno></job><job id="1"><pickup>7 FOSBURY MEWS W23JE</pickup><dropoff>HEATHROW TER(T5) TW6 2GA</dropoff><bookingdatetime>13/05/2014 20:57:40</bookingdatetime><car>4</car><jbmessage>PAloc</jbmessage><zone>BALDWIN</zone><customerfare>41</customerfare><passname>BLOECKER</passname><cartype>MPV</cartype><tel>07435358308</tel><comments></comments><accountno></accountno><allowtime>15</allowtime><tarif>2</tarif><emailaddress></emailaddress><driverfare>41</driverfare><driverextras>0</driverextras><customerextras>0</customerextras><driver></driver><comments1></comments1><referenceno>220938</referenceno><payment>Cash</payment><fromno>7</fromno><fromstreet>FOSBURY MEWS</fromstreet><frompostcode>W23JE</frompostcode><tono></tono><tostreet>HEATHROW TER(T5)</tostreet><topostcode>TW6 2GA</topostcode><prebooking>X</prebooking><customer></customer><flightno></flightno><bookedby>SHEERAZ</bookedby><fromzoneno>21</fromzoneno><tozoneno>196</tozoneno>
</job>
</joblist>
Instead of usage setSelection inside of setTimeout you need just use additional parameter of reloadGrid: current:true. See the answer for more details.
UPDATED: The code of gridComplete seems be the reason of your problem:
$("#dispatch").setSelection(0, true);
it resets the selection of the grid after reloading to the row with the id="0".
I would strictly recommend you to replace the code of loadComplete to much more effective rowattr callback. See the answer for the corresponding code example.
Additionally you should not bind $('body').keyup on every row selection. In the way you bind (register) more and more new keyup event handles without unbinding the previous one. I'm not sure what you want to do in the part of the code, but you should probably move the code outside of onSelectRow callback.
I don't see any reason to set ondblClickRow with respect of setGridParam after the grid is created. Instead of that you can just include ondblClickRow callback directly in the list of jqGrid option during creating the grid (like you defined loadComplete, onSelectRow and gridComplete callbacks).
I recommend you to use $(this) instead of $('#dispatch') inside of any jqGrid callback.

Cancel the update in inline kendo grid delete the row

I am using two kendo inline grid parent and child. child grid contains the list of products,when user select the products(multiple selection) from child grid and clicked to save button,it's inserted into an parent grid.
Child grid:
var selectedIds = {};
var ctlGrid = $("#KendoWebDataGrid3");
ctlGrid.kendoGrid({
dataSource: {
data:data1,
schema: {
model: {
id: 'id',
fields: {
select: {
type: "string",
editable: false
},
Qty: {
editable: true,
type: "number",
validation: { min: 1, required: true }
},
Unit: {
editable: false,
type: "string"
},
StyleNumber: {
editable: false,
type: "string"
},
Description: {
editable: false,
type: "string"
}
}
}
},
pageSize: 5
},
editable: 'inline',
selectable: "multiple",
sortable: {
mode: 'single',
allowUnsort: false
},
pageable: true,
columns: [{
field: "select",
title: " ",
template: '<input type=\'checkbox\' />',
sortable: false,
width: 35},
{
title: 'Qty',
field: "Qty",
width:90},
{
field: 'Unit',
title: 'Unit',
width: 80},
{
field: 'StyleNumber',
title: 'Style Number',
},
{
field: 'Description',
width: 230},
{command: [<!---{text:"Select" ,class : "k-button",click: selectProduct},--->"edit" ], title: "Command", width: 100 }
],
dataBound: function() {
var grid = this;
//handle checkbox change
grid.table.find("tr").find("td:first input")
.change(function(e) {
var checkbox = $(this);
var selected = grid.table.find("tr").find("td:first input:checked").closest("tr");
grid.clearSelection();
//persist selection per page
var ids = selectedIds[grid.dataSource.page()] = [];
if (selected.length) {
grid.select(selected);
selected.each(function(idx, item) {
ids.push($(item).data("id"));
});
}
})
.end()
.mousedown(function(e) {
e.stopPropagation();
})
//select persisted rows
var selected = $();
var ids = selectedIds[grid.dataSource.page()] || [];
for (var idx = 0, length = ids.length; idx < length; idx++) {
selected = selected.add(grid.table.find("tr[data-id=" + ids[idx] + "]") );
}
selected
.find("td:first input")
.attr("checked", true)
.trigger("change");
}
});
var grid = ctlGrid.data("kendoGrid");
grid.thead.find("th:first")
.append($('<input class="selectAll" type="checkbox"/>'))
.delegate(".selectAll", "click", function() {
var checkbox = $(this);
grid.table.find("tr")
.find("td:first input")
.attr("checked", checkbox.is(":checked"))
.trigger("change");
});
save button clicked Event
function selectProduct()
{
//Selecting child Grid
var gview = $("#KendoWebDataGrid3").data("kendoGrid");
//Getting selected rows
var rows = gview.select();
//Selecting parent Grid
var parentdatasource=$("#grid11").data("kendoGrid").dataSource;
var parentData=parentdatasource.data();
//Iterate through all selected rows
rows.each(function (index, row)
{
var selectedItem = gview.dataItem(row);
var selItemJson={id: ''+selectedItem.id+'', Qty:''+selectedItem.Qty+'',Unit:''+selectedItem.Unit+'',StyleNumber:''+selectedItem.StyleNumber+'',Description:''+selectedItem.Description+''};
//parentdatasource.insert(selItemJson);
var productsGrid = $('#grid11').data('kendoGrid');
var dataSource = productsGrid.dataSource;
dataSource.add(selItemJson);
dataSource.sync();
});
closeWindow();
}
Parent Grid:
var data1=[];
$("#grid11").kendoGrid({
dataSource: {
data:data1,
schema: {
model: { id: "id" ,
fields: {
Qty: { validation: { required: true } },
Unit: { validation: { required: true } },
StyleNumber: { validation: { required: true } },
Description: { validation: { required: true } }
}
}
},
pageSize: 5
},
pageable: true,
height: 260,
sortable: true,
toolbar: [{name:"create",text:"Add"}],
editable: "inline",
columns: [
{field: "Qty"},
{field: "Unit"},
{field: "StyleNumber"},
{field: "Description"},
{ command: ["edit", "destroy"], title: " ", width: "172px" }]
});
$('#grid11').data().kendoGrid.bind("change", function(e) {
$('#grid11').data().kendoGrid.refresh();
});
$('#grid11').data().kendoGrid.bind('edit',function(e){
if(e.model.isNew()){
e.container.find('.k-grid-update').click(function(){
$('#grid11').data().kendoGrid.refresh();
}),
e.container.find('.k-grid-cancel').click(function(){
$('#grid11').data().kendoGrid.refresh();
})
}
})
Adding data into parent grid work nicely,no issue,but when i select the parent grid add new row to edit then trigger the cancel button row was deleted.
I am not able to figure out the problem.please help me.
I found the error, hope can help you.
If you did not config the dataSource: schema: model's "id" field, when click edit in another row before update or click cancel, it will delete the row.
var dataSource = new kendo.data.DataSource({
...
schema: {
model: {
id:"id", // Look here, if you did not config it, issue will happen
fields: {...
...}
}
}
...
})
I have the same issue, and I config cancel like :
...
cancel: function(e) {
this.refresh();
},
...
I don't think it's the best way, but it's working.
Hope another people can give us a better way.
after saving I call $('#grid').data('kendoGrid').dataSource.read();
that cancels the edit row and reads any changes.
Still doesn't seem to be fixed.
I'm addressing it with 'preventDefault()'. This may require explicit closing of window as a consequence.
cancel: function (e) {
// Not sure why this is needed but otherwise removes row...
e.preventDefault();
e.container.data("kendoWindow").close();
},
schema: {
model: { id: "StyleNumber" // "Any ID Field from the Fields list" ,
fields: {
Qty: { validation: { required: true } },
Unit: { validation: { required: true } },
StyleNumber: { validation: { required: true } },
Description: { validation: { required: true } }
}
}
}
This will solve your problem.

Resources