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?
Related
I'm creating an overview of features and their feature dependencies (not user stories).
I'm fetching the wsapi store filtered on release in step 1 and in step 2 I'm fetching the predecessor and successor collections in order to display their values.
I would like to use this wsapi store directly in a grid, but when performing an onScopeChange (release filtered app) the rendering of the grid happens before my loading of predecessor + successor collections. Thus, I'm trying to store the data in a custom.store to use in the grid - so far so good.
My issue is that I need to do all (most) formatting in the grid on my own. I'm setting the custom store model to PortfolioItem/Feature and would expect this to be used on the grid, but it just doesn't. Is this possible? If so, what am I doing wrong?
Custom store
_getViewStore: function () {
var me = this;
/*
Extract data from featureStore
*/
var records = me.myFeatureStore.getRecords();
/*
Create new, update, store for adding into grid
*/
if (!me.myViewStore) {
me.myViewStore = Ext.create('Rally.data.custom.Store', {
model: 'PortfolioItem/Feature',
data: records,
});
} else {
me.myViewStore.removeAll();
me.myViewStore.add(records);
}
},
Grid
_createGrid: function () {
var me = this;
me.myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallygrid',
store: me.myViewStore,
columnCfgs: [{
xtype: 'gridcolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Predecessors',
dataIndex: 'Predecessors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputPre = '';
var records = record.predecessorStore.getRecords();
_.each(records, function (feature) {
mFieldOutputPre += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputPre += ' - ' + feature.get('Name') + '<br>';
}); //_.each
return mFieldOutputPre;
},
},
{
text: 'FormattedID',
dataIndex: 'FormattedID',
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
text: 'Release',
dataIndex: 'Release',
flex: 1
},
{
text: 'State',
dataIndex: 'State',
flex: 1
},
{ // Column 'Successors'
xtype: 'templatecolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Successors',
dataIndex: 'Successors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputSuc = '';
var records = record.successorStore.getRecords();
_.each(records, function (feature) {
//console.log('feature = ', feature);
mFieldOutputSuc += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputSuc += ' - ' + feature.get('Name') + '<br>';
});
return mFieldOutputSuc;
},
}
]
}],
renderTo: Ext.getBody()
});
me.add(me.myGrid);
}
The Release + State fields does not display data correct when using my custom store, but if I use my wsapi (feature) store that are formatted correctly.
Thank you in advance
I'd probably load all the stores first and then add the rallygrid configured with your already loaded feature store. Then you don't have to worry about the timing issues. I'm guessing you already found this example in the docs for loading the child collections?
https://help.rallydev.com/apps/2.1/doc/#!/guide/collections_in_v2-section-collection-fetching
This example is also pretty helpful, as it shows how to load hierarchical data much like you're doing, and uses promises to help manage all of that and then do something when everything has finished loading:
https://help.rallydev.com/apps/2.1/doc/#!/guide/promises-section-retrieving-hierarchical-data
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.
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.
I have problem configuring RowExpander for my grid. When the grid renders the expander is already opened for each row and with nothing inside. When i click on its icon the following error is generated: nextBd is null. I found very similar problem here http://www.sencha.com/forum/showthread.php?185837-Grid-Panel-PlugIn-Rowexpander-nextBd-is-null but the solution does not work for me and still dont get it why plugin config cannot be passed in initComponent method:
Here is my grid code:
Ext.define('GSIP.view.plans.PlanReqList' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.gsip_devplan_list',
id: 'gsip_plan_list',
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'Nazwa:{name}'
]
}],
//title:i18n.getMsg('gsip.view.PlanReqList.title'),
layout: 'fit',
initComponent: function() {
this.store = 'DevPlan';
// this.plugins = [{
// ptype: 'rowexpander',
// rowBodyTpl : [
// {name}
// ]
// }];
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.tbar = [{
xtype:'commandbutton',
id: 'newReq',
iconCls:'icon-application_add',
text: i18n.getMsg('gsip.view.plans.PlanReqList.addReq'),
command: 'newReq',
}];
this.viewConfig = {
forceFit:true,
getRowClass: function(record, index) {
var c = record.get('elapsedPercent');
if (c >= 0) {
return 'elapsed-normal';
}
}
}
this.columns = [
{header: "Id", dataIndex: "id", width:50, sortable: true, filter:{type:'numeric'}},
{header: i18n.getMsg('gsip.view.plans.PlanReqList.column.name'), dataIndex: "name", flex:1, sortable: true, filter:{type:'string'} },
}
];
this.callParent(arguments);
},
The rowexpander plugin makes use of a feature called rowbody.
In your initComponent() you override this.features (which already includes rowbody) with this line:
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
Thus the rowbody feature is not included; thus the .x-grid-rowbody-tr class is not injected; thus rowexpander can't find such class for nextBd and returns null.
You should try:
var iNewFeatures = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.features = iNewFeatures.concat( this.features );
Lastly, plugins cannot be initiated in InitComponent(), you can either declare them as configs, or within the constructor. See this thread for more info.
I am using a grid panel in which I need to make a column as a link(It should look like link-with no action). I am using listener in the gridpanel and on click of a cell its working fine. Only thing is 1st column should look like a link. But how to put href="#" I am not sure. This is my code:
var addressDetailsStore = Ext.create('Ext.data.Store', {
id:'addressDetailsStore',
autoLoad: true,
fields:
[
'addressType',
'street1',
'street2',
'province',
'city',
'country'
],
proxy: {
type: 'ajax',
url: 'resources/json/addressDetails.json', // url that will load data with respect to start and limit params
reader: {
type: 'json',
root: 'items',
}
}
});
Ext.define('iOMS.view.common.addressView', {
extend: 'Ext.grid.Panel',
alias: 'widget.AddressViewPanel',
layout: 'fit',
collapsible: true,
title:'Address',
store: addressDetailsStore,
listeners:{
cellclick:function (iView, iCellEl, iColIdx, iRecord, iRowEl, iRowIdx, iEvent){
// Getting the event and I am doing logic here..
}
I just want 'addressType' columns appear like a link and I dont know where to put href...
Thanks for your responses.
-Praveen
You could also use a template column:
columns: [
{ text: 'External Link', xtype: 'templatecolumn', tpl: '{title}'}
]
You can specify the columns you want, and for the column with just a link, add a renderer. This example might help you.
var template = new Ext.XTemplate(
' ').compile();
columns:[
{
header: "",
renderer: function () {
return template.applyTemplate();
}
},
You can use renderer function like as follow
columns: [
{
header: 'number',
dataIndex: 'number',
flex: 1,
renderer: function(number) {
return Ext.String.format('{0}', number);
}
},