How to allow kendo grid to bind to an undefined field - kendo-ui

I have this json object
{
id: string,
name: string,
category: {
id: string
name: string,
}
}
I want to have column that bind to productCategory.name. However that field is nullable. When productCategory is null/undefined, kendo will throw error. How can i tell kendo that if field is undefined, just show empty string?
EDIT
Below is my sample data
[{
"id":1,
"name":"Spaghetti",
"category":{
"id":"1",
"name":"Food"
}},
{
"id":2,
"name":"Coca-cola",
"category":null
}}]
Below is my kendo datasource
var kendoDataSource = new kendo.data.DataSource({
schema: {
data: "data",
total: "total",
model: {
id: "id",
fields: {
id: { type: "string" },
name: { type: "string" },
"category.name": { type: "string" }
}
}
}
});
Data above will throw "undefined" error, because second product does not have category.

Try using empty object instead of null
created a fiddle,check this:
http://jsfiddle.net/Sowjanya51/h930jcru/

Just provide a default value in your model like this:
var kendoDataSource = new kendo.data.DataSource({
schema: {
data: "data",
total: "total",
model: {
id: "id",
fields: {
id: { type: "string" },
name: { type: "string" },
"category.name": { type: "string" },
category: { defaultValue: {
id: "",
name: "",
}
}
}
}
}
});
This will initialize productCategory if it is null or undefined.

Related

How to create custom resolvers for Gatsby page queries?

I have a Gatsby application pulling data from Sanity.
This is Sanity's schema for the course.js:
import video from './video'
export default {
// Computer name
name: `courses`,
// Visible title
title: `Courses`,
type: `document`,
fields: [
{
name: `title`,
title: `Course title`,
type: `string`,
description: `Name of the course`
},
{
name: `slug`,
title: `slug`,
type: `slug`,
options: {
source: `title`,
maxLength: 100,
}
},
{
name: `price`,
title: `Price`,
type: `number`
},
{
name: `thumbnail`,
title: `Thumbnail`,
type: `image`,
options: {
hotspot: true,
}
},
{
name: `playlist`,
title: `Playlist`,
type: `array`,
of: [
{
title: `Video`,
name: `video`,
type: `video`,
}
]
},
]
}
And this is Sanity's schema for video.js:
export default {
// Computer name
name: `video`,
// Visible title
title: `Video`,
type: `object`,
fields: [
{ name: `title`, type: `string`, title: `Video title` },
{ name: `url`, type: `url`, title: `URL` },
{ name: `public`, title: `public`, type: `boolean`, initialValue: false }
]
}
This Gatsby page query:
{
allSanityCourses {
nodes {
title
price
playlist {
url
title
public
}
}
}
}
Results in:
{
"data": {
"allSanityCourses": {
"nodes": [
{
"title": "Master VS Code",
"price": 149,
"playlist": [
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Introduction",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Philosophy",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Tech and Tools",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Integration",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Extensions",
"public": false
}
]
}
]
}
},
"extensions": {}
}
To prevent the url field from being injected into the React component this Gatsby page query runs on (because these urls are paid for), I need to remove it, if the public field is set to false.
I've tried inserting this into gastby-node.js:
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions
const typeDefs = [
schema.buildObjectType({
name: "SanityCourses",
fields: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve: (source) => "nope"
},
},
},
interfaces: ["Node"],
}),
]
createTypes(typeDefs)
}
And:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
SanityCourses: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve(source, args, context, info) {
return "nope"
},
}
},
},
}
createResolvers(resolvers)
}
But neither seems to work. The url field returns the url as always. The resolvers don't even seem to fire (I've tried putting console.log()'s in them).
Any help on how to remove the url field if the public field is set to false, or general direction to go in would be very appreciated.
Ditch the attempt in createSchemaCustomization since you don't need to customize the schema here (though I believe there is a way to achieve what you want using it, it is not expected that the data in it is sourced from existing nodes, and this undeclared dependency can create caching issues).
Then update your createResolvers function to something like this:
exports.createResolvers = ({ createResolvers }) => {
createResolvers({
SanityVideo: {
safeUrl: {
type: "String",
resolve: (source, args, context, info) => source.public ? source.url : null
},
},
})
}
I don't believe resolvers can replace schema-originated nodes (fields), hence using safeUrl instead of url
The type you are adding a field to is SanityVideo, and it doesn't matter what the parent node is—this will apply to all instances of SanityVideo in your data

