Ext js summaryRenderer function not calling - model-view-controller

This is my view
Ext.define('view.OrdersGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.ordersgrid',
store: 'TicketOrders',
features:[
{
ftype: 'groupingsummary',
groupHeaderTpl: [
'{[values.rows[0].data.EventName]} — <small class="muted">{[values.rows[0].data.EventDate]}</small>',
],
//hideGroupedHeader: true,
//collapsible: false,
remoteRoot: 'record',
//showSummaryRow: true,
}
],
initComponent: function () {
var me = this;
me.on('edit', function (editor, e) {
me.getSelectionModel().select(e.record);
me.fireEvent('onEdit', e.record);
});
me.selModel.on('select', function (t, record, index, eOpts) {
me.fireEvent('onRecordSelected', record);
});
me.selModel.on('deselect', function (t, record, index, eOpts) {
me.fireEvent('onRecordSelected', record);
});
me.columns =
[
{
id: 'order',
text: "Order Id",
sortable: true,
dataIndex: 'TOId',
hidden: true
},
{
text: "Order Number",
flex: 1.5,
sortable: true,
dataIndex: 'OrderNumber',
renderer: function (value, metadata, record) {
if (record.get('OrderStatus') == 3) { // error orders
return value + " <img src='images/icons/icon_question_mark.gif' title='" + record.get('Description') + "'/>";
}
else {
return value;
}
}
},
{
text: "Event",
flex: 3,
sortable: true,
dataIndex: 'EventName',
hidden: true,
//summaryType: 'sum',
renderer: function (value, metadata, record) {
return value + " ( " + record.get('TicketCount') + " )";
}
},
{
text: "Price",
flex: 1,
sortable: true,
dataIndex: 'TotalCharges',
//summaryType: 'sum',
//renderer: function (value, summaryData, dataIndex) {
// debugger;
// return parseInt(value);
// }
summaryRenderer: function (value, metadata, record) {
debugger;
return Ext.String.format(
"Total: {0}",
Ext.Number.toFixed(value)
);
}
}
];
this.callParent(arguments);
}, // end init function
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
})
], //end plugins
}
);
This is my model
Ext.define('model.TicketOrder', {
extend: 'Ext.data.Model',
fields: [
'TOId',
'OrderNumber',
'EventName',
'TicketCount',
{
name: 'TotalCharges',
type: 'int'
}
],
idProperty: 'TOId',
proxy: {
// load using script tags for cross domain, if the data in on the same domain as
// this page, an HttpProxy would be better
type: 'ajax',
disableCaching: true,
url: 'WebService.asmx/GetTicketOrdersByUserId?userId=' + Utilities.UserId,
reader: {
root: 'orders',
totalProperty: 'totalCount'
},
// sends single sort as multi parameter
simpleSortMode: true
}
});
This is my store
Ext.define('store.TicketOrders', {
extend: 'Ext.data.Store',
model: 'model.TicketOrder',
autoLoad: false,
remoteSort: false,
pageSize: 50,
groupField: 'EventOriginalId'
});
I am using MVC architecture, I have put a debugger in summaryRenderer in view but it is not executing and not showing any summary row, need help please. Also tell me what the remoteRoot should be set..enter code here

Un-comment out 'showSummaryRow: true" you will need this. Then for each column you define that you want a summary on you will need to define the summaryRenderer: function() {...} and SummaryType: 'sum'. EXTJS can be a real pain, especially when you want to do something custom. Watch out for extra commas (looks like you've got a couple in the features portion). Try to keep it as simple as possible. Best of luck!
features:[
{
ftype: 'groupingsummary',
groupHeaderTpl: [
'{[values.rows[0].data.EventName]} — <small class="muted">{[values.rows[0].data.EventDate]}</small>',
],
//hideGroupedHeader: true,
//collapsible: false,
remoteRoot: 'record',
showSummaryRow: true
}
],

Related

How to sync my Store when I update the bounded record using form (onUpdateClick). I'm using Extjs 7.5 (Sencha CMD)

