text input datepicker enddate after startdate validation - validation

I have 2 input boxes, startdate and enddate. I am trying to force the user to select a date in the 2nd input box that is after the date in the first input box. This will be validated on ajax save.
Everything including the isvalid works great in ie but does not work in FF or opera.
In FF and opera no matter what the date before or after start date, it just keeps displaying the isValid: "Must be after start date" message and not validating.
Does anybody have any ideas why, or a solution using the datepickers so it modifies the minDate on the 2nd datepicker.
Here are the buttons for the ajax modal:
buttons: {
'Save': function() {
if($("#new_request_form").valid()){
// do stuff if form validates
submitFormWithAjax($("#new_request_form"));
$(this).dialog('close');
} else {
// do stuff if form does not validate
}
},
'Cancel': function() {$(this).dialog('close');}
},
Here is the date check to make sure the enddate is after the startdate:
jQuery.validator.addMethod("isValid", function (value, element) {
var startDate = $('#startdate').val();
var finDate = $('#enddate').val();
return Date.parse(startDate) < Date.parse(finDate);
}, "* End date must be after start date");
$("#new_request_form").validate({
rules: {
days: "required",
hours: {
required: true,
number: true,
digits: false
},
startdate: "required",
enddate: {
required: true,
isValid: true
}
},
messages:{
days: "Required",
hours: {
required: "Required",
number: "Numbers Only"
},
startdate: "Required",
enddate: {
required: "Required",
isValid: "Must be after start date"
}
}
});
var $ac_start_date = '<?php echo $ac_end_date ?>',
$ac_start_date_flip = '<?php echo $ac_end_date_flip ?>',
$ac_start_parsed = Date.parse($ac_start_date),
_today = new Date().getTime();
// For Opera and older winXP IE n such
if (isNaN($ac_start_parsed)) {
$ac_start_parsed = Date.parse($ac_start_date_flip);
}
var _aDayinMS = 1000 * 60 * 60 * 24;
// Calculate the difference in milliseconds
var difference_ms = Math.abs($ac_start_parsed - _today);
// Convert back to days and return
var DAY_DIFFERENCE = Math.round(difference_ms/_aDayinMS);
// do initialization here
$("#startdate").datepicker({
dateFormat: 'dd-mm-yy',
changeMonth: true,
changeYear: true,
yearRange: '0:+100',
minDate: '+1d',
maxDate: '+' + (DAY_DIFFERENCE + 1) + 'd'
});
// do initialization here
$("#enddate").datepicker({
dateFormat: 'dd-mm-yy',
changeMonth: true,
changeYear: true,
yearRange: '0:+100',
minDate: '+1d',
maxDate: '+' + (DAY_DIFFERENCE + 1) + 'd'
});
}, 'html');
return false;
});
}
function submitFormWithAjax(form) {
form = $(form);
$.ajax({
url: form.attr('action'),
data: form.serialize(),
type: (form.attr('method')),
dataType: 'script',
success: function(data){
}
});
return false;
}

Related

Data missing error when using Carbon::createFromFormat in laravel [dateFormat: year-month]

