Uncaught TypeError: Cannot read property 'getRootNode' of undefined in ExtJs - extjs4.1

I'm trying to use the Store data which is hardcoded in store to form the tree check tree, but i cannot able to achieve this and i'm getting this error below
I'm new to extjs, can any one aware of this issue.
Uncaught TypeError: Cannot read property 'getRootNode' of undefined
Store
Ext.define('my.store.ModuleHomeStore', {
extend: 'Ext.data.TreeStore',
autoLoad : false,
root: {
text:'test Object Tree',
id:'TestTreeStoreId',
expanded: true,
children: [{
"text":"AntiVirus Software",
"id":"46",
"leaf":"false"
},
{
"text":"Appliance",
"id":"68",
"leaf":"false"
}
]
},
folderSort: true,
sorters: [{
property: 'text',
direction: 'ASC'
});
}];
views
Ext.define('my.view.MainTree', {
extend : 'Ext.tab.Panel',
width : 400,
height : 600,
alias : 'widget.MainTreeTest',
name : 'mainTree',
plain: true,
items : [{
xtype: 'pTree',
width:219,
height:700,
bbar: [{
xtype: 'button',
text: 'Cancel'
},{
xtype: 'button',
text: 'Ok'
}]
}]
});
Ext.define('my.view.PreTree', {
extend : 'Ext.tree.Panel',
title: 'MyPreference',
alias : 'widget.pTree',
id : 'preid',
store: 'ModuleHomeStore',
height: 600,
width: 400,
multiSelect: true,
rootVisible : false,
resizable:false,
hideHeaders : true,
sortable : true,
xtype:'check-tree'
});

I have created fiddles for you. They have working examples with your code.
Couple of points, as you know that ExtJs is MVC based framework, so kindly implement everything according to MVC structure.
Only issue related to your code was that in your view:
store: 'ModuleHomeStore',
is not returning a store instance. One way is to use make use of lookup for store using Ext.data.StoreManager.lookup as done in this fiddle.
Or you can create an instance of store as done here.
This is also another solution as suggested by another SO question. But then you should implement proper controllers and separate your views, stores, models to have full grip over framework.

Related

Grid Filter not submitting param values