This is my first time using a javascript framework, I would like to implement MVVM in my EXT JS application and the data is coming from my WEB API (ASP.NET FRAMEWORK).
My problem is that, I don't seem to understand how to fully use viewModel which looks up to my store. I successfully bound my ViewModel in my grid but now I don't know how to update the selected record using a form (modal) and sync my store (send update request through API)
I have a feeling that I'm doing it the wrong way. I don't know how to do this in fiddle so I'll just paste my code here.
Genre.js [Model]
Ext.define('VAM2.model.Genre', {
extend: 'VAM2.model.Base',
alias: 'model.genre',
fields: [
{name: 'GenreId', type: 'int'},
{name: 'Code', type: 'string'},
{name: 'CreatedBy', type: 'string'},
]
});
Genre.js [Store]
Ext.define('VAM2.store.Genre', {
extend: 'Ext.data.Store',
alias: 'store.genre',
model: 'VAM2.model.Genre',
autoLoad: false,
pageSize: 10,
storeId: 'GenreId',
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
});
GenreViewModel.js - I'm not sure if this is okay but the read is working
Ext.define('VAM2.view.genre.GenreViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.genre',
requires:[
'VAM2.model.Genre'
],
stores: {
myGenres : {
model: 'VAM2.model.Genre',
autoLoad: true,
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
}
},
data:{
title:'Sample Binding'
},
formulas: {
currentRecord: {
bind: {
bindTo: '{groupGrid.selection}', //--> reference configurated
//--> on the grid view (reference: groupGrid)
deep: true
},
get: function(record) {
return record;
},
set: function(record) {
if (!record.isModel) {
record = this.get('records').getById(record);
}
this.set('currentRecord', record);
}
}
}
});
View -- This is where it gets confusing. I don't know how to put the bounded data from grid to a form modal and then save and sync my store.
Ext.define('VAM2.view.genre.GenreList', {
extend: 'Ext.container.Container',
xtype: 'myGenreList',
requires: [
'VAM2.view.genre.GenreController',
'VAM2.view.genre.GenreViewModel',
'Ext.grid.column.Boolean',
'Ext.form.field.Checkbox',
'Ext.form.field.TextArea',
'Ext.form.field.Text'
],
controller: "genre",
viewModel: {
type: "genre"
},
width:'100%',
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
style: {
backgroundColor: '#f5f5f5'
},
items: [{
xtype: 'grid',
reference: 'groupGrid', //--> used in the viewmodel,
bind: {
title: '{title}',
store: '{myGenres}'
},
columns: [{
text:'GenreIdField',
id:'GenreIdField',
dataIndex:'GenreId',
hidden:true
},{
text: 'Code',
dataIndex: 'Code',
flex:1
}, {
text: 'Created By',
dataIndex: 'CreatedBy',
flex: 1
}],
listeners:{
select:'onGenreSelected_FORMA' //--> I'm thinking this will trigger
//-> a form (modal) containing the data to update
}
}]
});
A fiddle example would be great! Thank you!
Screenshot:
This is where I would like to display form modal that can sync/update my store when I modify some data.
To do store.sync() you need to set values on the record first.
Example is without ViewModel:
https://fiddle.sencha.com/#fiddle/3isg&view/editor
select: function (grid, record) {
console.log(record);
let win = Ext.create("Ext.window.Window", {
title: 'Edit',
modal: true,
autoShow: true,
width: 400,
height: 500,
controller: {},
items: [{
xtype: 'form',
reference: 'form',
fieldLabel: 'name',
items: [{
xtype: 'textfield',
name: 'name'
}]
}],
buttons: [{
text: 'cancel',
handler: function () {
win.close();
}
}, {
text: 'save',
handler: function () {
var values = this.lookupController().lookup('form').getValues();
record.set(values);
grid.getStore().sync({
scope: this,
success: function () {
win.close();
Ext.toast({
html: 'Well done',
align: 't'
});
},
failure: function () {
Ext.toast({
html: 'Problem occurred',
align: 't'
});
}
});
}
}],
listeners: {
afterrender: function () {
this.lookupController().lookup('form').loadRecord(record);
}
}
})
}

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/

kendoui grid cell editor of dropdownlist