I'm getting "Data Missing" error when using Carbon to pass data to pdf view in Laravel.
The query work when the data is pass back to the same page with dropdown list but getting error when pass to another page.
the error that i get
I'm using date picker as my dropdown list & the date format that I'm using is:
"2020-December"
ajax:
changeMonth:true,
changeYear:true,
showButtonPanel:true,
dateFormat: "yy-MM",
onClose: function(dateText, inst) {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
$(this).datepicker('setDate', new Date(year, month, 1));
}
});
$('#convertBtn').click(function() {
var s = document.getElementById("sites");
var site = s.options[s.selectedIndex].text;
var startdate = $('#datepicker-8').val();
if(site != '' && startdate != '' )
{
$.ajax({
paging: false,
searching: false,
processing: true,
retrieve: true,
serverSide: true,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url:"{{ route('billing.bill') }}",
type:"GET",
dataType:"json",
data:{
site:site,
startdate:startdate,
},
success:function(data){
alert(JSON.stringify(data));
},
error: function(data){
alert('Error');
}
})
}
else
{
alert("Please select 'Site' & 'Date'. ");
}
});
controller
$sites['report_date'] = Carbon::createFromFormat('Y-F', $request->startdate);
$data = DB::table('monthly_data')
->where('site', $request->site)
->whereMonth('report_date', $sites['report_date'])
->whereYear('report_date',$sites['report_date'])
->get();
$pdf = \App::make('dompdf.wrapper');
$pdf -> loadView('pdf',compact('data'));
$pdf -> setPaper('a4','landscape');
return $pdf->stream('report.pdf');
may i know how to solve this error?
solution:
do some changes in ajax
data: {
site: site,
startdate: startdate,
},
xhrFields: {
responseType: 'blob' // to avoid binary data being mangled on charset conversion
},
success: function(blob, status, xhr) {
var ieEDGE = navigator.userAgent.match('/Edge/g');
var ie = navigator.userAgent.match('/.NET/g'); // IE 11+
var oldIE = navigator.userAgent.match('/MSIE/g');
if (ie || oldIE || ieEDGE) {
window.navigator.msSaveBlob(blob, fileName);
} else {
var fileURL = URL.createObjectURL(blob);
document.write('<iframe src="' + fileURL + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>');
}
},
error: function(data) {
alert('Error');
}
remove dataType:"json"; and replace it with xhrFields: { responseType: 'blob'} then it works

jqGrid - How can i track the speed of local operations

I have received as a assignment create 2 applications, one optimized and one unoptimized and i am using free jqGrid to display the data from DB.
I have successfully created both but i would like to track the speed at witch the local operations are done(paging,search,sorting).
I have tried to set up events for each button that triggers the operations, but they dont seem to trigger... i was wondering if there is something better that is built into jqGrid that i could use or a advice that would help me resolve this.
My jqGrid code goes like this:
$(function () {
var colModelSettings = [
{name:'id', label:'id',key: true, hidden: true, width:10,sorttype:'number',editable: true},
{name:'judet',label:'Judet',width:70, align: 'center',editable:true},
{name:'localitate',label:'Localitate',width:80,editable:true,searchoptions: {sopt: ['eq','bw','ew','cn']},align: 'center'},
{name:'tipStrada',label:'tipStrada',editable:true,searchoptions: {sopt: ['eq','bw','ew','cn']},width:100,align: 'center' },
{name:'denumire',label:'denumire',editable:true,width:100,searchoptions: {sopt: ['eq','bw','ew','cn']},align: 'center'},
{name:'cod',label:'cod',width:90,editable:true,align: 'center'}
];
var beforeEvent = 0;
$("#gridAdrese").jqGrid({
pager: $("#pagerGrid"),
url: "/UnoptimizedProject/rest/fetchData",
datatype: "json",
mtype: "POST",
loadonce: true,
forceClientSorting:true,
height: window.innerHeight-250,
sortname: 'id',
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
if (postData.searchField === undefined) postData.searchField = null;
if (postData.searchString === undefined) postData.searchString = null;
if (postData.searchOper === undefined) postData.searchOper = null;
return JSON.stringify(postData);
},
rowNum: 5000,
viewrecords: true,
loadComplete: function(){
if(beforeEvent !== undefined){
var afterEvent = new Date().getTime();
console.log(afterEvent- beforeEvent);
beforeEvent = 0;
}
},
sortorder: 'asc',
caption:'Coduri Postale Neoptimizat' ,
autowidth: true,
colModel: colModelSettings,
});
$("#gridAdrese").jqGrid('navGrid', "#pagerGrid", {edit:false, add:false, del:false, save:false, cancel:false, search:true, searchtext: 'Search', refresh: false});
$("#jqgh_gridAdrese_judet, #jqgh_gridAdrese_localitate, #jqgh_gridAdrese_tipStrada, #jqgh_gridAdrese_denumire, #jqgh_gridAdrese_cod ").on("click",function(){
beforeEvent = new Date().getTime();
console.log("Sorting");
})
$("#fbox_gridAdrese_search").on("click",function(){
beforeEvent = new Date().getTime();
console.log("searching");
});
$("#next_pagerGrid , #last_pagerGrid, #prev_pagerGrid, #first_pagerGrid").on("click",function(){
beforeEvent = new Date().getTime();
console.log("paging");
})
});
You can do about the following:
var startTime, measureTime = false, timeInterval,
startMesure = function () {
startTime = new Date();
measureTime = true;
};
startMesure();
$("#gridAdrese").jqGrid({
url: "/UnoptimizedProject/rest/fetchData",
...
onSortCol: function () {
startMesure();
},
onPaging: function (pgButton, options) {
//if (pgButton === "records") {
startMesure();
//}
},
searching: {
closeAfterSearch: true,
closeAfterReset: true,
closeOnEscape: true,
searchOnEnter: true,
beforeSearch: function () {
startMesure();
return false; // allow filtering
},
onSearch: function () {
startMesure();
},
onReset: function () {
startMesure();
},
},
loadComplete: function () {
if (measureTime) {
timeInterval = new Date() - startTime;
setTimeout(function () {
alert("Total loading time: " + timeInterval + "ms\nFull time: " +
(new Date() - startTime));
}, 50);
measureTime = false;
}
}
}).jqGrid("filterToolbar").jqGrid("navGrid");
We reset startTime with respect of startTime = new Date(); to the current time at the beginning of sorting, paging or filtering.

