extjs4 treepanel behaviour issue - extjs4

i am working in extjs4. I have treeview as-
store is loading json values correctly in treeview. But when i am clciking on treenodes its expanding only once and if we click again its giving error as-
"TypeError: listener.fireFn is undefined".And treenodes are not getting expanded again.
i have treeview code as-
Ext.define('Balaee.view.qb.qbquestion.tree1', {
extend: 'Ext.tree.Panel',
//title: 'Simple Tree',
width: 200,
id:'tree1',
height: 150,
// floating:true,
alias : 'widget.tree1',
//store: Ext.data.StoreManager.lookup('qb.qbquestionStore'),
store:'qb.qbquestionStore',
displayField: 'text',
rootVisible : true,
multiSelect : true,
valueField:'id',
renderTo: Ext.getBody(),
And treestore as-
Ext.define('Balaee.store.qb.qbquestionStore',{
extend: 'Ext.data.TreeStore',
model: 'Balaee.model.qb.QbquestionModel',
autoLoad: true,
constructor: function() {
Ext.apply(this,{
proxy: {
type: 'ajax',
url: 'index.php/qbquestion/getCategory'
},
root: {
text: 'Main',
id: 'src',
expanded: true
}
});
this.callParent(arguments);
}
});
So how to overcome this

Related

Grid for Update Entries

I did the following code to list the searched items in the grid.
Ext.onReady(function(){
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
var searchUsers = new Ext.FormPanel({
renderTo: "searchUsers",
frame: true,
title: 'Search Users',
bodyStyle: 'padding:5px',
width: 500,
items:[{
xtype:'textfield',
fieldLabel: 'Username',
name: 'userName'
}],
buttons:[
{
text:'Search',
formBind: true,
listeners: {
click: function(){
Ext.Ajax.request({
method:'GET',
url : url+'/lochweb/loch/users/getUser',
params : searchUsers.getForm().getValues(),
success : function(response){
console.log(response); //<--- the server response
Ext.define('userList', {
extend: 'Ext.data.Model',
fields: [{ name: 'id', mapping: 'id' },
{ name: 'name', mapping: 'name' },
{ name: 'firstName' ,mapping:'personalInfo.firstName'},
{ name: 'lastName' ,mapping:'personalInfo.lastName'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'userList',
autoLoad: true,
proxy: {
type: 'ajax',
url : url+'/lochweb/loch/users/getUser',
reader: {
type: 'json',
root: 'Users'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
renderTo: "searchUsers",
plugins: [rowEditing],
width: 900,
height: 300,
frame: true,
title: 'Users',
store: store,
iconCls: 'icon-user',
columns: [{
text: 'ID',
width: 40,
sortable: true,
dataIndex: 'id'
},
{
text: 'Name',
flex: 1,
sortable: true,
dataIndex: 'name',
field: {
xtype: 'textfield'
}
},
{
text: 'FirstName',
flex: 1,
sortable: true,
dataIndex: 'firstName',
field: {
xtype: 'textfield'
}
},
{
text: 'LastName',
flex: 1,
sortable: true,
dataIndex: 'lastName',
field: {
xtype: 'textfield'
}
}]
});
}
});
}
}
}
]
});
var win = new Ext.Window({
layout:'fit',
closable: false,
resizable: true,
plain: true,
border: false,
items: [searchUsers]
});
win.show();
});
How to Fit the grid inside the Search User window
Add an icon in the grid,so that by clicking on that icon the values from the
grid must be populated to entry form for update.
Here with your code, I've found something:
Use renderTo: "searchUsers" for both FormPanel and the Grid: You add the FormPanel to the window, so this config should not exist (Please refer to renderTo document). So remove them.
Use frame: true for both FormPanel and the Grid: There you have the window as container, so the Form and Grid have been framed inside. So remove them.
You dynamically add the Grid on searching: I recommend you create the result Grid as a separate component (not inside success's result) and specify both Form and Grid as items' components of window. You still can config the Grid with hidden. When Ajax is successful, you can fill the Grid with data returned and show it.
"add an icon in the grid": You can specify a new column in columns of the Grid and use renderer config of grid panel to show the button. For example:
renderer: function(v) {
return "<input type='button'.../>";
}
Finally, you can catch the itemclick event of the grid to know if the column of the clicked cell is the cell which contains the button, the entry will be populated to somewhere you want. Don't forget to specify the grid's Selection model as cellmodel

How to refresh DataView'data rendering in Sencha touch 2

I add a dataview in an carousel form and it shows up as a list. Then I delete several items of the dataview, but the list in carousel view doesn't change. What should I do to refresh the view?
I have tried several methods such as 'remove()', 'removeAll()', 'destroy()', 'refresh()', but it has no effect.
Model:
Ext.define('Chihiro.model.User', {
extend: 'Ext.data.Model',
config: {
fields: [ 'id', 'name', 'nickname', 'signiture', 'gender', 'birthday', 'school', 'job', 'portrait', 'interests', 'dis'],
proxy: {
type: 'localstorage',
id: 'friends'
},
autoLoad: true
}
});
dataview:
Ext.define('Chihiro.view.userlist.List', {
extend: 'Ext.DataView',
xtype: 'userlist',
store: {
model: 'Chihiro.model.User'
},
config: {
ui:'loans',
useComponents: true,
defaultType: 'listitem',
emptyText: '<div style="margin-top: 20px; text-align: center">没有找到任何人哦</div>',
deselectOnContainerClick: false
}
});
Panel:
Ext.define('Chihiro.view.contact.List', {
extend: 'Ext.Carousel',
xtype: 'contactpanel',
id: 'contactnavigationview',
layout: 'vbox',
config: {
fullscreen: true,
//autoDestroy: false,
scrollable: true,
//defaultBackButtonText: '返回',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: '好友'
}
]
}
});
You will need to re-load the store in order to refresh the dataview.
Methods like remove(), removeAll(), destroy() and refresh() will definitely won't have any effect.
When you change the items inside a store, you need to call load() method on your datastore. This will essentially refresh your dataview.
yourStoreForDataView.load();
Useful Post : Sencha-touch : refresh list : store

Treegrid how use local json(memory proxy)

My code:
Ext.onReady(function() {
Ext.define('Unit', {
extend: 'Ext.data.Model',
fields: [
{name: 'task',type: 'string'}
]
});
var store = Ext.create('Ext.data.TreeStore', {
autoLoad: true,
model: 'Unit',
data:result,
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
});
var tree = Ext.create('Ext.tree.Panel', {
id:"treepanel",
title: 'Core Team Projects',
width: 500,
height: 300,
renderTo: Ext.getBody(),
collapsible: true,
useArrows: true,
rootVisible: false,
store: store,
multiSelect: true,
singleExpand: true,
//the 'columns' property is now 'headers'
columns: [{
xtype: 'treecolumn', //this is so we know which column will show the tree
text: 'Task',
flex: 2,
sortable: true,
dataIndex: 'task'
},{
//we must use the templateheader component so we can use a custom tpl
xtype: 'treecolumn',
text: 'Duration',
flex: 1,
sortable: true,
dataIndex: 'duration',
align: 'center'
}]
});
});
JSON is: http://dev.sencha.com/deploy/ext-4.0.0/examples/tree/treegrid.json
The tree don't display my result, how to do it? I am a new ExtJs4.
Sorry I don't want to use AJAX for get result.
If json file is not on the same domain you need to use type: 'jsonp'
Refer the below link. You can get clear idea about client proxy in Ext JS.
http://www.pointerunits.com/2013/01/ext-js4-client-proxies.html
If your data is present in your server, you have to use any one server proxies for loading data from server.
Ajax proxy - For loading data by using AJAX call
JSONP proxy - For loading data from different server (for avoiding CORS Problem)
Rest Proxy - For loading data by calling rest services.
The data attribute has to be declared inside the proxy:
Before (Fiddle):
var store = Ext.create('Ext.data.TreeStore', {
model: 'Unit',
data: result,
proxy: {
type: 'memory',
reader: {
type: 'json'
}
}
});
After: (Fiddle):
var store = Ext.create('Ext.data.TreeStore', {
model: 'Unit',
proxy: {
type: 'memory',
data: result,
reader: {
type: 'json'
}
}
});
Voilá!

Sencha Touch Splitview NestedList and getDetailCard

I've seen quite a few examples of a sencha touch app with a nestedList that creates a view within the getDetailCard method and all of that works fine. BUT I have not seen this implemented in an MVC setup. More specifically, a splitview MVC app where the nestedList is docked to the left and the detail pane to the right.
I can use setActiveItem to display a fullscreen detail view with the relevant data all day but when doing so, the left docked nestedlist is removed. How do I keep the split-view setup and update the detailView?
Controller: Products.js
/**
* #class Products
* #extends Ext.Controller
*/
Ext.regController('Products', {
// index action
index: function(){
if ( ! this.indexView){
this.indexView = this.render({
xtype: 'ProductIndex',
});
}
this.application.viewport.setActiveItem(this.indexView);
},
detail: function(options){
var record = options.params[0].attributes.record.data;
console.log(record);
if ( ! this.detailView){
this.detailView = this.render({
xtype: 'ProductDetail',
//data: record
});
//var detailsView = this.indexView.query('#detailsView')[0];
this.detailView.update(record);
}
//this.application.viewport.setActiveItem(this.detailView, options.animation);
}
});
Model: Product.js
Ext.regModel('Product', {
fields: [
{name: "id", type: "int"},
{name: "pid", type: "int"},
{name: "type", type: "string"},
{name: "status", type: "string"},
{name: "title", type: "string"},
{name: "content", type: "auto"},
{name: "date", type: "string"},
{name: "modified", type: "string"}
]
});
MVCApp.ProductStore = new Ext.data.TreeStore({
model: 'Product',
autoLoad: true,
storeId: 'ProductStore',
proxy: {
type: 'ajax',
id: 'ProductStore',
url: 'data/nestedProducts.json',
reader: {
type: 'tree',
root: 'items'
}
}
});
View: ProductIndexView.js
KCI.views.ProductIndex = Ext.extend(Ext.Panel, {
layout: 'hbox',
dockedItems: [
{
dock: 'left',
xtype: 'nestedlist',
width: '320',
height: '100%',
store: 'ProductStore',
displayField: 'title',
useToolbar: Ext.is.Phone ? false : true,
getDetailCard : function(record, parentRecord){
Ext.dispatch({
controller : 'Products',
action : 'detail',
historyUrl : 'Products/index',
params : [record, parentRecord]
});
}
}
],
items: [
{
xtype: 'ProductDetail',
itemId: 'detailView',
width: "704",
height: '100%'
}
]
});
Ext.reg('ProductIndex', KCI.views.ProductIndex);
View: ProductDetailView.js
KCI.views.ProductDetail = Ext.extend(Ext.Panel, {
scroll: 'vertical',
styleHtmlContent: true,
background: '#464646',
html: '<h1>Product Detail</h1>',
tpl: ['{title}<br />{id}<br />{pid}<br />{leaf}<br />{date}<br />{modified}<br />{type}<br />{status}<div>{content}</div>']
});
Ext.reg('ProductDetail', KCI.views.ProductDetail);
Try creating a sub viewport which will contain detail pane. Then you can just setActiveItem for that viewport instead of the application viewport.
I have the answer, this will slide the detail card out, update it and slide it back in.
In my Products controller, I needed to alter my detail view:
detail: function(options)
{
this.currentItem = options.params[0].attributes.record.data;
var rightPanel = this.application.viewport.query('#rightPanel')[0];
if ( ! this.detailView)
{
this.detailView = this.indexView.query('#detailView')[0];
this.dummyView = this.indexView.query('#dummyView')[0];
this.dummyView.on('activate', function()
{
this.detailView.update(this.currentItem);
rightPanel.setActiveItem(this.detailView, {type: 'slide'});
}, this);
}
rightPanel.setActiveItem(this.dummyView, {type: 'slide', reverse: true});
}
Then in my Product Index view, create a sub panel and a dummyview:
var rightPanel = new Ext.Panel({
layout: 'card',
xtype: 'rightPanel',
itemId: 'rightPanel',
items: [
{
xtype: 'ProductDetail',
itemId: 'detailView',
width: "704",
height: '100%',
html: 'right panel'
},
{
itemId: 'dummyView'
}
]
});
EDIT: Wanted to reference my source, and highly talented ST dev: CAM

Loading combobox with json data in ExtJS 4

Im just trying to simply load some json data into my combobox using a basic data store. Here is my json data:
{"services": [{"id": 1, "name": "dropbox"}, {"id": 2, "name": "facebook"}, {"id": 3, "name": "twitter"}]}
Here is my extjs 4 code:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
'id', 'name'
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'json',
url: '/account/service/list',
reader: {
root: 'services',
totalProperty: 'totalCount'
}
}
});
store.load();
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
store:store
}]
}]
}]
});
});
Everything is being done on localhost so no cross domain stuff. I've been going through documentation but just can't figure out what im doing wrong.
As always any tips is much appreciated!
Update:
I edited some changes to the datastore and am getting a bit farther:
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services',
type: 'json'
}
}
});
store.load();
Now when the page loads or I attempt to click the combobox the url it is addressing is:
GET /account/service/list?_dc=1318340688155&page=1&start=0&limit=25
From my reading this looks like jsonp but I dont know where the page,start, and limit params come from?
Update2:
Thanks to the help from Molecule Man I was able to sort this out:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
autoLoad: true,
proxy: {
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache:false,
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services'
}
}
});
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
queryMode:'local',
emptyText: 'Select Service',
store:store,
displayField: 'name',
valueField: 'id'
}]
}]
}]
});
});
Hope this helps anyone else :)
Your combobox' config doesn't contain displayField (defaults to 'text') and valueField(defaults to displayField's value) which are required:
items: [{
xtype:'combo',
displayField: 'name',
valueField: 'id',
store:store
}]