I created a KendoUI grid where the first column uses a custom editor. After editing, it doesn't call request of update, however if it is not using editor it will call request of update. Why?
var columns = [
{ field: 'AccountId', title: '客户名称', locked: false, template: '#= me.detail.brandName(data, \'ID\') #', editor: accountGridEditor, width: 200 },
{ field: 'BankNo', title: '付款银行', template: '#= me.detail.format(data, \'Bank\') #', attributes: { style: 'text-align: left;' }, width: 150 },
{ field: 'UnLinkedAmount', title: '未分配', template: '#= me.detail.format(data, \'UnLinkedAmount\') #', attributes: { style: 'text-align: left;' }, width: 100 },
{ command: ["edit", "destroy"], title: " ", width: "250px" }
];
var dataSource = c.dataSourceOption({
transport: {
read: { url: url.api('Finance/FundJournal') },
update: { url: url.api('Finance/FundJournal', { action: 'post' }) },
destroy: { url: url.api('Finance/FundJournal', { action: 'delete' }), type: 'delete' },
parameterMap: function (data, type) {
console.log(type);
console.log(data);
if (type === 'read') return getReadParameters();
if (type === "update") return data;
if (type === 'create') return data;
if (type === 'destroy') return { id: data.Id };
return data;
}
},
schema: {
model: {
id: "Id",
fields: {
AccountId: { editable: true, nullable: false, validation: { required: true } },
BankNo: { editable: false},
UnLinkedAmount: { editable: false }
}
}
},
filter: [{ field: 'SubType', operator: 'neq', value: 'Id' }]
});
var grid = $("#result").kendoGrid({
dataSource: dataSource,
height: 550,
columns: columns,
editable: "inline",
save:function(e){$.ajax();}
}).data('kendoGrid');
If record property is set from dropdownlist something like this:
change: function() {
options.model.Name = this.value();
options.model.dirty = true;
}
it is necessary explicitly to set that model as dirty, to say to datasource that this record was modified and need to be updated. Otherwise, you can use set().
change: function() {
options.model.set('Name',this.value());
}
That way record is automatically marked as dirty in datasource.

How to retrieve a text value in a kendo drop down list within a kendo grid cell but still pass the ID in CRUD