jqGrid getGridParam('colModel') missing information

I would like capture the colModel for my jqGrid when the page unloads and store it in session so the next time the user comes to the page it can be loaded automatically. But, the information returned by ('#contract_grid').getGridParam('colModel') is missing part or all of the information in searchoptions for the grid columns.
Any idea why this is or how to capture the full colModel? The grid works great on the initial load but without the other searchoptions params, the filter bar features/menus don't work when I refresh the page from the colModel stored in session.
Create the default colModel for the grid
var defaultColModel =
[
{name:'REQUESTID'
,index:'requestID'
,label:'Request ID'
,search:true
,stype:'text'
,width:75
,key:true
,hidden:false
},
{name:'REQUESTEDDATE'
,index:'requestedDate'
,label:'Request Date'
,sorttype:"date"
,search:true
,width:50
,searchoptions:{
dataInit:function(el){jQuery(el).daterangepicker(
{
arrows:false
, dateFormat:'yy-mm-dd'
, onClose: function(dateText, inst){ jQuery("#contract_grid")[0].triggerToolbar();}
, onOpen: function() {
jQuery('div.ui-daterangepickercontain').css({"top": jQuery('#mouseY').val() + 'px', "left": jQuery('#mouseX').val() + 'px' });
}
});
}
}
,hidden:false
},
{name:'BUSINESSOWNERPERSONID'
,index:'businessOwnerPersonID'
,label:'Business Owner'
,search:true
,stype:'select'
,width:100
,hidden:false
,searchoptions: {
dataUrl: 'cfc/com_common.cfc?method=getAjxPeople&role=businessOwnerPersonID',
buildSelect: function(resp) {
var sel= '<select><option value=""></option><option value="7583,1636">My Reports</option>';
var obj = $.parseJSON(resp);
$.each(obj, function() {
sel += '<option value="'+this['lk_value']+ '">'+this['lk_option'] + "</option>"; // label and value are returned from Java layer
});
sel += '</select>';
return sel;
},
dataEvents: [{
type: 'change',
fn: function(e) {
alert(this.value)
}
}]
}
}
];
When user navigates away from page, save the grid to session so it loads when they come back
$(window).on('beforeunload', function(){
takeSnapshot();
});
function takeSnapshot(){
var gridInfo = new Object();
gridInfo.colModel = jQuery('#contract_grid').getGridParam('colModel');
gridInfo.postData = jQuery('#contract_grid').jqGrid('getGridParam', 'postData');
var snapshotData = JSON.stringify(gridInfo);
$.ajax({
url: "actions/act_filter.cfc?method=takeSnapshot",
type: "POST",
async: false,
data: {gridName:'contract_grid'
,gridParamName:'contractGridParams'
,filterData:snapshotData
}
});
}
Create grid variable
var myGrid = jQuery("#contract_grid").jqGrid({
url: 'cfc/com_ajxRequestNew.cfc?method=getReqJSON&returnformat=json',
datatype: 'json',
postData: {filters: myFilters},
mtype: 'POST',
search: true,
colModel: defaultColModel,
altRows: true,
emptyrecords: 'NO CONTRACTS FOUND',
height: 400,
width: 1200,
sortname: lastSortName,
sortorder: lastSortOrder,
page: lastPage,
pager: jQuery('#report_pager'),
rowNum: lastRowNum,
rowList: [10,20,50,100],
viewrecords: true,
clearSearch: false,
caption: "Contracts Dashboard",
sortable: true,
shrinkToFit: false,
ajaxSelectOptions: {type: "GET"},
gridComplete: function() {
//set the selected toolbar filter values
var myFields = JSON.parse(myFilters);
//set fields in form at top. filter contains index value so get corresponding name value because its used in the column label #gs
if ( myFields['rules'].length > 0 ) {
for (var i=0; i < myFields['rules'].length; i++ ) {
$.each(defaultColModel, function(j) {
if(this.index == myFields['rules'][i]['field'] ) {
thisFieldName = this.name;
jQuery('#gs_' + thisFieldName).val( myFields['rules'][i]['data'] );
}
})
}
}
}
});
jQuery("#contract_grid").navGrid('#report_pager',{
edit:false,
add:false,
del:false,
search:false,
refresh:false
}).navButtonAdd("#report_pager",{ caption:"Clear",title:"Clear Filters", buttonicon :'ui-icon-trash',
onClickButton: function() {
jQuery.ajax({
url: "/assets/js/ajx_clearFilter.cfm?showHeader=0",
async: false,
type: "POST",
data: ({variableName:'session.contractGridParams'})
});
myGrid[0].clearToolbar();
}
}).navButtonAdd("#report_pager",{ caption:"Restore",title:"Restore Default Grid Columns and Filters", buttonicon :'ui-icon-refresh',
onClickButton: function() {
window.location = '?page=dsp_requestListingNew&clearSession=1';
}
}).navButtonAdd("#report_pager",{
caption: "Export",
title: "Export to Excel",
buttonicon :'ui-icon-document',
onClickButton: function(e){
jQuery("#contract_grid").jqGrid('excelExport',{url:'includes/act_requestListingExport.cfm'});
}
}).navButtonAdd("#report_pager",{
caption: "Columns",
buttonicon: "ui-icon-calculator",
title: "Select and Reorder Columns",
jqModal: true,
onClickButton: function(e){
$('#contract_grid').jqGrid('columnChooser', {
dialog_opts: {
modal: true,
minWidth: 470,
show: 'blind',
hide: 'explode'
}
});
}
}).navButtonAdd("#report_pager",{
caption: "Save",
title: "Save Snapshot",
buttonicon :'ui-icon-disk',
onClickButton: function(e){
takeSnapshot(0);
$('#fltrFrmLink').click();
}
});
jQuery("#contract_grid").jqGrid('filterToolbar', {
stringResult : true
, searchOnEnter : true
, autoSearch : true
, beforeClear : function() {
//set sortnames
var sn = jQuery("#contract_grid").jqGrid('getGridParam','sortname');
//set sort orders
var so = jQuery("#contract_grid").jqGrid('getGridParam','sortorder');
so = "desc";
//set grid params
jQuery("#contract_grid").jqGrid('setGridParam',{ sortorder:so, sortname:sn });
}
});
colModel returned by ('#contract_grid').getGridParam('colModel') on unload. searchoptions is missing everything for REQUESTEDDATE. Part of dataEvents and all of buildSelect are missing for BUSINESSOWNERPERSONID.
[{"name":"REQUESTID",
"index":"requestID",
"label":"Request ID",
"search":true,
"stype":"text",
"width":75,
"key":true,
"hidden":false,
"title":true,"lso":"",
"widthOrg":75,"resizable":true,"sortable":true},
{"name":"REQUESTEDDATE",
"index":"requestedDate",
"label":"Request Date",
"sorttype":"date",
"search":true,
"width":50,
"searchoptions:{},
"hidden":false,
"title":true,
"lso":"",
"widthOrg":50,
"resizable":true,
"sortable":true,"stype":"text"},
{"name":"BUSINESSOWNERPERSONID",
"index":"businessOwnerPersonID",
"label":"Business Owner",
"search":true,
"stype":"select",
"width":100,"hidden":false,
"searchoptions":{"dataUrl":"cfc/com_common.cfc?method=getAjxPeople&role=businessOwnerPersonID",
"dataEvents":[{"type":"change"}]},
"title":true,
"lso":"",
"widthOrg":100,
"resizable":true,
"sortable":true}]
JSON don't support serialization of functions. So the functions from searchoptions.dataInit, searchoptions.buildSelect and all other which you use in colModel will be discarded after you use JSON.stringify.
It's important to know which version of jqGrid/free jqGrid or Guriddo jqGrid JS you use. Starting with jqGrid 4.7 one can define template in colModel with string value (see the pull request). In the way you will have the main information in colModel which can be serialized using JSON.stringify.