How can we hide zero value from text box if field type is number in kendo-ui?

I have a field with Project Code and type as a number but while rendering in the browser it shows default value as 0. So how should I hide or remove zero?
I am new to Kendo-UI. So I am not getting any idea.
schema: {
data: "data", total: "total",
model: {
id: "id",
fields: {
SBU: { type: "string" },
Project_Code: { type: "number" },
Role: { type: "string" },
IPM_Oracle_UserID: { type: "string" },
IQ_LoginID: { type: "string" }
}
}
}
Here in the above coa de, there is "Project_Code" field which has type as number but on browser the default value it render is zero. So, how to hide/remove default value zero for "Project_Code" field.
I found the answer after some searching.Just you need add nullable as true. Please find below re-framed code of mine.
schema: {
data: "data", total: "total",
model: {
id: "id",
fields: {
SBU: { type: "string" },
Project_Code: { type: "number", nullable: true },
Role: { type: "string" },
IPM_Oracle_UserID: { type: "string" },
IQ_LoginID: { type: "string" }
}
}
}

Kendo UI Inline Grid

I am having an issue with validation on certain fields. I want to only validate on a couple of fields, and the other fields should not validate. In my Email field, I am firing a function to check proper formatting, but the other fields are simply set to validate. Any help would be greatly appreciated.
model: {
id: "UserID",
fields: {
UserID: { editable: false },
CompanyID: { editable: false },
FirstName: { type: "string", validation: { required: { message: "Name is required"} } },
LastName: { type: "string", validation: { required: { message: "Name is required" } } },
Email: {
type: "string",
validation: {
required: { message: "Email is required." },
validateEmailFormat: function(input) {
if (input.attr("data-bind") == "value:Email") {
input.attr("data-validateEmailFormat-msg", "Email format invalid.");
return checkEmail(input.val());
}
return true;
}
}
},
PhoneNumber: { type: "string" },
Extension: { type: "string" }
}
}
With this code, all fields are being validated when trying to save/update. I don't want Extension or PhoneNumber to validate.
In your update/Save action, You can remove your fields from the ModelState which don't want to valid, like :
ModelState.Remove("PhoneNumber");
ModelState.Remove("Extension");

Kendo Ui DataSource Add Function not working properly

