Proper way of creating date fields in jsGrid - javascript

So I'm a beginner using jsGrid to make a calendar grid, which looks like this
http://i.stack.imgur.com/gU4V9.png
I've created the header fields as such:
var headerFields = [{
name: "name",
title: "", type: "text",
width: 60
}];
for(var i = 1; i <= 31; i++){
headerFields[i] = {
name: String(i),
title: String(i),
type: "text",
width: 20,
sorting: false,
inserting: false
};
}
headerFields.push({ type: "control", width: 24, editButton: false });
And then that's initialized in the jsGrid itself as such:
$("#jsGrid").jsGrid({
...
fields: headerFields,
...
}
Aside from all months having 31 days I feel like this is a very non-kosher way of doing this, because if I want to reference a cell by a certain day it's done like "item[17]" which is so ambiguous, it feels like it should have another layer like "item.day(17)" but I'm having a hard time figuring out how to apply that.
Any thoughts?

working example of jsgrid date field
var db = {
loadData: function(filter) {
return $.grep(this.users, function(user) {
return (!filter.Name || user.Name.indexOf(filter.Name) > -1);
});
},
insertItem: function(item) {
this.users.push(item);
},
deleteItem: function(item) {
var index = $.inArray(item, this.users);
this.users.splice(index, 1);
}
};
window.db = db;
db.users = [
{
"Account": "D89FF524-1233-0CE7-C9E1-56EFF017A321",
"Name": "Prescott Griffin",
"RegisterDate": "2011-02-22T05:59:55-08:00"
},
{
"Account": "06FAAD9A-5114-08F6-D60C-961B2528B4F0",
"Name": "Amir Saunders",
"RegisterDate": "2014-08-13T09:17:49-07:00"
},
{
"Account": "EED7653D-7DD9-A722-64A8-36A55ECDBE77",
"Name": "Derek Thornton",
"RegisterDate": "2012-02-27T01:31:07-08:00"
},
{
"Account": "2A2E6D40-FEBD-C643-A751-9AB4CAF1E2F6",
"Name": "Fletcher Romero",
"RegisterDate": "2010-06-25T15:49:54-07:00"
},
{
"Account": "3978F8FA-DFF0-DA0E-0A5D-EB9D281A3286",
"Name": "Thaddeus Stein",
"RegisterDate": "2013-11-10T07:29:41-08:00"
}
];
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 class='date-picker'>").datetimepicker();
},
editTemplate: function (value) {
return this._editPicker = $("<input class='date-picker'>").datetimepicker();
},
insertValue: function () {
return this._insertPicker.data("DateTimePicker").useCurrent();
},
editValue: function () {
return this._editPicker.data("DateTimePicker").useCurrent();
}
});
jsGrid.fields.date = MyDateField;
$("#jsGrid").jsGrid({
height: "90%",
width: "100%",
inserting: true,
filtering: true,
editing: true,
paging: true,
autoload: true,
controller: db,
fields: [
{ name: "Account", width: 150, align: "center" },
{ name: "Name", type: "text" },
{ name: "RegisterDate", type: "date", width: 100, align: "center" },
{ type: "control", editButton: false }
]
});
Refference: http://jsfiddle.net/tabalinas/L6wbmvfo/

if you're using Moment, this worked for me:
var DateField = function (config) {
jsGrid.Field.call(this, config);
};
DateField.prototype = new jsGrid.Field({
sorter: function (date1, date2) {
return moment(date1) - moment(date2);
},
itemTemplate: function (value) {
return moment(value).locale('en').format('YYYY-MM-DD HH:mm:ss');
},
});
jsGrid.fields.date = DateField;
I just ignored edit & insert functions because I don't need them.

Related

how can i get array data source, kendo-grid?