knockout validation for array of objects

I have an array of dynamically added objects and I want to validate this array for required fields and numeric values.
I have 3 buttons, one for adding note, another for removing note and one for saving
How to validate every object ?
.. the code:
$(function () {
var initialData = [{
Title: "",
NoteText: "",
Suggestion: "",
MediaTime: ""
}];
var CreateNewNoteModel = function (Notes) {
var self = this;
self.Notes = ko.observableArray(ko.utils.arrayMap(Notes, function (Note) {
return { Title: Note.Title, NoteText: Note.NoteText, Suggestion: Note.Suggestion, MediaTime: Note.MediaTime };};
}));
var i = 1;
self.addNote = function () {
self.Notes.push({
Title: "", NoteText: "", Suggestion: "", MediaTime: ""
});
$('#editor' + i).wysihtml5();
$('#editorB' + i).wysihtml5();
i++;
};
self.removeNote = function (Note) {
self.Notes.remove(Note);
};
self.save = function () {
self.lastSavedJson(JSON.stringify(ko.toJS(self.Notes), null, 2));
var jsondata = self.lastSavedJson();
$.ajax({
url: "/api/Notes/?mid=" + m + "&p=" + p,
cache: false,
type: 'Post',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: jsondata,
success: function () {
alert("Success");
document.location.reload(true);
}
});
};
self.lastSavedJson = ko.observable("")
};
ko.applyBindings(new CreateNewNoteModel(initialData));
});
I am using jQuery validate plugin to add validation to knockout-js by using jQuery's validation methods: "$.validator.addMethod" and "$.validator.addClassRules".
Example:
First define your validation methods and css classes. Later on, we add the css classes to your inputs to validate your fields.
function DefineValidationRules() {
$.validator.addMethod("validateNumber", ValidateInteger, "This field is not a number");
$.validator.addMethod("validateRequired", $.validator.methods.required, "This field is required");
$.validator.addMethod("validateMin", $.validator.methods.min, $.format("This number be greater than or equal to {0}"));
$.validator.addMethod("validateMax", $.validator.methods.min, $.format("This number must be less than or equal to {0}"));
$.validator.addMethod("validateMinlength", $.validator.methods.minlength, $.format("This field must contain at least {0} characters"));
$.validator.addMethod("validateRangelength", $.validator.methods.rangelength, $.format("This field must contain between {0} and {1} characters"));
$.validator.addClassRules("validate-number", { validateNumber: true });
$.validator.addClassRules("validate-number-min", { validateNumber: true, validateMin: 1 });
$.validator.addClassRules("validate-required-number-min", { validateRequired: true, validateNumber: true, validateMin: 1 });
$.validator.addClassRules("validate-required", { validateRequired: true });
$.validator.addClassRules("validate-rangelengthmax6", { validateRangelength: [0,6] });
}
DefineValidationRules();
You can also add your own custom validation method:
function ValidateInteger(value) {
//do whatever you want to check
}
Having an input in knockout:
<input class="validate-required validate-number" type="text" data-bind="value: examplefield, valueUpdate: 'afterkeydown', attr: { attrname: 'itsvalue'}" />
Checking on submit:
$("#yoursubmitbutton").on("click", function () {
var formtosubmit = $("#idofyourform");
//check for validation errors
if (isValid(formtosubmit)) {
formtosubmit.submit();
//
// code to proceed to next step
}
});
function isValid(el) {
var $thisform = el;
$thisform.validate({
errorElement: "label",
errorPlacement: function (error, element) {
//eventual different error placing
if (element.attr("name") == "fname" || element.attr("name") == "lname") {
element.css("border", "2px solid red");
error.insertAfter("#lastname");
} else {
error.insertAfter(element);
}
}
});
return $thisform.valid();
}

