I have some jquery like this...
init: function () {
var self = this;
this.dataSource = new kendo.data.DataSource({
transport: {
read: {
url: $.url.action(self.controller, self.action, { projectId: projectId }),
cache: false,
dataType: "json"
}
},
schema: {
model: {
id: "StudyId",
fields: {
Name: { type: "string" },
ViewName: { type: "string" },
Description: { type: "string" },
ViewDescription: { type: "string" },
UpdateDate: { type: "date" },
StudyId: { type: "number" },
NextMilestoneName: { type: "string" },
NextMilestoneDate: { type: "date" },
StudyStatus: { type: "string"}
}
}
},
sort: { field: "UpdateDate", dir: "desc" },
sortable: { mode: "single", allowUnsort: false },
pageSize: 4
});
I want to conditionally display this depending on if ViewDescription is empty...
#if (!String.IsNullOrEmpty(????))
{
<span><strong>#Resources.Resources.Description1 </strong>#:ViewDescription#</span>
<br>
}
I can't figure it out! what do i put into the ????'s to access the ViewDescription?
Based on what you posted, it seems that you are trying to leverage a razor view based on information that wont exist until after the page loads, even until that Kendo control call "Read()". That Razor view will be built before that javascript has executed. However, after that code executes, you can do something like this in JS.
(Also check here: http://docs.telerik.com/kendo-ui/api/framework/datasource#events-change)
init: function () {
var self = this;
this.dataSource = new kendo.data.DataSource({
transport: {
read: {
url: $.url.action(self.controller, self.action, { projectId: projectId }),
cache: false,
dataType: "json"
}
},
change: function(e) {
if(e.items["ViewDescription"]!=null){
$("#IDofDivHere").append("<span><strong>#Resources.Resources.Description1</strong>"+e.items["ViewDescription"]+"</span><br>");
}
},
schema: {
model: {
id: "StudyId",
fields: {
Name: { type: "string" },
ViewName: { type: "string" },
Description: { type: "string" },
ViewDescription: { type: "string" },
UpdateDate: { type: "date" },
StudyId: { type: "number" },
NextMilestoneName: { type: "string" },
NextMilestoneDate: { type: "date" },
StudyStatus: { type: "string"}
}
}
},
sort: { field: "UpdateDate", dir: "desc" },
sortable: { mode: "single", allowUnsort: false },
pageSize: 4
});
So we are wiring up the kendo event change that should get fired when the data is retrieved (like a success callback in ajax), and then appending the data you wanted wherever you want it to go
Related
I need to set Kendo grid action button Icon based on value. My code as follows,
function InitProductServicesGrid() {
var prodServiceDataSource = new kendo.data.DataSource({
transport: {
type: "json",
read:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/GetProductServiceDetailsList",
type: "POST",
contentType: 'application/json',
data: GetAdditonalData,
datatype: "json"
},
update:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/SaveProductService",
type: "POST",
contentType: 'application/json',
datatype: "json"
}
},
schema: {
data: function (result) {
return JSON.parse(result.d);
},
model: {
id: "Id",
fields: {
Id: { type: "int" },
ServiceTime: { type: "string" },
IsActive: { type: "boolean"}
}
}
},
requestEnd: function (e) {
if (e.type === "destroy") {
var grid = $("#productServicesGrid").data("kendoGrid");
grid.dataSource.read();
}
},
error: function (e) {
e.preventDefault();
if (e.xhr !== undefined && e.xhr !== null) {
var messageBody = e.xhr.responseJSON.Message;
ShowGritterMessage("Errors", messageBody, false, '../App_Themes/Default/LtsImages/errorMessageIcon_large.png');
var grid = $("#productServicesGrid").data("kendoGrid");
grid.cancelChanges();
}
},
pageSize: 20,
});
$("#productServicesGrid").kendoGrid({
dataSource: prodServiceDataSource,
sortable: true,
filterable: false,
pageable: true,
dataBound: gridDataBound,
editable: {
mode: "inline",
confirmation: false
},
columns: [
{ field: "Id", title: "", hidden: true },
{
field: "ServiceTime",
title: "Time Standard",
sortable: false,
editor: function (container, options) {
var serviceTimeTxtBox = RenderServiceTime();
$(serviceTimeTxtBox).appendTo(container);
},
headerTemplate: '<a class="k-link" href="#" title="Time Standard">Time Standard</a>'
},
{
title: "Action", command: [
{
name: "hideRow",
click: hideRow,
template: comandTemplate
}
],
width: "150px"
}
]
});
}
I wrote a custom template function as follows,
function comandTemplate(model) {
if (model.IsActive == true) {
return '<a title="Hide" class="k-grid-hideRow k-button"><span class="k-icon k-i-lock"></span></a><a title="Hide"></a>';
}
else {
return '<a title="Show" class="k-grid-hideRow k-button"><span class="k-icon k-i-unlock"></span></a><a title="Show"></a>';
}
}
But when I debug the I saw the following value for model value.
I followed this sample code as well. here you can see, I also set the custom template like the sample code. Please help me to solve this. Why I can't access model IsActive value from comandTemplate function.
Updated
When clicking hideRow action, I access the dataItem as follows.
function hideRow(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if (dataItem.IsActive == true) {
dataItem.IsActive = false;
}
else {
dataItem.IsActive = true;
}
}
Is there any possible way to access data from template function as above or any other way?
I would suggest a different approach because you can't access grid data while rendering and populating grid.
My suggestion is to use two actions and hide it based on the flag (in your case IsActive).
Something like this: Custom command
NOTE: in visible function you can access item!
EDIT: you can access it and change it on dataBound traversing through all data.
Check this example: Data bound
I don't see the advantage of relying on the grid commands. You can render any button you want yourself and and use the dataBound event to bind a click handler:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{
template: function(dataItem) {
const isActive = dataItem.isActive;
return `<a title=${isActive ? "Hide": "Show"} class="k-grid-hideRow k-button"><span class="k-icon k-i-${isActive ? 'lock' : 'unlock'}"></span></a>`
}
}
],
dataBound: function(e) {
e.sender.tbody.find(".k-grid-hideRow").click(evt => {
const row = evt.target.closest("tr")
const dataItem = e.sender.dataItem(row)
dataItem.set("isActive", !dataItem.isActive)
})
},
dataSource: [{ name: "Jane Doe", isActive: false }, { name: "Jane Doe", isActive: true }]
});
Runnable Dojo: https://dojo.telerik.com/#GaloisGirl/eTiyeCiJ
I want to use the ShieldUI library (grid component) in order to present tabular data to the user.
The issue with this library is that if I create a new item and right after I want to edit or delete it, the grid is unable to provide its id (as the database generates for me), although I return the id from backend after the INSERT query is executed. Here is what I tried:
<!-- HTML and JS part -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery Shield UI Demos</title>
<link id="themecss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" />
<script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script>
</head>
<body class="theme-light">
<div id="grid"></div>
<script type="text/javascript">
$(document).ready(function () {
$("#grid").shieldGrid({
dataSource: {
remote: {
read: "/products",
modify: {
create: {
url: "/products/productCreate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
},
update: {
url: "/products/productUpdate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
},
remove: {
url: "/products/productRemove",
type: "post",
data: function (removed) {
return { id: removed[0].data.Id };
}
}
}
},
schema: {
fields: {
Id: { path: "Id", type: Number },
Price: { path: "Price", type: Number },
Name: { path: "Name", type: String },
Category: { path: "Category", type: String },
AddedOn: { path: "AddedOn", type: Date },
Active: { path: "Active", type: Boolean }
}
}
},
rowHover: false,
columns: [
{ field: "Name", title: "Product Name", width: "300px" },
{ field: "Price", title: "Price", width: "100px" },
{ field: "Category", title: "Category", width: "200px" },
{ field: "AddedOn", title: "Added On", format: "{0:MM/dd/yyyy}" },
{ field: "Active", title: "Active" },
{
title: " ",
width: "100px",
buttons: [
{ cls: "deleteButton", commandName: "delete", caption: "<img src='/Content/img/grid/delete.png' /><span>Delete</span>" }
]
}
],
editing: {
enabled: true,
event: "click",
type: "cell",
confirmation: {
"delete": {
enabled: true,
template: function (item) {
return "Delete row with ID = " + item.Id
}
}
}
},
toolbar: [
{
buttons: [
{ commandName: "insert", caption: "Add Product" }
],
position: "top"
}
]
});
});
</script>
<style>
.deleteButton img
{
margin-right: 3px;
vertical-align: bottom;
}
</style>
</body>
</html>
Below is the ASP.MVC part:
[ActionName("productCreate")]
public Product PostProduct(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = Products.Max(i => i.Id) + 1;
Products.Add(item);
return item;
}
To make this work, I need to refresh the grid's content by performing a sort operation (the framework updates the grid before sorting) or worse, a page refresh.
So what is the issue with this approach? Am I missing something?
We need to modify the create object and use AJAX call in order to make this work.
So instead of:
create: {
url: "/products/productCreate",
type: "post",
data: function (edited) {
var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
return {
Active: edited[0].data.Active,
AddedOn: date,
Category: edited[0].data.Category,
Name: edited[0].data.Name,
Price: edited[0].data.Price,
Id: edited[0].data.Id
};
}
}
You have to do:
create: function (items, success, error) {
var newItem = items[0];
$.ajax({
type: "POST",
url: "/products/productCreate",
dataType: "json",
data: newItem.data,
complete: function (xhr) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// update the id of the newly-created item with the
// one returned from the server
newItem.data.Id = xhr.responseJSON.Id;
success();
return;
}
}
error(xhr);
}
});
}
whenever i cancelled the updating process from the child node,the child node just merge with root node,i don't find error in the console or i can't find anything suspicious.but after a reload,all becomes normal
$(document).ready(function () {
var windowTemplate = kendo.template($("#windowTemplate").html());
var dataSource = new kendo.data.TreeListDataSource({
transport: {
read: {
url: "officeprofiletree",
type: 'POST',
dataType: "json"
},
update: {
url: "officeprofilenametree_update",
type: 'POST',
contentType :'application/json',
dataType: "json"
},
destroy: {
url: "officeprofilenametree_destroy",
type: 'POST',
contentType :'application/json',
dataType: "json"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models)
{
return JSON.stringify(options.models);
}
}
},
batch: true,
sort: { field: "name", dir: "asc" },
schema: {
model: {
id: "officeProfileNMId",
parentId: "parentId",
fields: {
officeProfileNMId: { type:"number" },
parentId:{nullable:true,type:"number"},
mobile:{ type:"string"},
address:{type:"string"},
phone: {type:"string"},
},
}
}
});
var window = $("#window").kendoWindow({
visible:false,
title: "Are you sure you want to delete this record?",
width: "450px",
height: "60px",
}).data("kendoWindow");
var treelist = $("#treelist").kendoTreeList({
dataSource: dataSource,
pageable: true,
dataBound: function (){
var tree = this;
var trs = this.tbody.find('tr').each(function(){
var item = tree.dataItem($(this));
if( item.parentId == null) {
$(this).find('.k-button,.k-button').hide();
}
});
},
columns: [
{ field: "name", title: "Name"},
{ field: "mobile", title:"Mobile", format: "{0:c}", hidden: true },
{ field: "address", title:"Address",hidden: true },
{ field: "phone",title:"Phone" ,hidden: true },
{ command: [
{name: "edit"},
{name: "Delete",
click: function(e){
e.preventDefault();
var tr = $(e.target).closest("tr");
var data = this.dataItem(tr);
window.content(windowTemplate(data));
window.center().open();
$("#yesButton").click(function(){
treelist.dataSource.remove(data);
treelist.dataSource.sync();
window.close();
reloading();
})
$("#noButton").click(function(){
window.close();
})
}
}
]}
] ,
editable: {
mode: "popup",
},
}).data("kendoTreeList");
});
the updation and deletion works fine by the way,Here is the fiddle
https://jsfiddle.net/me09jLy7/2/
updation:
whenever i create a child to ranikannur gives me 3 children with same name in each root ranikannur,in my database there is only one child is parented by ranikannur but treelist shows it as 3 children in each parent node,the children count 3 is getting from the total ranikannurparent nodes(here tree has 3 ranikannur parent nodes)
i guess.how is this getting the 3 children?
u just try it...
$(document).ready(function () {
var windowTemplate = kendo.template($("#windowTemplate").html());
var dataSource = new kendo.data.TreeListDataSource({
transport: {
read: {
url: "officeprofiletree",
type: 'POST',
dataType: "json"
},
update: {
url: "officeprofilenametree_update",
type: 'POST',
contentType :'application/json',
dataType: "json"
},
destroy: {
url: "officeprofilenametree_destroy",
type: 'POST',
contentType :'application/json',
dataType: "json"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models)
{
return JSON.stringify(options.models);
}
}
},
batch: true,
sort: { field: "name", dir: "asc" },
schema: {
model: {
id: "officeProfileNMId",
parentId: "parentId",
fields: {
officeProfileNMId: { type:"number" },
parentId:{nullable:true,type:"number"},
mobile:{ type:"string"},
address:{type:"string"},
phone: {type:"string"},
},
}
}
});
var window = $("#window").kendoWindow({
visible:false,
title: "Are you sure you want to delete this record?",
width: "450px",
height: "60px",
}).data("kendoWindow");
var treelist = $("#treelist").kendoTreeList({
dataSource: dataSource,
pageable: true,
dataBound: function (){
var tree = this;
var trs = this.tbody.find('tr').each(function(){
var item = tree.dataItem($(this));
if( item.parentId == null) {
$(this).find('.k-button,.k-button').hide();
}
});
},
columns: [
{ field: "name", title: "Name"},
{ field: "mobile", title:"Mobile", format: "{0:c}", hidden: true },
{ field: "address", title:"Address",hidden: true },
{ field: "phone",title:"Phone" ,hidden: true },
{ command: [
{name: "edit"},
{name: "Delete",
click: function(e){
e.preventDefault();
var tr = $(e.target).closest("tr");
var data = this.dataItem(tr);
window.content(windowTemplate(data));
window.center().open();
$("#yesButton").click(function(){
treelist.dataSource.remove(data);
treelist.dataSource.sync();
window.close();
reloading();
})
$("#noButton").click(function(){
window.close();
})
}
}
]}
] ,
editable: {
mode: "popup",
},
}).data("kendoTreeList");
});
Trying to create an event that changes a String called status in my NetworkApp collection.
Event:
Template.app_detail.events({
'click .accept': function (e, t) {
console.log("Accept");
NetworkApp.update(this._id, {$set:{
status: "Accepted"
}});
},
'click .reject': function (e, t) {
console.log("Reject");
NetworkApp.update(this._id, {$set:{
status: "Rejected"
}});
}
})
It updates the last time the application was modified but not the status. No errors appear in the console but it does log Accepted or Rejected so the code can connect to the db and the helper is being triggered by the buttons. Any help is appreciated!~
Simple Schema:
NetworkAppSchema = new SimpleSchema({
ign: {
type: String,
label: "IGN"
},
discordName: {
type: String,
label: "Discord Name"
},
memberlength: {
type: String,
label: "How long have you been a member at Digital Hazards?"
},
languageKnown: {
type: String,
label: "What languages do you know?",
autoform: {
type: 'textarea'
}
},
whyyou: {
type: String,
label: "Why do you want to join the Network staff?",
autoform: {
type: 'textarea'
}
},
applicant: {
type: String,
label: "Applicant",
autoValue: function() {
return Meteor.userId();
},
autoform: {
type: "hidden"
}
},
createdAt: {
type: Date,
label: "Applied At",
autoValue: function() {
return new Date();
},
autoform: {
type: "hidden"
}
},
status: {
type: String,
label: "Status",
autoValue: function() {
return "Pending";
},
autoform: {
type: "hidden",
}
}
});
autoValue does not mean initial value: your autoValue functions are running every time.
For createdAt for example you should have:
createdAt: {
type: Date,
denyUpdate: true,
autoValue() {
if (this.isInsert) return new Date();
},
},
this will avoid the createdAt ever changing after insert.
Similarly for status:
status: {
type: String,
label: "Status",
autoValue() {
if (this.isInsert) return "Pending";
},
autoform: {
type: "hidden",
}
}
Below code works fine with the data as in ReadOrder.json (below), however how to read the associated object when it is nested inside another object as in ReadOrderNested.json(below, within 'collection').
Question is more specifically can we use a mapping property or proxy's reader config with rootProperty (tried this approach with no luck)
Sencha fiddle : https://fiddle.sencha.com/#fiddle/9fb
Extjs version : 5.0.0
//Base Model
Ext.define('MyApp.model.Base', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}],
schema: {
namespace: 'MyApp.model'
}
});
//Order Model
Ext.define('MyApp.model.Order', {
extend: 'MyApp.model.Base',
fields: [{
name: 'customer',
type: 'string'
}, {
name: 'paymentStatus',
type: 'string'
}]
});
//PaymentDetail Model
Ext.define('MyApp.model.PaymentDetail', {
extend: 'MyApp.model.Base',
fields: [{
name: 'orderId',
reference: 'Order'
}, {
name: 'cardNumber',
type: 'string'
}, {
name: 'status',
type: 'string'
}]
});
Ext.define('MyApp.store.OrderStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.Order',
proxy: {
type: "rest",
url: 'Order.json',
appendId: false,
api: {
create: undefined,
read: 'ReadOrder.json',
update: 'UpdateOrder.json',
destroy: undefined
},
reader: {
type: 'json',
rootProperty: 'order'
},
writer: {
writeAllFields: true,
allDataOptions: {
persist: true,
associated: true
}
}
},
});
Ext.application({
name: 'MyApp',
launch: function() {
var orderStore = Ext.create('MyApp.store.OrderStore');
orderStore.load({
callback: function(records) {
var order = this.first();
debugger;
var paymentDetailList = order.paymentDetails();
paymentDetailList.each(function(paymentDetail) {
//Print initial values of payment detail
console.log(paymentDetail.get('cardNumber'));
console.log(paymentDetail.get('status'));
})
}
});
}
});
Data : ReadOrder.json
{ "success": true,
"order": [{
"id": 1,
"customer": "Philip J. Fry",
"paymentStatus": "AWAIT_AUTH",
"paymentDetails": [{
orderId : 1,
"cardNumber": "4111111111",
"status": 'CREATED'
}, {
orderId : 1,
"cardNumber": "4222222222",
"status": "CREATED"
}]
}]
}
How to read with this data when the associated object is nested inside 'collection', ReadOrderNested.json:
{ "success": true,
"order": [{
"id": 1,
"customer": "Philip J. Fry",
"paymentStatus": "AWAIT_AUTH",
"paymentDetails": {
"collection" : [{
orderId : 1,
"cardNumber": "4111111111",
"status": 'CREATED'
}, {
orderId : 1,
"cardNumber": "4222222222",
"status": "CREATED"
}]}
}]
}
I am using ExtJS 4, dunno whether there is a difference. I am using a model with fields like this:
fields: [{
name: 'id',
type: 'int'
},{
name: 'paymentDetails'
}],
and when loading one model into a form
form.load(record);
Ext.getStore("paymentDetailsStore").removeAll();
Ext.getStore("paymentDetailsStore").loadRawData(record.get("paymentDetails"));
with paymentDetailsStore bound to a grid which is in the same window as the form.