I'm getting array of properties and I want to show all of them in grid.
How to do it? Is it possible?
This is my code:
function StartBuild(ProfileProperties) {
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
$(document).ready(function () {
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
$("#grid").kendoGrid({
dataSource: datasource,
pegable: true,
sortable: {
mode: "single",
allowUnsort: false
},
columns: [{
field: "name",
title: "name",
filterable: {
cell: {
enabled:true
}
}
}, {//[Bild, nameP, email,phonework, Mobile, ManagerName]
field: "email",
title: "email"
}, {
field: "phoneWork",
title: "phoneWork"
}, {
field: "Mobile",
title: "Mobile"
}, {
field: "Manager",
title: "Manager"
}],
filterable: {
mode: "row"
},
});
});
}
Only if I write details[0] it shows the first properties otherwise it doesn't show anything.
It looks like there are a couple of problems.
http://dojo.telerik.com/#Stephen/uVOjAk
First, the transport setup is incorrect. pageSize, batch, and schema are not part of the transport configuration...you need to take them out of the transport block and just have them in the datasource block.
You want:
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
}
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
});
Instead of(what you have):
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
Second, the details needs to be an array of objects, not an array of an array of an object.
You want:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details.push({ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] });
}
Instead of:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
Two other issues that are not directly causing a problem, but are incorrect are:
Your dataSource.schema configuration does not match your actual data at all. The schema really needs to match the fields of the actual data otherwise it cannot match up the configuration.
You spelled "pageable" wrong in the grid configuration.

Kendo UI grid comboBox undefined on focus out?

I have working on Keno UI grid and I have added a comboBox as a column in the grid which also supports autocomplete feature. Apparently, comboBox is working fine but when I type half of world and focus out of the comboBox cell then it shows undefined. I have tried to handle it on combobox change event, but it is still showing undefined value? Below is my code for combobox and grid.
function productDropDownEditor(container, options) {
$('<input id="ProductDropDown" style="width:250px;" data-bind="value:' + options.field + '"/>')
.appendTo(container).kendoComboBox({
dataSource: dataSource,
autoBind: false,
dataTextField: 'ProductName',
dataValueField: 'ProductID',
filter: "contains",
suggest: true,
index: 3,
change: function (e) {
debugger;
var cmb = this;
// selectedIndex of -1 indicates custom value
if (cmb.selectedIndex < 0) {
cmb.value(0); // or set to the first item in combobox
}
},
close: function (e) {
debugger;
var cmb = this;
}
});
And here is following code for kendo grid.
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "Products", width: "250px",
editor: productDropDownEditor,
title: "Product",
template: "#=Products.ProductName#",
attributes: {
"class": "select2_single"
}
},
{ field: "PurchasePrice", width: "150px" },
{ field: "PurchaseQuantity", width: "150px" },
{ field: "SaleRate", title: "Sale Rate", width: "150px" },
{ field: "Amount", title: "Amount", width: "150px" },
{ command: "destroy", title: "Delete", width: "110px" },
],
editable: true, // enable editing
pageable: true,
navigatable: true,
sortable: true,
editable: "incell",
toolbar: ["create"], // specify toolbar commands
edit: function (e) {
//debugger;
//// var parentItem = parentGrid.dataSource.get(e.model.PurchaseID);
////e.model.set("ShipCountry", parentItem.Country);
//if (e.model.isNew()) {
// // set the value of the model property like this
// e.model.set("PropertyName", Value);
// // for setting all fields, you can loop on
// // the grid columns names and set the field
//}
},
//editable: "inline",
dataSource: {
serverPaging: true,
requestStart: function () {
kendo.ui.progress($("#loading"), true);
},
requestEnd: function () {
kendo.ui.progress($("#loading"), false);
},
serverFiltering: true,
serverSorting: true,
batch: true,
pageSize: 3,
schema: {
data: "data",
total: "Total",
model: { // define the model of the data source. Required for validation and property types.
id: "Id",
fields: {
PurchaseID: { editable: false, nullable: true },
PurchasePrice: { nullable: true },
PurchaseQuantity: { validation: { required: true, min: 1 } },
SaleRate: { validation: { required: true, min: 1 } },
Amount: { type: "number", editable: false },
Products: {
nullable: false,
validation: { required: true},
defaultValue: {ProductID:1, ProductName:"Googo" },
//from: "Products.ProductName",
parse: function (data) {
debugger;
if (data == null) {
data = { ProductID: 1};
}
return data;
},
type: "object"
}
}
}
},
batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
change: function (e) {
debugger;
if (e.action === "itemchange" && e.field !== "Amount") {
var model = e.items[0],
type = model.Type,
currentValue = model.PurchasePrice * model.PurchaseQuantity;//formulas[type](model);
if (currentValue !== model.Amount) {
model.Amount = currentValue;
$("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(4)").text(currentValue);
}
//if (e.field == "Products") {
// $("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(0)").text(model.Products);
//}
}
},
transport: {
read: {
url: "#Url.Action("Read", "Purchase")", //specify the URL which should return the records. This is the Read method of the HomeController.
contentType: "application/json",
type: "POST", //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
},
parameterMap: function (data, operation) {
debugger;
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them:
// data.models[0].ProductID = data.models[0].Product.ProductID;
var result = {};
// data.models[0].ProductID = $("#ProductDropDown").val();
for (var i = 0; i < data.models.length; i++) {
var purchase = data.models[i];
for (var member in purchase) {
result["purchaseDetail[" + i + "]." + member] = purchase[member];
}
}
return result;
} else {
var purchaseID = $("#hdnPurchaseId").val();
//output = '{ purchaseID: ' + purchaseID + '}';
data.purchaseID = purchaseID; // Got value from MVC view model.
return JSON.stringify(data)
}
}
}
},
}).data("kendoGrid");