I have a basic grid, and I have added some filters to columns. I added them in the constructor like so, since some of them use stores
constructor: function(config) {
Ext.apply(this, {
features : [{
ftype: 'filters',
encode: true,
local: false,
filters: [{
type: 'string',
dataIndex: 'name'
},{
type: 'string',
dataIndex: 'priority'
},{
type: 'list',
store: Ext.getStore('adminCategory'),
dataIndex: 'adminOrg',
labelField: 'displayName'
},{
type: 'list',
store: Ext.getStore('adminClientList'),
dataIndex: 'client',
labelField: 'name',
listeners: {
activate: function(obj, eOpts) {
console.log(obj);
}
}
}]
}]
});
this.callParent(arguments);
The menu items load just fine, however when the filter activates, and starts to load the store, the filter params are not present, so they aren't submitted to the server.
I checked the beforeload event on the store, and the filters array is empty (in the operations object where all the sorter info is stored too).
The filtersfeature doesn't store the filter info in the same place as the default filters go. I don't know why, but it doesn't. In the same object you found the filters and sorters arrays, look in the params property, there should be a property in params called filter. That will contain the filters. By default, I believe all the filters are encoded into a json string, so if you want them as an array, you'll have to use Ext.decode.

Sencha Touch 2.0 List Paging plugin working on one list, but not another

I have two lists in 2 separate tabs, both hooked up to a server side database. I'm attempting to set up list paging and on one of the lists its functioning exactly as it should be. For the other list, the model and store have all the same settings as the list that pages properly but no 'Load More..." text shows up at the bottom for this list.
With regards to the list paging plugin, both lists are basically exactly the same as each other (ie the Store, Model, 'List' view) but on one the paging just does not work. Does anyone have any idea what could possibly be causing this?
Editing with some more information:
I'm using Chrome to develop. Looking at the Network I seem to be getting JSON that looks right, for the one thats not working it's returning 8 records, and the total property returned is 13 (this makes sense because I've got my page size set to 8).
The Store from list that does NOT work
Ext.define("IdeaBank.store.SharedProblems", {
extend: "Ext.data.Store",
required: "IdeaBank.model.SharedProblem",
config: {
model: "IdeaBank.model.SharedProblem",
clearOnPageLoad: false,
pageSize: 8,
proxy: {
type: 'ajax',
api: {
create: "http://mywebsite.com/submitProblem.php?action=create",
read: "http://mywebsite.com/submitProblem.php?action=read",
update: "http://mywebsite.com/submitProblem.php?action=update",
destroy: "http://mywebsite.com/submitProblem.php?action=delete",
},
reader: {
type: 'json',
rootProperty: "problems",
totalProperty: "total",
}
},
autoLoad: true
}
});
The Store from list that does work
Ext.define("IdeaBank.store.SharedSolutions", {
extend: "Ext.data.Store",
required: "IdeaBank.model.SharedSolution",
config: {
model: "IdeaBank.model.SharedSolution",
clearOnPageLoad: false,
proxy: {
type: 'ajax',
api: {
create: "http://mywebsite.com/submitSolution.php?action=create",
read: "http://mywebsite.com/submitSolution.php?action=read",
update: "http://mywebsite.com/submitSolution.php?action=update",
destroy: "http://mywebsite.com/submitSolution.php?action=delete",
},
reader: {
type: 'json',
rootProperty: "solutions",
totalProperty: "total",
}
},
pageSize: 8,
autoLoad: true
}
});
List view from the one that does NOT work
Ext.define("IdeaBank.view.SharedProblemsList", {
extend: 'Ext.dataview.List',
alias: 'widget.sharedproblemslist',
requires: ['Ext.plugin.ListPaging'],
config: {
autoLoad: true,
plugins: [
{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true
}
],
loadingText: "Loading...",
emptyText: [
"</pre><div class='notes-list-empty-text' style = 'padding: 2em;'>",
"<p>There are no problems listed for the category you have selected.</p>",
"</div><pre>"
].join(""),
onItemDisclosure: true,
itemTpl: [
"</pre>",
"<div class = 'list-item-title'><span style = 'margin-right: 5px; color: #25E014; font-size: 0.7em;'>{rating}</span> {problem}</div>",
"<pre>"
].join(""),
}
});
List view from the one that does work
Ext.define("IdeaBank.view.SharedSolutionsList", {
extend: 'Ext.dataview.List',
alias: 'widget.sharedsolutionslist',
requires: ['Ext.plugin.ListPaging'],
config: {
autoLoad: true,
plugins: [
{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true
}
],
loadingText: "Loading...",
emptyText: [
"</pre><div class='notes-list-empty-text' style = 'padding: 2em;'>",
"<p>There are no published solutions for the category you have selected.<p>",
"</div><pre>"
].join(""),
onItemDisclosure: true,
itemTpl: [
"</pre>",
"<div class = 'list-item-title'><span style = 'margin-right: 5px; color: #25E014; font-size: 0.7em;'>{rating}</span> {title}</div>",
"<pre>"
].join(""),
}
});
Make sure that you implement the paging logic in your server side codes. You have to supply the functionality of sending page by page. Maybe "submitSolution.php" does not send the data partially.

Passing view with close button

I want the close button to be reusable so I created its own class so I can attach it to the views that need it. I want to just be able to pass the view that is attached to the view to the controller to close that view. It should be fairly simple and I would suspect that this is how many do it but I can't get it to work correctly. I get it to close the view but get the error
Uncaught TypeError: Cannot read property 'dom' of null
I understand this to generally mean that the view isn't being destroyed but I thought this told it to destroy the view:
Ext.Viewport.remove(curView, true);
Here is what I believe to be the pertinent code
Controller:
closeView: function(btn, e,opts){
var curView = btn.getParent().getParent();
console.log('From btn: ' + curView + ',' + opts);
Ext.Viewport.remove(curView, true);}
View:
Ext.define('SenchaFirstApp.view.DetailView',{
extend: 'Ext.tab.Panel',
requires: ['Ext.Toolbar', 'Ext.tab.Panel', 'Ext.form.FieldSet', 'Ext.field.Select'],
model: ['SenchaFirstApp.model.Details', 'SenchaFirstApp.model.SiteInfo'],
alias: 'widget.detailview',
// xtype: 'tabpanel',
config:
{
scrollable: true,
width: 1500,
height: 800,
// fullscreen: true,
layout: {type: 'card', animation:{type: 'flip'}},
centered: true,
border: 10,
tabBar: {
docked: 'top',
},
formParams: {
},
items:
[
{
//Tab bar
xtype: 'tbar',
title: 'Details View',
items: [
{
xtype: 'closebtn',
id: 'detailsBtn',
sourceForm: this
}]
},
{
title: 'Equipment Monitor', //first tab
xtype: 'monitor',
},
{
title: 'Site Information', //second tab
xtype: 'siteinfo',
}
]
} //End Config
I tried to use
Ext.Viewport.remove(Ext.Viewport.getActiveItem, true)
but that also didn't work. I suspect that has to do with how I created that view maybe. I'm new to Sencha so there could be many things I'm doing wrong so I appreciate the help.
I forgot to mention that, after closing the tab panel, I can't open it again without refreshing which again I'm sure is due to the view not being destroyed
It appears that the problem was using id's. I thought that I took them out but I guess not. I took the id's out and used alias's and got it working. I'm still not figuring out how to pass the view attached to the button but now
Ext.Viewport.remove(Ext.Viewport.getActiveItem, true)
is working. The true property tells it to destroy the view after removing it.

ExtJS 4 (MVC) Store not using my custom Model class

I'm using ExtJS 4.0.7 with its standard MVC architecture. I have a grid with custom store and model classes. The data is loaded remotely via store.load(). I'm using ext-dev.js for debug purposes with dynamic dependency loading.
The app loads fine with no errors in Chrome's console. But the problem is that the records in my store have exactly the same data as provided by my AJAX call, regardless of what fields I have in my model. I even tried renaming and deleting fields but Ext is not paying attention.
Browsing my store object using the console shows that the records all have their own custom runtime-generated model class named Ext.data.reader.Json-Modelext-gen1141. Here is the gist of my code:
My model:
Ext.define('MyApp.model.FooModel', {
extend: 'Ext.data.Model',
idProperty: 'column1',
fields: [
{name: 'column1', convert: function(value, record) {
return value + ' TEST-TEST-TEST';
}},
'column2',
'column3'
]
});
My store:
Ext.define('MyApp.store.FooStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.FooModel',
autoLoad: false,
proxy: {
type: 'ajax',
url: '/blah/blah',
reader: {
type: 'json'
}
}
});
My grid:
Ext.define('MyApp.view.FooGrid', {
extend: 'Ext.grid.Panel',
alias: 'fooGrid',
store: 'FooStore',
columns: [{
text: 'Column 1',
dataIndex: 'column1',
flex: 1
},{
text: 'Column 2',
dataIndex: 'column2',
flex: 1
},{
text: 'Column 3',
dataIndex: 'column3',
flex: 1
}]
});
My controller:
Ext.define('MyApp.controller.Foo', {
extend: 'Ext.app.Controller',
views: ['FooGridFrame'],
models: ['FooModel'],
stores: ['FooStore'],
init: function() {
this.control({
'fooGrid': {
activate: function(grid) {
grid.getStore().load();
}
}
});
}
});
I can't tell what I'm doing wrong. Any ideas?
It turns out that the AJAX backend (written by another dev for Ext3) was providing some config data via a metaData property. I didn't know that Ext's Store paid any attention to this. My problem was solved by updating the backend to omit the metaData property.
It probably would have also worked to update metaData to provide the appropriate config that I needed, but I'm refactoring to make all the UI config happen in the client.

Mixing tpl and items in Sencha Touch 2

I have a list detail view which works fine - it has a tpl and no items. I would like to add other components so I added an items array but now the tpl no longer shows. I have tried keeping the tpl in the main config and also adding it as a component to no avail (how does the data know where the appropriate tpl is located btw?) - I guess ideally I would like to be able to inject my list data anywhere on the page - i..e above and below and in between items. How is this done?
Ext.define("App.view.ListDetail", {
extend: "Ext.Container",
record: undefined,
config: {
layout: 'vbox',
style: "padding: 5px;",
scrollable: true,
// tpl: ["<div>", "name<br />verified star<br />avatar pic", "</div>"].join(""), // this works fine if I have no items array
//adding this causes above tpl to no longer render
items: [
{
xtype: 'component',
tpl: ["<div>", "name<br />verified star<br />avatar pic", "</div>"].join(""), //this does nothing
},
{
xtype: 'panel',
//more stuff here
},
]
}
});
Unfortunately you cannot mix tpl and items configurations together, as they both update the html of the component.
To achieve what you want, you will need to add another item into the items configuration, ensuring you position it where you want it, and then add your custom tpl config into that item.
Also, I'm sure you are aware, but you need to use the data configuration alongside tpl, or it will not show anything.
Ext.define("App.view.ListDetail", {
extend: "Ext.Container",
record: undefined,
config: {
layout: 'vbox',
style: "padding: 5px;",
scrollable: true,
//adding this causes above tpl to no longer render
items: [
{
xtype: 'component',
tpl: ["<div>", "name<br />verified star<br />avatar pic", "</div>"].join("") //this does nothing
},
{
xtype: 'panel'
//more stuff here
},
{
tpl: ["<div>", "name<br />verified star<br />avatar pic", "</div>"].join("") // this works fine if I have no items array
}
]
}
});