I defined a Kendo Data Source as below. It is populating values in a ListView.
var datasourceAppList = new kendo.data.DataSource({
transport: {
create: function(options){
//alert(options.data.desc);
alert(options.data.desc);
var localData = JSON.parse(localStorage.getItem("LsAppList"));
localData.push(options.data);
localStorage.setItem("LsAppList", JSON.stringify(localData)); //localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
read: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
options.success(localData);
},
update: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
for(var i=0; i<localData.length; i++){
if(localData[i].extappId == options.data.extappId){
localData[i].desc = options.data.desc;
localData[i].deviceNo = options.data.deviceNo;
localData[i].validationKey = options.data.validationKey;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(localData);
},
destroy: function(options){
var localData = JSON.parse(localStorage["LsAppList"]);
localData.remove(options.data.ID);
localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
},
schema: {
model: {
extappId: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}}
},
});
First : I call the following code. it adds the data correctly both to te page listview and localStorage.
datasourceAppList.add({ extappId: "9905", desc: "test", deviceNo: "5", validationKey: "CACACACA"});
datasourceAppList.sync();
Second: I call the folowing code
datasourceAppList.add({ extappId: "9908", desc: "harvest", deviceNo: "7", validationKey: "ppppppp"});
datasourceAppList.sync();
Problems:
the page is showing the first record twice.
The localstorage has 2 times the first record and 1 time the second record.
what am I doing wrong?
--- one problem still exists. though the localStorage is correct, the listview is populating wrong.
First Record Add : ListView is Correct
Second Record Add : ListView is Corract
Third Record Add : First 2 lines shows the first record and the last line shows the last record.
My HTML code is
<div id="applications" data-role="view" data-title="Defined Applications" data-layout="default" data-model="appdetail">
<ul id="applist" data-role="listview" data-style="inset" data-source="datasourceAppList" data-template="tmp" data-click="listViewClick" data-auto-bind="true"></ul>
<p align="center">
<a style="width: 30%" data-role="button" data-rel="modalview" data-click="showModalViewAdd" id="buttonAddApplication" data-icon="ecg-plus">Add</a>
<a style="width: 30%" data-role="button" data-rel="modalview" data-click="refreshApplicationList" id="buttonRefreshApplication" data-icon="refresh">Refresh</a>
</p>
</div>
<script id="tmp" type="text/x-kendo-template">
<a id = "#: extappId #">#: desc # </a>
</script>
It is actually a combined problem:
You schema definition is:
schema: {
model: {
extappId: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
It says extappId: "ID"... what is this? Do you want to say that extappId is the id of that record? If so, the actual definition should be:
schema: {
model: {
id: "extappId",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
What happens here is not being (correctly) defined the id, KendoUI expects that id is actually id and since this is not being set during the create next time that you sync it tries to save it, it is equivalent to:
datasourceAppList.add({ extappId: 9905, desc: "test", deviceNo: 5, validationKey: "CACACACA"});
datasourceAppList.add({ extappId: 9908, desc: "harvest", deviceNo: 7, validationKey: "ppppppp"});
datasourceAppList.sync();
But if you try this, you will see that then create is never invoked. Now what happens is that the id of the record (i.e. extappId) is already defined and not null and so KendoUI believes that is already saved.
For solving this second issue my recommendation is defining the schema as:
schema: {
model: {
id: "ID",
fields: {
extappId: { type: "number" },
desc: { type: "string" },
deviceNo: { type: "number" },
validationKey: { type: "string" }
}
}
}
Now, the id is a field called ID and this ID should be created on transport.create (cannot be set before invoking add method).
Then, you set it in create and you can use:
create: function(options){
// Set `ID` to kendo.guid
options.data.ID = kendo.guid();
alert(options.data.desc);
var localData = JSON.parse(localStorage.getItem("LsAppList"));
localData.push(options.data);
localStorage.setItem("LsAppList", JSON.stringify(localData)); //localStorage["LsAppList"] = JSON.stringify(localData);
options.success(localData);
},
Check it here : http://jsfiddle.net/OnaBai/n7sNd/3/

Kendo UI Grid not loading data from datasource

I am new on kendo UI framework. I am struggling with observable datasource with kendoGrid.
The problem is the table gets created but with empty data.
Here is the link http://jsfiddle.net/praveeny1986/Pf3TQ/5/
And the code :
var gridDataModel = kendo.data.Model.define({
fields: {
"Product": {
type: "string"
},
"Domain": {
type: "string"
},
"PercentPlan": {
type: "string"
},
"CWV": {
type: "string"
},
"Target": {
type: "string"
},
"Accuracy": {
type: "string"
}
}
});
var dataSource = new kendo.data.DataSource({data: tabledata1});
var gridModel = kendo.observable({
gridData: dataSource
});
kendo.bind($("#chart"),gridModel);
$("#chart").kendoGrid({
scrollable:false,
dataSource:gridModel.get('gridData'),
height:600,
autoBind:true,
columns:[
{
field: "Product",
title: "Product"
},
{
field: "Domain",
title: "Sales Domain"
},
{
field: "PercentPlan",
title: "% to Plan"
},
{
field: "CWV",
title: "CWV"
},
{
field: "Target",
title: "Target"
},
{
field: "Accuracy",
title: "Accuracy"
}]
});
var tabledata1 = [
{
Product:"mobile",
Domain:"SMARTPHONES-EAST",
PercentPlan:"95",
CWV:"160",
Target:"200",
Accuracy:"9"
},
{
Product:"mobile",
Domain:2,
PercentPlan:"80",
CWV:"160",
Target:"200",
Accuracy:"8.5"
},
{
Product:"mobile",
Domain:3,
PercentPlan:"75",
CWV:"150",
Target:"200",
Accuracy:"8"
},
{
Product:"mobile",
Domain:4,
PercentPlan:"60",
CWV:"120",
Target:"200",
Accuracy:"6"
},
{
Product:"mobile",
Domain:5,
PercentPlan:"50",
CWV:"150",
Target:"300",
Accuracy:"5"
}
];
Please suggest what i am doing wrong ?
Thanks in advance
Your table data is undefined at the time that you create and bind the datasource.
var dataSource = new kendo.data.DataSource({data: tabledata1});
var tabledata1 = [ ... ];
Move the declaration of tabledata1 to before creating the datasource.
See this updated fiddle.
http://jsfiddle.net/nukefusion/Pf3TQ/7/

Resources