Getting a string on an update request in KendoUI datasource

I have a pretty simple grid with data source that retrieves data correctly
For that cause I have a schema.parse function defined
The problem is that when I try to update/create new row the schema.parse() called again and the parameter that is passed to it is a string that contains the HTML of my page. cannot really get what the hell is going on there.
thanks
var _dataSource = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: layerDefProvider.getLayerUrlById("surveys") + "/query",
data: {
f: "json",
//token: token,
outFields: "*",
//outSR: 3857,
where: "1=1"
},
type: "POST"
},
create: function (options) {
console.debug("called");//never gets called
},
update: function (options) {
console.debug("called");//never gets called
},
destroy: function (options) {
console.debug("called");//never gets called
}
},
filter: {
field: "OBJECTID", operator: "eq", value: 0
},
schema: {
data:function(response) {
},
parse: function (data) {//on loading it is fine, on updating the data param is a string of my HTML of the page
var rows = [];
var features = data.features;
if (!features) {
return [];
}
for (var i = 0; i < features.length; i++) {
var dataRow = {};
dataRow.OBJECTID = features[i].attributes.OBJECTID;
dataRow.Name = features[i].attributes.Name;
dataRow.Date = features[i].attributes.Date;
dataRow.Comment = features[i].attributes.Comment;
rows.push(dataRow);
}
return rows;
},
model: {
id: "OBJECTID",
fields: {
OBJECTID: { type: "number", editable: false },
Name: { type: "string" },
Date: { type: "string" },
Comment: { type: "string" }
}
}
}
});
var _surveysPicker = $(config.table).kendoGrid({
toolbar: ["create","save"],
editable: true,
dataSource: _dataSource,
height: 300,
sortable: true,
selectable: "multiple",
columnMenu: true,
resizable: true,
columns: [{
field: "OBJECTID",
width: 40
}, {
field: "Name",
width: 40
}, {
field: "Date",
width: 40
}, {
field: "Comment",
width: 100
}]
});
You need to move your parse function inside read event if you need to parse data only on read action.

Kendo UI Grid Refesh on Dropdown Selection

