I'm trying to import kendo-grid in salesforce LWC component.
Salesforce provides a loadScript method which parses and loads any external component in a LWC component. I'm trying to load kendo grid using this component. Unfortunately i wont be able to import kendo.all.min.js since loadScript fails for this method.
So I'm trying to load the individual dependencies modules of kendo grid. Below is the current code that i have. I'm basically figuring out the dependencies through trial and error and resolved most of the issues.
loadScript(this, jquery + '/jquery.min.js')
.then(() => loadScript(this, kendojs + '/kendo.core.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.data.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.columnsorter.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.groupable.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.draganddrop.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.columnmenu.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.filtermenu.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.grid.min.js'))
.then(() => {
Promise.all([
loadStyle(this, kendocss + '/kendo.common.min.css'),
loadStyle(this, kendocss + '/kendo.default.min.css'),
loadStyle(this, kendocss + '/kendo.default.mobile.min.css')
]).then(() => {
const ele = this.template.querySelector('div.datatable');
// eslint-disable-next-line no-undef
$(ele).kendoGrid({
dataSource: {
data: products,
schema: {
model: {
fields: {
ProductName: { type: "string" },
UnitPrice: { type: "number" },
UnitsInStock: { type: "number" },
Discontinued: { type: "boolean" }
}
}
},
pageSize: 20
},
height: 550,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
"ProductName",
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px" },
{ field: "UnitsInStock", title: "Units In Stock", width: "130px" },
{ field: "Discontinued", width: "130px" }
]
});
}).catch(error => {
alert(error);
});
})
Error
c.observable is not defined
Can someone let me know which module i can load to resolve this dependency in kendo?
Edit 1
Updated the staticresources for kendo as well as the the loadScript Sequence as suggested by the official kendo docs, It now throws Invalid template error
Code
loadScript(this, jquery + '/jquery.min.js')
.then(() => loadScript(this, kendojs + '/kendo.core.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.data.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.columnsorter.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.userevents.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.draganddrop.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.sortable.min.js'))
.then(() => loadScript(this, kendojs + '/kendo.grid.min.js'))
.then(() => {
Promise.all([
loadStyle(this, kendocss + '/kendo.common.min.css'),
loadStyle(this, kendocss + '/kendo.default.min.css'),
loadStyle(this, kendocss + '/kendo.default.mobile.min.css')
]).then(() => {
let ele = this.template.querySelector('div.datatable');
// eslint-disable-next-line no-undef
$(ele).kendoGrid({
dataSource: {
data: products,
schema: {
model: {
fields: {
ProductName: { type: "string" },
UnitPrice: { type: "number" },
UnitsInStock: { type: "number" },
Discontinued: { type: "boolean" }
}
}
}
},
columns: [
"ProductName",
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px" },
{ field: "UnitsInStock", title: "Units In Stock", width: "130px" },
{ field: "Discontinued", width: "130px" }
]
});
}).catch(error => {
console.error(error);
alert(error);
});
})
Error
kendoGrid.js:1322 Error: Invalid template:'<tr data-uid="#=data.uid#" role='row'><td data-field="ProductName"class="#= data && data.dirty && data.dirtyFields && data.dirtyFields['ProductName'] ? ' k-dirty-cell' : '' #" role='gridcell'>#= data && data.dirty && data.dirtyFields && data.dirtyFields['ProductName'] ? '<span class="k-dirty"></span>' : '' ##:data.ProductName==null?'':data.ProductName#</td><td data-field="UnitPrice"class="#= data && data.dirty && data.dirtyFields && data.dirtyFields['UnitPrice'] ? ' k-dirty-cell' : '' #" role='gridcell'>#= data && data.dirty && data.dirtyFields && data.dirtyFields['UnitPrice'] ? '<span class="k-dirty"></span>' : '' ##:kendo.format("{0:c\}",data.UnitPrice==null?'':data.UnitPrice)#</td><td data-field="UnitsInStock"class="#= data && data.dirty && data.dirtyFields && data.dirtyFields['UnitsInStock'] ? ' k-dirty-cell' : '' #" role='gridcell'>#= data && data.dirty && data.dirtyFields && data.dirtyFields['UnitsInStock'] ? '<span class="k-dirty"></span>' : '' ##:data.UnitsInStock==null?'':data.UnitsInStock#</td><td data-field="Discontinued"class="#= data && data.dirty && data.dirtyFields && data.dirtyFields['Discontinued'] ? ' k-dirty-cell' : '' #" role='gridcell'>#= data && data.dirty && data.dirtyFields && data.dirtyFields['Discontinued'] ? '<span class="k-dirty"></span>' : '' ##:data.Discontinued==null?'':data.Discontinued#</td></tr>' Generated code:'var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;with(data){$kendoOutput='<tr data-uid="'+(data.uid)+'" role=\'row\'><td data-field="ProductName"class="'+( data && data.dirty && data.dirtyFields && data.dirtyFields['ProductName'] ? ' k-dirty-cell' : '' )+'" role=\'gridcell\'>'+( data && data.dirty && data.dirtyFields && data.dirtyFields['ProductName'] ? '<span class="k-dirty"></span>' : '' )+''+$kendoHtmlEncode(data.ProductName==null?'':data.ProductName)+'</td><td data-field="UnitPrice"class="'+( data && data.dirty && data.dirtyFields && data.dirtyFields['UnitPrice'] ? ' k-dirty-cell' : '' )+'" role=\'gridcell\'>'+( data && data.dirty && data.dirtyFields && data.dirtyFields['UnitPrice'] ? '<span class="k-dirty"></span>' : '' )+''+$kendoHtmlEncode(kendo.format("{0:c}",data.UnitPrice==null?'':data.UnitPrice))+'</td><td data-field="UnitsInStock"class="'+( data && data.dirty && data.dirtyFields && data.dirtyFields['UnitsInStock'] ? ' k-dirty-cell' : '' )+'" role=\'gridcell\'>'+( data && data.dirty && data.dirtyFields && data.dirtyFields['UnitsInStock'] ? '<span class="k-dirty"></span>' : '' )+''+$kendoHtmlEncode(data.UnitsInStock==null?'':data.UnitsInStock)+'</td><td data-field="Discontinued"class="'+( data && data.dirty && data.dirtyFields && data.dirtyFields['Discontinued'] ? ' k-dirty-cell' : '' )+'" role=\'gridcell\'>'+( data && data.dirty && data.dirtyFields && data.dirtyFields['Discontinued'] ? '<span class="k-dirty"></span>' : '' )+''+$kendoHtmlEncode(data.Discontinued==null?'':data.Discontinued)+'</td></tr>';}return $kendoOutput;'
at Object.compile (kendo.core.js:238)
at Object.i [as template] (jquery.min.js:2)
at init._tmpl (kendo.grid.js:6302)
at init._templates (kendo.grid.js:6456)
at init._continueInit (kendo.grid.js:1509)
at new init (kendo.grid.js:1499)
at Proxy.eval (kendo.core.js:2517)
at Function.each (jquery.min.js:2)
at S.fn.init.each (jquery.min.js:2)
at S.fn.init.e.fn.<computed> [as kendoGrid] (kendo.core.js:2516)
eval # kendoGrid.js:1322
Promise.catch (async)
eval # kendoGrid.js:1321
Promise.then (async)
connectedCallback # kendoGrid.js:1281
callHook # aura_proddebug.js:14564
(anonymous) # aura_proddebug.js:7261
runWithBoundaryProtection # aura_proddebug.js:10292
invokeComponentCallback # aura_proddebug.js:7259
runConnectedCallback # aura_proddebug.js:10063
insert # aura_proddebug.js:6339
createChildrenHook # aura_proddebug.js:6140
insert # aura_proddebug.js:6299
updateStaticChildren # aura_proddebug.js:5485
(anonymous) # aura_proddebug.js:9966
runWithBoundaryProtection # aura_proddebug.js:10292
patchShadowRoot # aura_proddebug.js:9959
rehydrate # aura_proddebug.js:9943
flushRehydrationQueue # aura_proddebug.js:10013
flushCallbackQueue # aura_proddebug.js:4769
Promise.then (async)
addCallbackToNextTick # aura_proddebug.js:4781
scheduleRehydration # aura_proddebug.js:10178
(anonymous) # aura_proddebug.js:7577
notify # aura_proddebug.js:7500
valueMutated # aura_proddebug.js:7425
set # aura_proddebug.js:8215
_selectTab # tabBar.js:443
_selectTabAndFireSelectEvent # tabBar.js:411
handleTabClick # tabBar.js:401
callHook # aura_proddebug.js:9790
(anonymous) # aura_proddebug.js:7379
runWithBoundaryProtection # aura_proddebug.js:10292
invokeEventListener # aura_proddebug.js:7373
(anonymous) # aura_proddebug.js:6657
handleEvent # aura_proddebug.js:4890
handler # aura_proddebug.js:4896
listener.$$lwcEventWrapper$$ # aura_proddebug.js:2495
Thanks in advance
You can find the dependencies for every control listed here https://docs.telerik.com/kendo-ui/intro/scripts/scripts-general
For your convenience, below is the list for the Grid. If you have any further trouble, please open a new post in the official Kendo Grid forum so you can get an answer from the Kendo team (the forums are now open to anyone).
jquery.js - REQUIRED
kendo.core.js - REQUIRED
kendo.data.js - REQUIRED
kendo.columnsorter.js - REQUIRED
kendo.userevents.js - REQUIRED
kendo.draganddrop.js - REQUIRED
kendo.sortable.js - REQUIRED
kendo.selectable.js - Editing feature (optional)
kendo.calendar.js - Editing feature (optional)
kendo.popup.js - Editing feature (optional)
kendo.datepicker.js - Editing feature (optional)
kendo.numerictextbox.js - Editing feature (optional)
kendo.validator.js - Editing feature (optional)
kendo.binder.js - Editing feature (optional)
kendo.editable.js - Editing feature (optional)
kendo.window.js - Editing feature (optional)
kendo.selectable.js - Filtering feature (optional)
kendo.calendar.js - Filtering feature (optional)
kendo.popup.js - Filtering feature (optional)
kendo.datepicker.js - Filtering feature (optional)
kendo.numerictextbox.js - Filtering feature (optional)
kendo.list.js - Filtering feature (optional)
kendo.dropdownlist.js - Filtering feature (optional)
kendo.binder.js - Filtering feature (optional)
kendo.filtermenu.js - Filtering feature (optional)
kendo.popup.js - Column menu feature (optional)
kendo.selectable.js - Column menu feature (optional)
kendo.calendar.js - Column menu feature (optional)
kendo.datepicker.js - Column menu feature (optional)
kendo.numerictextbox.js - Column menu feature (optional)
kendo.list.js - Column menu feature (optional)
kendo.dropdownlist.js - Column menu feature (optional)
kendo.binder.js - Column menu feature (optional)
kendo.filtermenu.js - Column menu feature (optional)
kendo.data.odata.js - Column menu feature (optional)
kendo.menu.js - Column menu feature (optional)
kendo.columnmenu.js - Column menu feature (optional)
kendo.groupable.js - Grouping feature (optional)
kendo.popup.js - Row filter feature (optional)
kendo.list.js - Row filter feature (optional)
kendo.autocomplete.js - Row filter feature (optional)
kendo.filtercell.js - Row filter feature (optional)
kendo.pager.js - Paging feature (optional)
kendo.selectable.js - Selection feature (optional)
kendo.reorderable.js - Column reordering feature (optional)
kendo.resizable.js - Column resizing feature (optional)
kendo.popup.js - Grid adaptive rendering feature (optional)
kendo.dialog.js - Grid adaptive rendering feature (optional)
kendo.binder.js - Grid adaptive rendering feature (optional)
kendo.fx.js - Grid adaptive rendering feature (optional)
kendo.view.js - Grid adaptive rendering feature (optional)
kendo.pane.js - Grid adaptive rendering feature (optional)
kendo.switch.js - Grid adaptive rendering feature (optional)
kendo.ooxml.js - Excel export feature (optional)
kendo.excel.js - Excel export feature (optional)
kendo.color.js - PDF export feature (optional)
kendo.popup.js - PDF export feature (optional)
kendo.drawing.js - PDF export feature (optional)
kendo.pdf.js - PDF export feature (optional)
kendo.progressbar.js - PDF export feature (optional)
kendo.grid.js
Related
I've two locale; "fa" and "en" with fa being default. I've tried to change it with the following code block both on nuxtServerInit and fetch hook of layout but it still revert back to my default locale and gives me json.parse error on route change.
// using "nuxt": "^2.15.8" , "#nuxtjs/i18n": "^7.2.0" , "#nuxtjs/universal-storage": "^0.5.9" , "#nuxtjs/vuetify": "^1.12.3"
async fetch(){
let locale = this.$storage.getCookie('localeLang')
if(!!locale){
await this.$i18n.setLocale(locale)
this.$vuetify.rtl = this.$i18n.localeProperties.dir === 'rtl'
this.$storage.setCookie('localeLang', locale, {maxAge: 315360000})
}
}
When using in fetch hook i can see for a moment that it's in en then revert back to fa . but the htmlAttr of meta are set according to en locale (which has been set on cookie)
So what should I do? Any idea?
// nuxt.config.js
i18n: {
baseURL: process.env.DEFAULT_BASE_URL,
locales:[
{
code: 'fa',
iso: 'fa-IR',
file: 'fa.js',
currency: {name:'تومان', sign:'ت'},
dir: 'rtl',
name: 'فارسی',
initial: 'FA',
},
{
code: 'en',
iso: 'en-US',
file: 'en.js',
currency: {name:'Dollar', sign:'$'},
dir: 'ltr',
name: 'English',
initial: 'EN',
},
],
defaultLocale: 'fa',
strategy: 'no_prefix',
lazy: true,
langDir: '~/locale/lang/',
detectBrowserLanguage: false,
// vueI18n: '~/plugins/vue-i18n.js',
},
I am trying to navigate to a nested stack, when I use navigation.push(AppRoutes.RescueMeLanding.Name) I get the error:
Couldn't find a 'component', 'getComponent' or 'children' prop for the screen 'RescueMeStackScreen'. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined in, or mixed up default import and named import when importing.
Any ideas?
const AppRoutes = {
....
RescueMeLanding: {
Name: 'RescueMeStackScreen',
Label: 'Rescue Me',
isProtected: true,
},
....
};
RescueMeStackScreen:
const RescueMeStackScreen = () => {
return (
<RescueMeStack.Navigator
initialRouteName={AppRoutes.RescueMeLanding.Name}
>
<RescueMeStack.Screen
name={AppRoutes.RescueMeLanding.Name}
component={RescueMeLandingScreen}
options={{ headerShown: false }}
/>
<RescueMeStack.Screen
name={AppRoutes.RescueMeMap.Name}
component={RescueMeScreen}
options={{ headerShown: false }}
/>
;
</RescueMeStack.Navigator>
);
RootStackNavigator:
const RootStackNavigator = () => {
return (
<RootStack.Navigator
initialRouteName={AppRoutes.LoginRegistration.Name}
mode="modal"
>
....
<RootStack.Screen
name={AppRoutes.RescueMeLanding.Name}
component={RescueMeStackScreen}
options={{
title: AppRoutes.Register.Label,
headerShown: false,
animationEnabled: false,
}}
/>
....
</RootStack.Navigator>
);
When navigating to nested component, you need to specify parent explicitly.
See this for further information.
Thus, in your case;
navigation.push(AppRoutes.RescueMeLanding, { screen: AppRoutes.RescueMeLanding.Name })
What I also would suggest is name stack differently than the screen. Such as;
navigation.push(AppRoutes.RescueMeLandingStack, { screen: AppRoutes.RescueMeLanding.Name })
I have some problems with integration CKeditor 4 and CKFinder 3 in My Laravel Vue app.
I just want the functionality when I click on "image button" in my Ckeditor - CKFinder window appears and I'm able to upload all needed images.
What problems I have? (a few, but they must be related with each other):
I have that error in my devtools console: "[CKEDITOR] Error code: cloudservices-no-token-url." (I'm supposing that issue must be resolved when I properly integrate CKeditor with CKFinder)
(as WARN in devtools) - " [CKEDITOR] Error code: editor-plugin-conflict. {plugin: "image", replacedWith: "easyimage"} "
"Image Button" in my CKeditor disappeared (ckeck screenshot below):
You can see my Vue component code with config for ckeditor:
...
export default {
components: { VueCkeditor },
data() {
return {
content: '',
config: {
toolbar: [
{ name: 'styles', items : [ 'Styles','Format', 'FontSize' ] },
{ name: 'clipboard', items : ['Undo','Redo' ] },
{ name: 'editing', items : [ 'Scayt' ] },
{ name: 'insert', items : [ 'Image','Table','HorizontalRule','SpecialChar','Iframe' ] },
{ name: 'tools', items : [ 'Maximize' ] },
'/',
{ name: 'basicstyles', items : [ 'Bold','Italic','Strike','RemoveFormat' ] },
{ name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote' ] },
{ name: 'links', items : [ 'Link','Unlink','Anchor' ] },
],
height: 400,
extraPlugins: 'autogrow,uploadimage',
filebrowserBrowseUrl: '/filemanager_storage?type=Files',
filebrowserUploadUrl: '/filemanager_storage/upload?type=Files&_token='+window.Laravel.csrfToken,
},
};
},
...
Other details which may be useful:
I use CKFinder 3 Package for Laravel 5.5+ (https://github.com/ckfinder/ckfinder-laravel-package)
In my ckfinder.php (configurations for CKFinder) I set temporally that code:
$config['authentication'] = function () {
return true;
};
I'm not sure in that paths (in my config object in vue):
filebrowserBrowseUrl: '/filemanager_storage?type=Files',
filebrowserUploadUrl: '/filemanager_storage/upload?type=Files&_token='+window.Laravel.csrfToken,
},
*I created 'filemanager_storage' directory in my 'public' directory
Thanks guys a lot for any help!
I was facing similar issues regarding a ckeditor4.x integration I did recently in an opencart site with php. While it's not the same environment with vue, maybe this could prove useful to you.
Instead of using the easyimage plugin for managing the image upload , I replaced it with the image2 (enhanced image plugin) . After you've downloaded the image2 plugin and placed it under the ckeditor4/plugins/ directory, make sure to add this in your ckeditor instance:
extraPlugins : 'image2',
removePlugins: 'easyimage,cloudservices'
Regarding the urls in the ckeditor instance, while I'm not using the filebrowserBrowseUrl , I've declared the filebrowserUploadUrl as such :
filebrowserUploadUrl: '/path_where_ckfinder_is_installed/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json
While in my case it made the image upload possible, I'm still getting the warning [CKEDITOR] Error code: editor-plugin-conflict. {plugin: "image", replacedWith: "image2"} " This is something that I haven't been able to solve yet, but at least the image upload works in my case with no fuss.
Also, make sure in the config.php of ckfinder that you've declared the BaseUrl and root path for the user files directory, i.e
$config['backends'][] = array(
'name' => 'default',
'adapter' => 'local',
'baseUrl' => $your_file_path,
'root' => '/your_root_dir/' . $your_file_path, // Can be used to explicitly set the CKFinder user files directory.
'chmodFiles' => 0777,
'chmodFolders' => 0755,
'filesystemEncoding' => 'UTF-8'
);
Let me know if this solution suits your case.
I am changing only a couple of pages but docpad seems to render everything again. I'm not using any fancy plugins or dynamic components - just the basic ghost template. Are there some techniques to make less pages render?
maybe its something to do with the timestamp format in the docpad.coffee ?
moment = require('moment')
docpadConfig = {
templateData:
vars:
appserver: 'http://xxx'
site:
title: 'Pocket Tutor'
tagline: 'English language chat tutor'
description: 'Learn english by chatting'
logo: '/uploads/images/corpid/comiceng/96/logo-96.png'
url: 'http://app:9005'
cover: '/img/cover.jpg'
navigation: [
{
name: 'Home',
href: '/',
section: 'home'
},
{
name: 'About',
href: '/about.html',
section: 'about'
},
{
name: 'Lessons',
href: '/tags/lessons.html',
section: 'tag-lessons'
},
{
name: 'Grammar',
href: '/tags/grammar.html',
section: 'tag-grammar'
}
{
name: 'Teachers',
href: '/tags/tech.html',
section: 'tag-tech'
},
]
author:
name: 'Rikai Labs'
img: ''
url: 'http://rikai.co'
website: 'http://RIKAI.co'
location: 'space',
bio: 'we build chat apps'
getPreparedTitle: -> if #document.title then "#{#document.title} | #{#site.title}" else #site.title
getDescription: -> if #document.description then "#{#document.description} | #{#site.description}" else #site.description
bodyClass: -> if #document.isPost then "post-template" else "home-template"
masthead: (d) ->
d = d || #document
if d.cover then d.cover else #site.cover
isCurrent: (l) ->
if #document.section is l.section then ' nav-current'
else if #document.url is l.href then ' nav-current'
else ''
excerpt: (p,w) ->
w = w || 26
if p.excerpt then p.excerpt else p.content.replace(/<%.+%>/gi, '').split(' ').slice(0, w).join(' ')
encode: (s) -> encodeURIComponent(s)
slug: (s) -> return s.toLowerCase().replace(' ', '-')
currentYear: -> new Date().getFullYear()
time: (ts, format) ->
format = format || 'MMMM DO, YYYY'
ts = new Date(ts) || new Date()
moment(ts).format(format)
collections:
posts: ->
#getCollection("html").findAllLive({active:true, isPost: true, isPagedAuto: {$ne: true}}, {postDate: -1}).on "add", (model) ->
model.setMetaDefaults({layout:"post"})
plugins:
tags:
extension: '.html'
injectDocumentHelper: (doc) ->
doc.setMeta { layout: 'tag' }
rss:
default:
collection: 'posts'
url: '/rss.xml'
marked:
gfm: true
environments: # default
development: # default
# Always refresh from server
maxAge: false # default
# Only do these if we are running standalone via the `docpad` executable
checkVersion: process.argv.length >= 2 and /docpad$/.test(process.argv[1]) # default
welcome: process.argv.length >= 2 and /docpad$/.test(process.argv[1]) # default
prompts: process.argv.length >= 2 and /docpad$/.test(process.argv[1]) # default
# Listen to port 9005 on the development environment
port: 9005 # example
production:
port: 9005
maxAge: false # default
}
module.exports = docpadConfig
update: stubbing out the date and time methods
time: -> 'time'
currentYear: -> 'year'
gives a little speed up but still making one edit to one file gives info:
Generated 40/150 files in 7.364 seconds
update2: added
standalone: true
to some pages to test, but still takes
info: Generated 40/150 files in 7.252 seconds
so even a single standalone page triggers a bunch of other stuff.
It is possible to handle the Docpad regeneration process manually. To do this you need to turn off Docpad's watch. That is, run Docpad with the docpad server command. What will happen here is that it doesn't matter how many times you edit a document it will not be loaded into the docpad collection. You will then have to load any updates manually. That is, have some code to load the document.
model = #docpad.getCollection('posts').findOne({someValue: someValue})
model.load()
Following that trigger the regeneration.
#docpad.action 'generate', reset: false, (err) ->
if err
#docpad.log "warn", "GENERATE ERROR"
This is what I do in my posteditor plugin
I suspect this is not really what you are asking for but it does give you full control over the regeneration process.
I am using Ext.net 2.0 and I am trying to load the first record of the store inside a form panel. I always get no records (getCount() = 0) in the store ? Am I missing something ?
#(Html.X().Store()
.ID("myStore")
.AutoSync(true)
.AutoDataBind(true)
.Proxy(proxy =>
proxy.Add(
Html.X().AjaxProxy().API(api =>
{
api.Create = "/Property/Save/";
api.Read = "/Property/GetById/";
})
.Reader(reader => reader.Add(Html.X().JsonReader().Root("data").IDProperty("P_ID")))
.Writer(writer => writer.Add(Html.X().JsonWriter().AllowSingle(true)))
))
.Listeners(c =>
{
c.DataChanged.Handler ="var store = Ext.getStore('myStore');" +
"alert(store.getCount());";
})
.AutoLoadParams(parameters =>
{
parameters.Add(Html.X().Parameter().Name("id").Value("document.location.href.split('/')[5]").Mode(ParameterMode.Raw));
})
.Model(model => model.Add(
Html.X().Model()
.Fields(fields =>
{
fields.Add(Html.X().ModelField().Name("ID").Type(ModelFieldType.Int));
fields.Add(Html.X().ModelField().Name("DispalyName").Type(ModelFieldType.String));
fields.Add(Html.X().ModelField().Name("Title").Type(ModelFieldType.String));
fields.Add(Html.X().ModelField().Name("ShortDescription").Type(ModelFieldType.String));
})
))
)
For the form panel
#(
Html.X().FormPanel()
.ID("myPanel")
.Layout(LayoutType.Form)
.Width(350)
.FieldDefaults(d => {
d.LabelWidth = 150;
})
.BodyPadding(10)
.Items(item =>
{
item.Add(Html.X().TextField().ID("Id").Name("ID").FieldLabel("Id").Hidden(true));
item.Add(Html.X().TextField().ID("DispalyName").Name("IdDispalyName").FieldLabel("Id Dispaly Name").MaxLength(400));
item.Add(Html.X().TextField().ID("Title").Name("Title").FieldLabel("Title").AllowBlank(false).MaxLength(200));
item.Add(Html.X().TextField().ID("ShortDescription").Name("ShortDescription").FieldLabel("Short Description").MaxLength(200));
}
) )
Thanks in advance.
More appropriate event is Load (it is fired when data is loaded to the store from a remote source)
See the following description
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Store-event-datachanged