Hi I am in trouble with extjs 5 mvvm example. My store isn't recognized. I tried similliar solutions from stack but it still crashing.
Project structure:
structure
Code:
Message.js
Ext.define('Tgis.view.message.Message', {
extend : 'Ext.window.Window',
title: 'Wiadomosci',
requires : ['Tgis.view.message.MessageController'],
store: 'MessageStore',
alias : 'widget.message',
config : {
minHeight: 320,
minWidth:400,
bodyPadding : 10,
width : 500,
ghost : false,
bodyPadding : 10,
autoShow : true
},
items: [{
xtype:'panel',
layout : 'vbox',
items : [
{
xtype : 'mvvm-DateView' ,
flex : 1
},
{
xtype : 'mvvm-MessageView',
flex : 5
}]
}]});
Messagedate.js
Ext.define('Tgis.view.message.MessageDate', {
extend : 'Ext.grid.Panel',
xtype : 'mvvm-DateView',
store : 'MessageStore',
columns: [
{
text : 'Data',
dataIndex : 'date'
}
]});
MessageMaster.js
Ext.define('Tgis.view.message.MessageMaster', {
extend : 'Ext.form.Panel',
xtype : 'mvvm-MessageView',
requires : [
'Tgis.view.message.MessageViewModel'
],
title : 'Wiadomosci',
frame : true,
padding : 10,
viewModel : {
type : 'detailform' // references DetailViewModel
},
items : [
{
xtype : 'textfield',
bind : '{rec.message}',
fieldLabel : 'Tresc:'
},
{
xtype : 'hiddenfield',
bind : '{rec.id}'
}
]});
MessageModel.js
Ext.define('Tgis.view.message.MessageModel', {
extend : 'Ext.data.Model',
fields : [
{
name : 'date',
type : 'date'
},
{
name : 'message',
type : 'string'
},
{
name : 'id',
type : 'integer'
}
]});
Ext.define('Tgis.view.message.MessageStore', {
extend : 'Ext.data.Store',
model : 'Tgis.view.message.MessageModel',
storeId: 'MessageStore',
data : [
{
'date' : '28.05.1994',
'message' : 'lisa#simpsons.com',
'id' : '1'
}
]});
MessageController.js
Ext.define('Tgis.view.message.MessageController', {
extend : 'Ext.app.Controller',
init: function() {
this.control({
'mvvm-DateView': {
select : this.onGridSelect
}
});
},
onGridSelect : function(grid, record, index, eOpts) {
// grab a reference to the Detail view...
// we could have used a controller "ref", but those can also be problematic
var detailView = Ext.ComponentQuery.query('mvvm-DateView')[0];
//set the form's ViewModel binding
detailView.getViewModel().setData({ rec: record });
}});
MessageViewModel.js
Ext.define('Tgis.view.message.MessageViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.detailform',
data : {
rec : null
}});
Main.js
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [{
xtype: 'panel',
bind: {
title: '{name}'
},
region: 'west',
width: 250,
split: true,
defaultType : 'button',
layout : 'vbox',
items : [{
text : 'Wiadomości',
handler : 'onClickMessages'
},{
text : 'Wyczyść LC',
handler : 'onClearMessages'
}]
},{
region: 'center',
xtype: 'tabpanel',
items:[{
title: 'Tab 1',
html: '<h2>Content appropriate for the current navigation.</h2>'
}]
}]});
MainController.js
Ext.define('Tgis.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
onClickButton: function () {
Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
},
onConfirm: function (choice) {
if (choice === 'yes') {
//
}
},
onClickMessages : function(button) {
Ext.Ajax.request({
url : 'http://localhost:8080/Messagess/res',
method : 'GET',
success : function(response) {
var json = Ext.decode(response.responseText);
//var itemsArray = new Array();
/*for (var i = 0; i < json.data.length; i++) {
var date = new Date(json.data[i].date);
var messageTxt = Ext.create('Ext.form.field.TextArea', {
fieldLabel :date.toLocaleString(),
value : json.data[i].message,
editable : false,
grow : true,
width : '100%'
});
if (localStorage.getItem('date') != 'null')
itemsArray.push(messageTxt);
}
var checkbox = Ext.create('Ext.form.field.Checkbox', {
id : 'checkboxmessage',
boxLabel : 'Nie pokazuj ponownie'
});
itemsArray.push(checkbox);*/
Ext.create('Tgis.view.message.Message', {
//messagess: json.data
//Ext.getCmp('usernameID').setValue('JohnRambo');
/*items: itemsArray,
buttons : [{
xtype : 'button',
text : 'Zamknij',
handler : 'onCloseClick'
}]*/
})
}
});
},
onClearMessages : function(button) {
localStorage.setItem('date', '0');
}});
MainModel.js
Ext.define('Tgis.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
data: {
name: 'Tgis'
}});
Call store like this in view solved in my project
store: {
type: 'MessageStore'
}
You have defined a "store template" but not created a store instance.
If you want to create multiple stores of that type (e.g. one for each grid), do it like this:
xtype:'grid',
store:Ext.create('MyApp.store.SomeStore',{
...
}),
If you only want a single store of that type, just add the store to stores:[] array in Application.js and it should work.
Related
Uncaught TypeError: Cannot read property 'items' of null
the error is inside initComponent
my error show when i use my xtype: 'treepanel', i think the error inside the initComponent
userName = localStorage.getItem("userName");
Ext.define('TutorialApp.view.main.Main', {
extend : 'Ext.container.Container',
requires :
[
'TutorialApp.view.main.MainController',
'TutorialApp.view.main.MainModel',
'TutorialApp.store.MainTree'
],
xtype : 'app-main',
controller: 'main',
plugins : 'viewport',
viewModel :
{
type : 'main'
},
layout : {
type : 'border'
},
items :
[
{
xtype : 'panel',
bind :
{
title: '{name} '+userName+''
},
region : 'west',
html : '<ul><li>This area is commonly used for navigation, for example, using a "tree" component.</li></ul>',
width : 250,
split : true,
collapsible : true,`enter code here`
bbar :
[
{
text : 'Button',
handler : 'onClickButton'
}
],
items : [
{
xtype : 'treepanel',
rootVisible : true,
store : 'MainTree',
initComponent: function()
{
// declare store
this.store = new TutorialApp.store.MainTree();
// declare all items
this.items = [
{
title: 'Tree'
}
];
this.callParent();
}
}
]
},
{
region : 'center',
xtype : 'tabpanel',
items :
[
{
title : 'Tab 1',
html : '<h2>Content appropriate for the current navigation.</h2>'
}
]
}
]
});
This tree store comes
its a simple store
Ext.define('TutorialApp.store.MainTree', {
extend: 'Ext.data.TreeStore',
root: {
text: 'Root',
expanded: true,
children: [
{
text: 'Child 1',
leaf: true
},
{
text: 'Child 2',
leaf: true
},
{
text: 'Child 3',
expanded: true,
children: [
{
text: 'Grandchild',
leaf: true
}
]
}
]
}
});
any help ?
i think the error inside the initComponent
initComponent is not really supposed to be passed as a config option. If you need to apply your own logic in initComponent, you have to derive your own class. So, instead of:
{
xtype: 'treepanel',
rootVisible: true,
store: 'MainTree',
initComponent: function() {
// declare store
this.store = new TutorialApp.store.MainTree();
// declare all items
this.items = [
{
title: 'Tree'
}
];
this.callParent();
}
}
define your own tree panel:
Ext.define('MyTreePanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.mytreepanel',
initComponent: function() {
// declare store
this.store = new TutorialApp.store.MainTree();
// declare all items
this.items = [
{
title: 'Tree'
}
];
this.callParent();
}
});
and use its xtype:
{
xtype: 'mytreepanel',
rootVisible: true,
store: 'MainTree'
}
I need to get some data with making ajax request and load the grid (which is empty first) with this data but even i get the data i couldnt load it to the grid.
What i'm doing wrong?
Here is my grid :
var gridFlightForms = Ext.create('Ext.grid.Panel', {
id : 'gridFlightForms',
store : storeFlightFormList,
width : '100%',
height : 300,
collapsible : false,
multiSelect : false,
autoScroll : true,
disableSelection : false,
monitorWindowResize : true,
viewConfig : {
stripeRows : true,
enableTextSelection : true
},
title : 'Flight Forms ',
bbar : Ext.create('Ext.ux.statusbar.StatusBar', {
id : 'gridData-statusbar',
defaultText : '',
defaultIconCls : 'default-icon',
}),
verticalScroller : {
xtype : 'paginggridscroller',
},
columns : [ {
text : '<fmt:message key="common.number.text" />',
xtype : 'rownumberer',
width : 40,
sortable : false
}, {
text : 'Form Id',
menuDisabled : true,
dataIndex : 'formId',
width : 150,
}, {
text : 'Form no',
menuDisabled : true,
dataIndex : 'formNo',
width : 150,
}, {
text : 'Form Type',
menuDisabled : true,
dataIndex : 'formType',
width : 150,
}, {
text : 'Flight Id',
menuDisabled : true,
dataIndex : 'flightId',
width : 150,
}, {
text : 'Revision',
menuDisabled : true,
dataIndex : 'revision',
width : 150,
}, {
text : 'IsLiex',
menuDisabled : true,
dataIndex : 'isLiex',
width : 150,
}, {
text : 'IsPrimary',
menuDisabled : true,
dataIndex : 'isPrimary',
width : 150,
}, {
text : 'Step Number',
menuDisabled : true,
dataIndex : 'stepNumber',
width : 150,
} ]
});
and my store :
var storeFlightFormList = Ext.create('Ext.data.Store', {
model : flightListModelName,
autoLoad : false,
proxy : {
type : 'ajax',
actionMethods : {
read : 'POST'
},
reader : {
type : 'json',
root : 'data'
},
api : {
read : flightFormListUrl
}
},
listeners : {
load : function(store, records) {
}
}
});
and that part is making post and try to load data to grid. I think this part is wrong.
Actually i can see data in resp.data when i debug it, but i cant store it as i mentioned before.
postDataAsParamsINN(
{flightId : flightId},flightFormListUrl,function(resp) {
gridFlightForms.setLoading(true,true);
storeFlightFormList.loadRawData(resp.data,false);
});
Ext.getCmp('gridFlightForms').getStore().load();
I'm pretty new at extjs, thanks in advance.
I'm not quite sure what postDataAsParamsINN is supposed to be doing, you should not need to be loading the data in yourself.
This fiddle demonstrates a working grid that uses a JSON store.
Here is the code:
Ext.application({
name: 'Fiddle',
launch: function() {
var store = Ext.create('Ext.data.JsonStore', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'characters'
}
},
listeners: {
load: function() {
console.log(this);
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: store,
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
}
});
Once you've bound your store to the grid it automatically fills the grid with whatever information is loaded into the store and refreshes when the store is updated.
I have this json string look like:
[{
"totalCount" : 134
}, {
"items" : [{
"id" : 1669,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101669"
}, {
"id" : 1670,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101670"
}, {
"id" : 1671,
"check" : false,
"name" : "2118mm趟门衣柜",
"part_number" : "DP101671"
}, {
"id" : 1672,
"check" : false,
"name" : "2118mm趟门衣柜",
"part_number" : "DP101672"
}, {
"id" : 1673,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101673"
}, {
"id" : 1674,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101674"
}, {
"id" : 1675,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101675"
}, {
"id" : 1676,
"check" : false,
"name" : "1800mm趟门衣柜",
"part_number" : "DP101676"
}, {
"id" : 1677,
"check" : false,
"name" : "2118mm趟门衣柜",
"part_number" : "DP101677"
}, {
"id" : 1678,
"check" : false,
"name" : "2118mm趟门衣柜",
"part_number" : "DP101678"
}
]
}
]
and my store look like:
var item_store = Ext.create('Ext.data.Store', {
model:'ItemModel',
autoLoad: true,
pageSize: 5,
proxy: {
type: 'ajax',
reader: {
type:'json',
root: 'items',
totalProperty: 'totalCount'
},
url: 'item_access.jsp?fullpage=true&item_cat=167&group_id='+groupId
}
});
but it cant read the root node for the store ,now my table look like that:
only with two blank row,
look like are node totalCount and items:
so how should I config the reader to read that string??
that is my grid:
var itemPanel=Ext.create('Ext.grid.Panel', {
id: 'item-panel',
title: '产品',
store: item_store,
columns: [
{ header: 'id', dataIndex: 'id' , flex: 1 },
{ header: 'part_number', dataIndex: 'part_number' , flex: 2 },
{ header: 'name', dataIndex: 'name', flex: 3 },
{ xtype: 'checkcolumn',header: '可见', dataIndex: 'check' , flex: 2 ,
listeners:{
checkchange: function(col, idx, isChecked) {
var view = itemPanel.getView(),
record = view.getRecord(view.getNode(idx));
postData(record.get('id'),"ITEM",isChecked);
}
}
}
],
region: 'center',
layout: 'card',
// paging bar on the bottom
bbar: Ext.create('Ext.PagingToolbar', {
store: item_store,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display",
items:[
'-', {
text: 'Show Preview',
pressed: pluginExpanded,
enableToggle: true,
toggleHandler: function(btn, pressed) {
var preview = Ext.getCmp('gv').getPlugin('preview');
preview.toggleExpanded(pressed);
}
}]
}),
});
my model:
Ext.define('ItemModel', {
extend : 'Ext.data.Model',
idProperty : 'id',
fields : [{
name : "name",
convert : undefined
}, {
name : "id",
type : types.INT
}, {
name : "part_number"
}, {
name : "check",
type : types.BOOLEAN
}
]
});
In the 4.x series you can pass functions for both the root/total:
totalProperty: function(data) {
return data[0].totalCount
},
root: function(data) {
return data[1].items
}
You may change the data structure if possible :
{ "totalCount": 134, "items": [] }
Edit
I have setup a quick test using ext-all-debug.js from version 4.2.0.663, the same as in your JsFiddle. At first glance, the problem comes from the line 41343 :
root = Ext.isArray(data) ? data : me.getRoot(data);
At this point getRoot - which refers to the root property somehow - is not called because data is an array. This is not a bug. I rather think that you misuse the JSON reader which is designed to consider an array not as a configuration structure, but as a record list. Sorry for repeating this but you'd better replace the array with an object as mentionned above. If it's not possible you'll have to bring some changes to the framework in order to make it suit your needs.
So I have a view, and a controller linked to that view, and I would like to dynamically assign values to a xtype item in the view via store.
So for example, I would like dynamically setup layouts (please have a look at the proveded code) and urls
items: [
{
itemId: 'nav_home',
id: 'homeView',
layout: "{layout}",
items: [{
xtype: 'articlelist',
id: 'latestNews',
url: {url},
}
],
},
Could anyone lead me how to approach this task?
Thanks
You can use initialize function to render components based on some condition. Here is an example :
Ext.define('MyApp.view.MyView', {
extend: 'Ext.Container',
alias : 'widget.myview',
config: {
items : [],
mylayout: null
},
initialize : function(){
var me = this;
if(me.config.mylayout == 'horizontal'){
me.add({
xtype : 'panel',
layout : 'hbox',
items : [{
xtype : 'panel',
html : 'first content'
},
{
xtype : 'panel',
html : 'second content'
}]
});
} else if(me.config.mylayout == 'vertical'){
me.add({
xtype : 'panel',
layout : 'vbox',
items : [{
xtype : 'panel',
html : 'first content'
},
{
xtype : 'panel',
html : 'second content'
},
{
xtype : 'panel',
html : 'third content'
}]
});
}
me.callParent();
}
});
You can create this view like this:
var myView = Ext.create("MyApp.view.MyView", {
mylayout : 'vertical'
});
mylayout could be any configuration object you want to pass.
Playing around with Sencha Touch 2.0 and have stumbled upon a problem. I want a list to show in my Ext.Container but nothing is happening.
My class (LoggedInView.js)
Ext.define("GS.view.LoggedInView", {
extend: "Ext.Container",
config: {
layout: 'vbox',
items: [{
xtype: "toolbar",
docked: "top",
title: "Pågående anbud"
},{
xtype: 'list',
itemTpl: '{name}',
flex: 1,
store : 'Auction'
}]
}
});
My Store (Auction.js)
Ext.define('GS.store.Auction', {
extend: 'Ext.data.Store',
config: {
autoLoad: true,
fields: ['name'],
data: [
{name: 'test1'},
{name: 'test2'},
{name: 'test3'},
{name: 'test4'},
]
},
});
My application (app.js)
Ext.application({
name: 'GS',
requires: [
'Ext.MessageBox'
],
views: ['Main', 'LoggedInView'],
stores: ['Auction'],
....etc...
What am I doing wrong here? I get the toolbar rendered correctly but the list is not showing.
EDIT
Alos attached my (main.js)
// The login button
var button = Ext.create('Ext.Button', {
text: 'Logga in',
minHeight: '45px',
handler: function (b, e) {
var form = Ext.getCmp('register');
form.submit({
url: 'URL HERE',
method: 'POST',
success: function (frm, res) {
var paneltab = Ext.create('GS.view.LoggedInView');
Ext.getCmp('register').destroy();
Ext.Viewport.add(paneltab);
},
failure: function (frm, res) {
alert('Form no submit!');
}
});
}
});
var loginForm = Ext.create('Ext.form.Panel', {
fullscreen: true,
id: 'register',
frame:true,
items: [
{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'userName',
placeHolder : 'Användarnamn'
},
{
xtype: 'passwordfield',
name : 'password',
placeHolder : 'Lösenord'
}
]
},
{
xtype: 'container',
items: [button]
},
]
});
Add fullscreen: true to your view config
My class (LoggedInView.js)
Ext.define("GS.view.LoggedInView", {
extend: "Ext.Container",
config: {
layout: 'vbox',
fullscreen: true,
items: [{
xtype: "toolbar",
docked: "top",
title: "Pågående anbud"
},{
xtype: 'list',
itemTpl: '{name}',
flex: 1,
store : 'Auction'
}]
}
});
Your code in senchafiddle: http://www.senchafiddle.com/#HcaOD
EDIT:
In your Main.js you don't define your Main View, so it can't be created in app.js
Reworked Main.js
Ext.define('GS.view.Main', {
extend : 'Ext.form.Panel',
config : {
fullscreen : true,
id : 'register',
frame : true,
items : [{
xtype : 'fieldset',
items : [{
xtype : 'textfield',
name : 'userName',
placeHolder : 'Användarnamn'
}, {
xtype : 'passwordfield',
name : 'password',
placeHolder : 'Lösenord'
}]
}, {
xtype : 'button',
text : 'Logga in',
minHeight : '45px',
handler : function(b, e) {
var form = Ext.getCmp('register');
form.submit({
url : 'http://testurl.com',
method : 'POST',
success : function(frm, res) {
var paneltab = Ext
.create('GS.view.LoggedInView');
Ext.getCmp('register').destroy();
Ext.Viewport.add(paneltab);
},
failure : function(frm, res) {
alert('Form no submit!');
}
});
}
}]
}
});
A additional problem ist, that the post method doesn't work, because it's not submitted, so it alerts "Form no submit!". But when you put your success code in the failure function, the list is shown.
However i recommend you to put the button handler in a controller.
The button Code then look like this:
{
xtype : 'button',
text : 'Logga in',
minHeight : '45px',
action: 'submitFormAction'
}
Controller.js
Ext.define('GS.controller.Controller', {
extend : 'Ext.app.Controller',
config : {
control : {
'button[action="submitFormAction"]' : {
tap : 'submitForm'
},
}
},
submitForm : function() {
var form = Ext.getCmp('register');
form.submit({
url : 'http://testurl.com',
method : 'POST',
success : function(frm, res) {
var paneltab = Ext.create('GS.view.LoggedInView');
Ext.getCmp('register').destroy();
Ext.Viewport.add(paneltab);
},
failure : function(frm, res) {
alert('Form no submit!');
}
});
}
});
Then you must add the controller in your app.js with controllers:['Controller'],.
Working senchafiddle: http://www.senchafiddle.com/#HcaOD#pArtn
Ok, found the solution to this problem. It was my Main.js class that was not defined. Restructured the code some and voila!
Ext.define('GS.view.Main', {
extend: 'Ext.form.Panel',
config: {
fullscreen: true,
id: 'register',
frame:true,
items: [{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'userName',
placeHolder : 'Användarnamn'
},
{
xtype: 'passwordfield',
name : 'password',
placeHolder : 'Lösenord'
}
]
}, {
xtype: 'button',
text: 'Logga in',
minHeight: '45px',
handler: function (b, e) {
var form = Ext.getCmp('register');
form.submit({
url: 'MY URL HERE',
method: 'POST',
success: function (frm, res) {
var paneltab = Ext.create('GS.view.LoggedInView');
Ext.getCmp('register').destroy();
Ext.Viewport.add(paneltab);
},
failure: function (frm, res) {
alert('Form no submit!');
}
});
}
}]
}
});