I have a grid where each row has a select drop down box in with values.
When an item is selected, how can I make the grid reload to reflect the change?
The reason I want to do this is because the item selected from the drop down effects an amount in another column.
Here is the code for my dropdown:
function shippingModelSelect(container, options)
{
$('<input required data-text-field="modelName" data-value-field="modelId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: [
{
"modelName": "Individual shipping cost",
"modelId": 1
},
{
"modelName": "Based on weight",
"modelId": 2
},
{
"modelName": "Based on value",
"modelId": 3
}
],
close: function()
{
handleChange();
}
});
}
My handle change function:
var gridAlert = $('#gridAlert');
var handleChange = function(input, value) {
if(input && value)
{
detail = 'Product <b>'+input[0].name+'</b> changed to <b>'+value+'</b>';
gridAlert.html('<b>Changes saved!</b><p>'+detail+'</p>');
gridAlert.fadeIn('slow', function(){
setTimeout(function(){
gridAlert.fadeOut();
}, 2000)
});
}
dataSource.sync();
}
And finally my grid setup:
dataSource = new kendo.data.DataSource({
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping: true,
serverAggregates: true,
transport: {
read: {
url: ROOT+'products/manage'
},
update: {
url: ROOT+'products/set-product',
type: "POST",
data: function(data)
{
data.dateAdded = kendo.toString(data.dateAdded, 'yyyy-MM-dd hh:ii:ss')
return data;
}
}
},
pageSize: 20,
sort: {
field: 'id',
dir: 'desc'
},
error: function(e) {
alert(e.errorThrown+"\n"+e.status+"\n"+e.xhr.responseText) ;
},
schema: {
data: "data",
total: "rowcount",
model: {
id: "id",
fields: {
id: {
type: 'number',
editable: false
},
SKU: {
type: "string"
},
name: {
type: "string"
},
dateAdded: {
type: "date",
format: "{0:yyyy/MM/dd hh:mm}",
editable: false
},
shippingModel: {
type: "string"
},
shippingModelId: {
type: "number"
},
price: {
type: "number"
}
}
}
}
})
$('#productGrid').kendoGrid({
dataSource: dataSource,
autoBind: true,
columns: [
{
field: "image",
title: "Image",
width: 30,
template: "#= '<img title=\"'+alt+'\" src=\"images/'+image+'\"/>' #"
},
{
field: "SKU",
title: "SKU",
width: 50,
headerTemplate: "<abbr title=\"Stock Keeping Unit - A unique identifier for this product\">SKU</abbr>"
},
{
field: "stockQuantity",
title: "Quantity",
width: 30
},
{
field: "name",
title: "Name",
width: 200
},
{
field: "dateAdded",
title: "Date Added",
width: 80,
template: "#= niceDate #"
},
{
field: "shippingModelId",
title: "Shipping Model",
width: 50,
editor: shippingModelSelect,
template: "#= shippingModel #"
},
{
field: "price",
title: "Price",
width: 80,
//format: "{0:c}",
template: "#= '£'+price.toFixed(2)+'<br /><span class=\"grey\">+£'+shipping+' shipping</span>' #"
}
],
sortable: true,
editable: true,
pageable: {
refresh: true,
pageSizes: [10, 20, 50]
},
scrollable: false,
reorderable: true,
edit: function(e) {
var value;
var numericInput = e.container.find("[data-type='number']");
// Handle numeric
if (numericInput.length > 0)
{
var numeric = numericInput.data("kendoNumericTextBox");
numeric.bind("change", function(e) {
value = this.value();
handleChange(numericInput, value);
});
return;
}
var input = e.container.find(":input");
// Handle checkbox
if (input.is(":checkbox"))
{
value = input.is(":checked");
input.change(function(){
value = input.is(":checked");
handleChange(input, value);
});
}
else
{
// Handle text
value = input.val();
input.keyup(function(){
value = input.val();
});
input.change(function(){
value = input.val();
});
input.blur(function(){
handleChange(input, value);
});
}
}
}
)
You will need to do two things.
Wait for changes to finish syncing
Tell the grid to re-read the datasource
This should do both for you
dataSource.bind("sync", function(e) {
$('#productGrid').data("kendoGrid").dataSource.read();
});
For more info see the datasource sync event and datasource read method on their docs site.