Kendo UI Grid posting back already Inserted Rows again

I am running into problem, where when an Insert is completed successfully and if i continue to insert another row, in the next insert it is also sending the row that was inserted successfully earlier, so it goes like this.
On the First insert that row is posted back to webAPI and inserted successfully.
On Next Insert Two rows are sent one of them was from first step.
On third Insert it send previous two rows as well as third row and so on.
What could be the cause of this ?
This is the Code in problem.
$(document).ready(function () {
try {
var degreeYearsArray = new Array();
function GetDegreeName(dgID, degreeName) {
for (var i = 0; i < degreeYearsArray.length; i++) {
if (degreeYearsArray[i].dgID_PK == dgID) {
return degreeYearsArray[i].Name;
}
}
return degreeName;
}
var degreeYearModel = {
id: "DGYR_PK",
fields: {
DGID_FK: {
type: "number",
nullable: false,
editable: false
},
Code: {
type: "string",
validation: {
required: true,
minlength: 2,
maxlength: 160
}
},
Year: {
type: "number",
validation: {
required: true
}
},
EffectiveDate: {
type: "date",
validation: true
},
TerminationDate: {
type: "date",
validation: true
}
}
};
var baseURL = "http://localhost:3103/api/Degree";
var degreeYearTransport = {
create: {
url: baseURL + "/PostDegreeYears", // "/PutOrgSchool",
type: "POST",
// contentType: "application/json"
dataType: "json"
},
read: {
url: function () {
var newURL = "";
if (window.SelectedDegree == null)
newURL = baseURL + "/GetDegreeYears"
else
newURL = baseURL + "/GetDegreeYears?degreeID=" + window.SelectedDegree.DGID_PK;
return newURL;
},
dataType: "json" // <-- The default was "jsonp"
},
update: {
url: baseURL + "/PutDegreeYears", //"/PostOrgSchool",
type: "PUT",
// contentType: "application/json",
dataType: "json"
},
destroy: {
url: function (employee) {
return baseURL + "/deleteOrg" + employee.Id
},
type: "DELETE",
dataType: "json",
contentType: "application/json"
},
parameterMap: function (options, operation) {
try {
if (operation != "read") {
options.EffectiveDate = moment(options.EffectiveDate).format("MM-DD-YYYY");
options.TerminationDate = moment(options.TerminationDate).format("MM-DD-YYYY")
}
var paramMap = kendo.data.transports.odata.parameterMap(options);
delete paramMap.$format; // <-- remove format parameter.
return paramMap;
} catch (e) {
console.error("Error occure in parameter Map or Degree.js" + e.message);
}
}
}; //transport
var dsDegreeYears = new kendo.data.DataSource({
serverFiltering: true, // <-- Do filtering server-side
serverPaging: true, // <-- Do paging server-side
pageSize: 2,
transport: degreeYearTransport,
requestEnd: function (e) {
try {
if (e.type == "update"){
$.pnotify({
title: 'Update Sucessful',
text: 'Record was Updated Successfully',
type: 'success'
});
}
if (e.type == "create") {
$.pnotify({
title: 'Insert Sucessful',
text: 'Record was Inserted Successfully',
type: 'success'
});
}
} catch (e) {
console.error("error occured in requestEnd of dsDegreeYears datasource in DegreeYears.js" + e.message);
}
},
schema: {
data: function (data) {
return data.Items; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data.Count; // <-- The total items count is the data length, there is no .Count to unpack.
},
model: degreeYearModel
}, //schema
error: function (e) {
var dialog = $('<div></div>').css({ height: "350px", overflow: "auto" }).html(e.xhr.responseText).kendoWindow({
height: "300px",
modal: true,
title: "Error",
visible: false,
width: "600px"
});
dialog.data("kendoWindow").center().open();
},
});
$("#" + gridName).kendoGrid({
dataSource: dsDegreeYears,
autoBind: false,
groupable: true,
sortable: true,
selectable: true,
filterable: true,
reorderable: true,
resizable: true,
columnMenu: true,
height: 430,
editable: "inline",
toolbar: ["create"],
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [ {
field: "DGID_FK",
title: "Degree Name",
width: 140,
template: function (dataItem) {
if (window.SelectedDegree != null) {
dataItem.DGID_FK = window.SelectedDegree.DGID_PK;
return window.SelectedDegree.Name;
}
else
return "";
}
},
{
field: "Code",
title: "Code",
width: 140
},
{
field: "Year",
title: "Year",
width: 140
},
{
field: "Description",
width: 110
},
{
field: "EffectiveDate",
width: 110,
format: "{0:MM/dd/yyyy}"
},
{
field: "TerminationDate",
width: 110,
format: "{0:MM/dd/yyyy}"
},
{
command: ["edit"] , title: " ", width: "172px"
}
]
}); //grid
//Hide history pull-down menu in the top corner
$.pnotify.defaults.history = false;
$.pnotify.defaults.styling = "bootstrap";
// styling: 'bootstrap'
//styling: 'jqueryui'
} catch (e) {
console.error("Error occured in DegreeYears" + e.message);
}
}); // document
This is the Response that is sent from WebAPI
{"$id":"1","DGYR_PK":27,"DGID_FK":64,"Year":4,"Code":"4THYR","EffectiveDate":"2014-01-11T00:00:00","TerminationDate":"2014-01-11T00:00:00","CreatedByUserID_FK":1,"DateCreated":"0001-01-01T00:00:00","UpdatedByUserID_FK":1,"DateUpdated":"0001-01-01T00:00:00","RowStatusID_FK":1,"Degree":null,"DegreeYearExamSchedules":[],"User":null,"RowStatu":null,"User1":null,"DegreeYearSubjects":[]}
So i do see i am returning ID as suggested by the users in response to the question.
still wondering
After you have inserted a record, you need to return the id of that row, otherwise grid consider the previous row as a new row too.
In your create function you call the web API
baseURL + "/PostDegreeYears", // "/PutOrgSchool",
In the server side consider the below code.
public void Create(ABSModel model)
{
try
{
using (context = new Pinc_DBEntities())
{
tblAB tb = new tblAB();
tb.ABS = model.ABS;
tb.AreaFacility = model.AreaFacility;
context.tblABS.Add(tb);
Save();
model.ABSID = tb.ABSID;//this is the important line of code, you are returning the just inserted record's id (primary key) back to the kendo grid after successfully saving the record to the database.
}
}
catch (Exception ex)
{
throw ex;
}
}
please adjust the above example according to your requirement.
This will happen if you don't return the "DGYR_PK" value of the newly inserted model. The data source needs a model instance to have its "id" field set in order not to consider it "new". When you return the "ID" as a response of the "create" operation the data source will work properly.
You can check this example for fully working Web API CRUD: https://github.com/telerik/kendo-examples-asp-net/tree/master/grid-webapi-crud
Here is the relevant code:
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
db.Products.AddObject(product);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, product);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = product.ProductID }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
Your primary key cannot be 0 or null. If you are using auto-incrementing values then you should invoke the "re-read" of your dataSource after post. Check the values and make sure your data values are >0. Note: I have set the default value of the PK in the model to -1 in the column model to help with this.
You can attached and respond to the requestEnd event on the DataSource.
requestEnd: function(e) {
if (e.type === "create") {
this.read();
}
}
What that is saying is: "After you created a record, reread the entries (including the newly created one) into the grid". Thereby giving you the newly created entry with key and all. Of course you see that the extra read may have some performance issue.

Resources