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.
Related
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.
Ext.define('App.view.Main', {
extend: 'Ext.Container',
xtype: 'mainview',
requires: [
'App.view.Main1',
'App.view.Menu2',
'App.view.My1',
'App.view.My2',
'App.view.Form'
],
config: {
items: [
{
xtype: 'file1'
},
{
xtype: 'file2',
hidden: true
},
{
xtype: 'file3',
hidden: true
},
{
xtype: 'file4',
hidden: true
},
{
xtype: 'file5',
hidden: true
},
{
xtype: 'file6',
hidden: true
},
{
xtype: 'file7',
hidden: true
}
]
}
});
In the above code Main file is mainview and I am doing hiding all those xtypes and showing what i want. But it is very difficult to maintain project for hiding and showing.
In my project i have a view files of morethan 30.
Is there any way to add files whatever i want without this hide and show?
If your views are relatively similar, you should create them programmatically. So follow these steps:
Create your main view with no items, give it an id, says "main-view".
Place this function somewhere you feel suitable:
addItemsToMainView: function(numberOfFiles){
var mainView = Ext.getCmp('main-view');
for (var i=1; i<= numberOfFiles; i++){
var xtypeName = "file" + i.toString();
mainView.add({xtype: xtypeName, id: i.toString()});
}
// if you want to show and hide all of them
for (var i=1; i<= numberOfFiles; i++){
Ext.getCmp(i.toString()).hide();
// or Ext.getCmp(i.toString()).show();
}
}
The above code snippet is just an example but I believe you can get an idea of how it works.
Hope this helps.
My application (mvc) is designed as such with 3 tabs in my view
Ext.define('App.view.cube.MainView', {
extend: 'Ext.panel.Panel',
....
layout: 'card',
...
dockedItems: [{
xtype: 'panel',
items: [{
// a drop down containing 2 choices
}]
}],
items: [{
xtype: 'tabpanel',
itemId: 'mmtabs',
activeTab: 1,
items: [{
title: 'Served',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'Served :',
itemId: '1'
}, {
title: 'UnServed',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'UnServed :',
itemId: '0'
}, {
title: 'Total',
xtype: 'treepanel', // my own xtype extending this xtype
id: 'Total :',
itemId: '2'
}]
}]
});
Basically a drop down with two choices should allow the user to view the required columns within the grid (treepanel). The very first time the app is loaded and the user changes to a different choice in the dropdown the columns do not hide as they should. But if he were to navigate to another tab and then do the same thing everything works as it is supposed to. I cannot figure out the problem.
In the code above i am reusing
xtype : 'treepanel', // my own xtype extending this xtype
across the three tabs by having different itemIds ( i hope this is fine ).
In my controller i have a function to toggle to the view (hide/show specific columns)
initialview (iterate over all columns in all tabs and set the appropriate view)
changeview invoked on the combobox within my view.
toggleView: function (cubemwwar, viewId) {
if ("2" == viewId) {
cubemwwar.columns[1].setVisible(false);
cubemwwar.columns[2].setVisible(false);
cubemwwar.columns[3].setVisible(false);
cubemwwar.columns[4].setVisible(true);
cubemwwar.columns[5].setVisible(true);
cubemwwar.columns[6].setVisible(true);
}
if ("1" == viewId) {
cubemwwar.columns[1].setVisible(true);
cubemwwar.columns[2].setVisible(true);
cubemwwar.columns[3].setVisible(true);
cubemwwar.columns[4].setVisible(false);
cubemwwar.columns[5].setVisible(false);
cubemwwar.columns[6].setVisible(false);
}
}, // on controller's onlaunch
initialView: function () {
var numTabs = this.getCubeMainView().query('#mmtabs')[0].items.length;
for (var i = 0; i < numTabs; i++) {
var tab = this.getCubeMainView().query('#mmtabs')[0].items.items[i];
this.toggleView(tab, 1);
}
},
// change views based on user selection
// from the combobox's select event
changeView: function (combo, rec, idx) {
// first time somehow the columns do not hide
// hide/show appropriate columns
// rec[0].data.id .. .possible values 1 and 2 only.
this.toggleView(this.getCubeMainView().query('#mmtabs')[0].getActiveTab(), rec[0].data.id);
},
On startup I iterated over all the tabs set them to active then set the first one back to active. That had solved this problem.
for(var i=0;i<numTabs ; i++)
{
var tab = tabPanel.items.items[i];
this.toggleView(tab,1);
tabPanel.setActiveTab(i);
}
tabPanel.setActiveTab(0);
this.startingup = false;
I'm fairly new to ExtJS, but have been able to get a GridPanel working with an associated paging toolbar. Everything works fine, until I close the popped up window and open another one. On the subsequent window loads, I get a "me.dom is undefined" error. If I remove the paging toolbar, everything works fine. I'm using version 4.0.7.
Thanks in advance.
Store definition:
Ext.define('VIMS.store.TOs',{
extend:'Ext.data.Store',
model:'VIMS.model.TO',
requires: 'VIMS.model.TO',
sorter:{property:'StartDate', direction:'DESC'},
buffered: true,
pageSize: 10,
listeners:{
beforeload: function(store,options) {
if(options.params && options.params.id){
store.getProxy().extraParams.id = options.params.id;
}
},
},
});
GridPanel definition:
Ext.define('VIMS.view.TaskOrderList' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.taskorderlist',
title : 'Task Orders',
store: 'TOs',
requires:'Ext.toolbar.Paging',
height:'100%',
columnLines:true,
/* removed this code ---------------------------------------
dockedItems :[{
xtype: 'pagingtoolbar',
store: 'TOs', // same store GridPanel is using
pageSize:10,
dock: 'bottom',
displayInfo: false,}],
-------------------------------------------- */
initComponent: function() {
this.columns = [
{header: 'Description', dataIndex: 'Description', flex: 1},
. . .
{header: 'Id', dataIndex: 'TaskOrderId', hidden:true},
];
// added from here ---------------------------------
var PagingBar = new Ext.PagingToolbar({
pageSize: 10,
store: 'TOs',
displayInfo: true,
});
this.bbar = PagingBar;
// to here ---------------------------------------
this.callParent(arguments);
}
});
To open the window, from my controller I use the following:
var view = Ext.widget('contractedit');
view.modal = true;
view.down('form').loadRecord(record);
The close is handled via the following:
closeMe: function(button) {
var win = button.up('window');
win.close();
},
you have an extra trailing comma that maybe getting in the way:
displayInfo: false,
also how r u managing the window?
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
}
]
}
});