Is it possible to have full CRUD functions in kendo grid with local data

I'm currently implementing a kendo grid and i'm populating it with local data.
That is; I have generated a JSON string from my action and supplying that string on the view page.
In the end i would like to know if it is possible to implement full CRUD functions with local data?
here's a sample of the code written so far;
<div id="example" class="k-content">
<div id="grid"></div>
<script>
$(document).ready(function() {
var myData = ${coursemodules},
dataSource = new kendo.data.DataSource({
data: myData,
batch: true,
pageSize: 30,
schema: {
model: {
id: "id",
fields: {
id: { editable: false, nullable: true},
name: { type: "string", validation: { required: true }},
qualificationLevel: { type: "string", validation: { required: true }},
description: { type: "string", validation: { required: true }},
published: { type: "boolean" },
gateApprove: { type: "boolean" },
duration: { type: "number", validation: { min: 1, required: true } },
academicBody: { type: "string" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
height: 350,
scrollable: true,
sortable: true,
pageable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{
field: "id",
title: "ID",
width: '3%'
},
{
field: "name",
title: "Course Title",
width: '20%'
},
{
field: "description",
title:"Description",
width: '35%'
},
{
field: "published",
title: "Published",
width: '7%'
},
{
field: "gateApprove",
title: "Gate Approve",
width: '7%'
},
{
field: "duration",
title: "Duration",
width: '5%'
},
{
field: "academicBody.shortName",
title: "Academic Body",
width: '10%'
}
],
editable: true
});
});
</script>
</div>
I have realise that for the datasource, you have to declare transport to implement the CRUD. However, I need to declare "data". I tried declaring both transport and data. That doesn't seem to work.
Yes you can Here is JSFiddle Hope this will help you.
// this should be updated when new entries are added, updated or deleted
var data =
[{
"ID": 3,
"TopMenuId": 2,
"Title": "Cashier",
"Link": "www.fake123.com"},
{
"ID": 4,
"TopMenuId": 2,
"Title": "Deposit",
"Link": "www.fake123.com"}
];
$("#grid").kendoGrid({
dataSource: {
transport: {
read: function(options) {
options.success(data);
},
create: function(options) {
alert(data.length);
},
update: function(options) {
alert("Update");
},
destroy: function(options) {
alert("Destroy");
alert(data.length);
}
},
batch: true,
pageSize: 4,
schema: {
model: {
id: "ID",
fields: {
ID: {
editable: false,
nullable: true
},
TopMenuId: {
editable: false,
nullable: true
},
Title: {
editable: true,
validation: {
required: true
}
},
Link: {
editable: true
}
}
},
data: "",
total: function(result) {
result = result.data || result;
return result.length || 0;
}
}
},
editable: true,
toolbar: ["create", "save", "cancel"],
height: 250,
scrollable: true,
sortable: true,
filterable: false,
pageable: true,
columns: [
{
field: "TopMenuId",
title: "Menu Id"},
{
field: "Title",
title: "Title"},
{
field: "Link",
title: "Link"},
{
command: "destroy"}
]
});
When binding local data, the Grid widget utilizes an abstraction that represents a local transport. Therefore, it does not require a custom transport; modifications made in the grid are reflected to the bound data source. This includes rollbacks through a cancellation.
There is fully functional example of this in telerik documentation
What you need is define transport block in dataSource object with custom CRUD funtions which update local source.
transport: {
create: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.data.ID = localData[localData.length-1].ID + 1;
localData.push(options.data);
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
read: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.success(localData);
},
update: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID == options.data.ID){
localData[i].Value = options.data.Value;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
destroy: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID === options.data.ID){
localData.splice(i,1);
break;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(localData);
},
}

Categories

Resources