I'm having a problem finding a solution related to the Kendo Grid.
I am rendering a kendo dropdown list within a cell of a Kendo Grid. It appears to look fine and all, until the user focuses off or tabs off of the dropdown within the cell. The red hash shows that a change was made, but it's showing the data-value-field of the kendo DDL and not the text. Ok, I realize I can just use the same field from the DS in the dataTextField as I'm using in the dataValueField, but that won't work for me...because when I'm calling create or update, I need to be able to pass the primary key or ID of that selected item back into my web api controller.
Here is the grids DS
function loadContactGrid(vendorID) {
var contactsReadURL = null;
contactsReadURL = "/contacts/getcontacts/" + parseInt(vendorID);
contactGridDS = new kendo.data.DataSource({
transport: {
read: {
url: contactsReadURL,
type: 'GET',
contentType: "application/json; charset=utf-8",
},
update: {
url: "/contacts/UpdateContacts/",
type: 'PUT',
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function(xhRequest, ErrorText, thrownError) {
alert('ERROR!!!\n' + ' xhRequest: ' + xhRequest + '\n' + ' ErrorText: ' + ErrorText + '\n' + ' thrownError: ' + thrownError + '\n');
},
complete: function(e) {
$("#contactGrid").data("kendoGrid").dataSource.read();
}
},
destroy: {
url: "/contacts/DeleteContact/",
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "DELETE"
},
create: {
url: "/contacts/InsertContact/",
contentType: "application/json; charset=utf-8",
type: 'POST',
dataType: "json",
success: function(results) {
alert('Contacts successfully saved!');
},
error: function(xhRequest, ErrorText, thrownError) {
alert('ERROR!!!\n' + ' xhRequest: ' + xhRequest + '\n' + ' ErrorText: ' + ErrorText + '\n' + ' thrownError: ' + thrownError + '\n');
},
complete: function(e) {
$("#contactGrid").data("kendoGrid").dataSource.read();
}
},
parameterMap: function(options, operation) {
if (operation !== "read" && options) {
return JSON.stringify(options.models);
}
if (operation == "create") {
// send the created data items as the "models" service parameter encoded in JSON
return { models: kendo.stringify(data.models) };
}
}
},
batch: true,
scrollable: false,
pageSize: 8,
change: function(e) {
if (e.action == "itemchange" && e.field == "email") {
var model = e.items[0];
if (isEmailValid($('input[name=email]').val()) == false) {
e.items[0].receivereport = false;
}
}
if (e.action == "itemchange" && e.field == "contacttype") {
var model = e.items[0];
//setTimeout(function () {
//$('.k-dirty-cell').focusout(function() {
//alert($(this).text(textOverrideContactType(e.items[0].contacttype)));
//});
//textOverrideContactType(e.items[0].contacttype);
//}, 1000); attempting to change text in cell here failed
}
if (e.action === "remove") {
this.sync();
}
},
schema: {
model: {
id: 'contactid',
fields: {
roletyp_seq: { editable: false, nullable: false, required: true, type: 'string' },
contacttype: { editable: true, nullable: false, required: true, type: 'number' },
roletyp_pk: { editable: false, nullable: false, required: true, type: 'number' },
contactid: { editable: false, nullable: false, required: true, type: 'number' },
vendorid: { editable: false, nullable: false, required: true, type: 'number' },
prevrole_pk: {
editable: false,
nullable: true,
required: true,
type: "number",
}
}
}
},
});
And my grid
$("#contactGrid").kendoGrid({
dataSource: contactGridDS,
navigatable: true,
dataBound: mapContactTypes,
editable: true,
//editable: "inline",
//editable: "popup",
edit: function (input) {
if ($('input[name=receivereport]').is(':focus')) {
//detect if email is valid
//get input immediately before this one
if (isEmailValid($('input[name=receivereport]').parent().prev().text()) == false) {
// disable check box
// alert("invalid");
$('input[name=receivereport]').attr('disabled', 'true');
$('input[name=receivereport]').prop('checked', false);
} else {
// enable check box
// alert("valid");
$('input[name=receivereport]').removeAttr('disabled');
$('input[name=receivereport]').prop('checked', false);
}
}
//when user clicks into or out of a field, if the name in the respective row name is blank, alert the user
var grid = this;
var fieldName = grid.columns[input.container.index()].field;
if (isNameInContactGridPopulated(fieldName) == false) {
alert("You can't leave out a contact name in the row you are editing.");
//disable save button
$('.k-grid-save-changes').addClass('k-state-disabled');
$('.k-grid-save-changes').hide();
} else {
//do nothing
$('.k-grid-save-changes').removeClass('k-state-disabled');
$('.k-grid-save-changes').show();
}
if ($('input[name=contactname]').is(":focus") == true) {
//disable save button
if ($('input[name=contactname]').val() == '') {
$('.k-grid-save-changes').addClass('k-state-disabled');
$('.k-grid-save-changes').hide();
}
}
$('input[name=contactname]').keyup(function() {
if ($(this).val() == '') {
$('.k-grid-save-changes').addClass('k-state-disabled');
$('.k-grid-save-changes').hide();
}
});
$('input[name=contactname]').focusout(function () {
if ($(this).val() != '') {
$('.k-grid-save-changes').removeClass('k-state-disabled');
$('.k-grid-save-changes').show();
}
});
},
toolbar: ["save", "cancel"],
pageable: true,
columns: [
{ field: 'roletyp_seq', title: 'RT Seq.', hidden: true, attributes: { 'class': 'contactCell_roletyp_seq' } },
{ field: 'contacttype', title: 'Contact Type', hidden: false, attributes: { 'class': 'contactCell_contacttype' }, editor: loadContactTypeEditor, width: "200px", template: "#=textOverrideContactType(1)#" },
//{ field: 'contacttype', title: 'Contact Type', hidden: false, attributes: { 'class': 'contactCell_contacttype' }, editor: loadContactTypeEditor, width: "200px", template: "#=textOverrideContactType(contacttype)#" },
//{ field: 'contacttype', title: 'Contact Type', hidden: false, attributes: { 'class': 'contactCell_contacttype' }, editor: loadContactTypeEditor, width: "200px" },
{ field: 'prevrole_pk', title: 'prev role ID', hidden: true, attributes: { 'class': 'contactCell_prevrole_pk' } },
{ field: 'roletyp_pk', title: 'Role Type ID', hidden: true, attributes: { 'class': 'contactCell_roletyp_pk' } },
{ field: 'contactid', title: 'Contact ID', hidden: true, attributes: { 'class': 'contactCell_contactid' } },
{ field: 'vendorid', title: 'Vendor ID', hidden: true, attributes: { "class": 'contactCell_vendorid' } },
{ field: 'contactname', title: 'Name', hidden: false, attributes: { "class": 'contactCell_contactname' } },
{ field: 'workphone', title: 'Phone', hidden: false, attributes: { "class": 'contactCell_phone' } },
{ field: 'mobilephone', title: 'Cell', hidden: false, attributes: { "class": 'contactCell_mobilephone' } },
{ field: 'title', title: 'Title', hidden: false, attributes: { "class": 'contactCell_title' } },
{ field: 'email', title: 'Email', hidden: false, attributes: { "class": 'contactCell_email' } },
{ field: 'receivereport', title: 'Receive Reports?', hidden: false, attributes: { "class": 'contactCell_receivereport' }, template: '<input type="checkbox" #= receivereport ? "checked=checked" : "" # value="" disabled="disabled" ></input>' },
{ command: "destroy", title: " ", width: "100px" }
],
sortable: {
mode: 'single',
allowUnsort: false
}
});
Then, I have two functions below. 1 is the custom editor and the other is an attempt I considered to override the text displayed in the kendo ddl.
function loadContactTypeEditor(container, options) {
var contactTypeDS = new kendo.data.DataSource({
dataType: "json",
type: "GET",
transport: {
read: "/contacts/GetAllContactTypes/"
}
});
contactTypeDS.read();
$('<input class="contactTypeDropDown" required data-text-field="roletyp_dsc" data-value-field="roletyp_pk" data-bind="value:' + options.field + '"/>').appendTo(container).kendoDropDownList({
dataTextField: "roletyp_dsc",
dataValueField: "roletyp_pk",
autoBind: false,
select: function (e) {
//if (e.sender.text() != '') {
// $('#contactGrid_active_cell').html(e.sender.text());
//}
//if (e.sender.text() != '') {
// setTimeout(function() {
// $('.contactCell_contacttype').text(e.sender.text());
// }, 1000);
//}
//options.model[options.field] = e.sender.text();
},
//dataBound: function(){
// options.model[options.field] = e.sender.text();
//},
dataSource: contactTypeDS
});
}
function textOverrideContactType(roleId) {
//need to find a match on the passed in role/contact type ID and return it's match to "mask/overwrite" the text that's there after a user selects an item in the dropdown
$.ajax({
dataType: 'json',
type: 'GET',
url: "/contacts/GetAllContactTypes/",
contentType: 'application/json; charset=utf-8',
success: function (data) {
$.each(data, function (key, val) {
if (roleId == key) {
return val;
}
});
},
failure: function (error) {
alert("Error loading contact types.");
}
});
}
To summarize: I tried a few things with no avail. What is happening, is, the DDL renders just fine, and even when the user doesn't move off of that DDL, the proper "label" shows, but when that control loses focus, it shows the data-value-field. I can't have that, I need to be able to show the data-text-field. That's why I wrote that textoverride method. But I'm trying to call it within the grid, fields's template: and it's not working. It says it doesn't recognize that function. I don't get it; it's clearly declared. What am I supposed to pass in as the parameter, it's not exactly like the demo here...a bit different, as I'm populating the DDL with another remote data source.
http://demos.telerik.com/kendo-ui/grid/editing-custom
Here's the other thing; I need that data-value-field, ID, to persist and be passed into my web api controller when it gets called. Right now, as it stands, I'm only able to get the "text" to show in the controller and not the "ID." That ID will not be available to me in the read method. The stored procs that the CRUD is hitting is completely different. My stored proc for insert and update needs to get that contacttype ID as the number.
Thanks in advance. I'm sure I'm close...
From the provided information it seems that you need to make the column ForegnKey by setting the "values" option of the column. Please check the example below:
[demo] Grid: ForeignKey column
[documentation] Grid API: columns.values option
I actually ended up using another means to do this. The above still seems illusive to me. I ended up changing the values of a key in another row, that was already available, to get passed back into the controller. I tried the answers provided with no avail. Sorry!

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