ExtJS Modal Panel is not displaying content - extjs

I have a modal panel which will appear when a link is clicked with a listener config.
The link is placed inside a grid. The problem is when the link is clicked the modal is appearing with no data. Please help.
listeners : {
click : function() {
Ext.create('Ext.data.Store', {
storeId:'myStore',
fields:['qname'],
data:{'items':[
{ 'qname': 'Lisa'},
{ 'qname': 'Bart'},
{ 'qname': 'Homer'},
{ 'qname': 'Marge'}
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Ext.create('Ext.window.Window', {
title : 'Add Survey',
titleAlign : 'center',
id : 'surveyWindow',
height : 400,
width : 300,
//modal : true,
layout : 'fit',
closeAction:'close',
store:Ext.data.StoreManager.lookup('myStore'),
items : {
xtype : 'grid',
id :'addSurveyGrid',
border : false,
columns : [{
xtype : 'rownumberer'
},{
header : 'Survey Name',
sortable : false,
dataIndex : 'qname',
flex : 1
}]
}
}).show();
}
}

You are passing the store to the Window, not the grid. Fixed that for you.

Related

ExtJS 4 Render Errors On Viewport in a New Tab

I am developing an extjs and spring application. I got stuck in rendering view in new tab in center region of viewport. I have not able to create an instance of the view using ref in controller. please help and let me know where i am doing wrong..
Controller js
Ext.define('Book.controller.NewBook', {
extend : 'Ext.app.Controller',
views : ['book.NewBook'],
refs : [ {
ref : 'bookViewport',
selector : 'viewport' //whatever the xtype is of your viewport class
}, { ref : 'newBookForm',
selector : '#newBook panel',
autoCreate: true//whatever the xtype is of your viewport class
} ],
init : function() {
// add the components and events we listen to
this.control({
'viewport > panel' : {
render : this.onPanelRendered
},
'viewport' : {
afterrender : this.onNewBookLinkClick
}
});
},
onNewBookLinkClick : function() {
var view = this.getBookViewport();
var newBook = this.getNewBookForm();
alert(newBook.id);
Ext.get('tab1').on('click', function() {
var tabExists = false;
var p1=Ext.getCmp('panel').getLayout();
var p2=Ext.getCmp('panel');
var items = p2.items;
for (var i = 0; i < items.length; i++) {
alert(items[i].id);
if (items[i].id === 'NewBook') {
this.getViewport().panel.setActiveTab(i);
tabExists = true;
this.getViewport().panel.setActiveTab(i);
}
}
if (!tabExists) {
p2.insert(1, newBook);
p2.setActiveTab(0);
}
});
},
onPanelRendered : function() {
}
});
View
Ext.define('Book.view.book.NewBook', {
extend : 'Ext.form.Panel',
alias : 'widget.newBook',
config: {},
constructor: function (config) {
this.initConfig(config);
return this.callParent(arguments);
},
initComponent: function () {
Ext.apply(this, {
layout : 'vbox',
contentEl : 'center2',
title : 'New Book',
store : 'Books',
id : 'NewBook',
defaults : {
bodyPadding : 10
},
items : [ {
xtype : 'panel',
width : 900,
collapsible : true,
title : 'Book Details',
defaults : {
width : 230,
cls : 'form-field'
},
defaultType : 'textfield',
items : [ {
fieldLabel : 'Book Id',
name : 'bookId',
value : '',
// validator : function(event) {
// if (!(/[0-9]/.test(this.getValue()))) {
// return "This Field should be in Numbers only";
// }
// return true;
// }
} ]
}]
});
this.callParent(arguments);
}
});
ViewPort
Ext.define('Book.view.Viewport', {
extend: 'Ext.container.Viewport',
alias : 'widget.viewport',
requires: [
'Book.view.book.catCombo',
'Book.view.book.subCatCombo',
'Book.view.book.NewBook',
'Book.view.book.BookGrid',
'Book.view.book.SearchBook',
'Book.view.book.ModifyBook'
],
id : 'borderViewPort',
layout : 'border',
items : [
Ext.create('Ext.Component', {
region : 'north',
height : 0
}),
{
region : 'west',
stateId : 'navigation-panel',
id : 'west-panel',
title : 'Navigation Menu',
split : true,
width : 200,
minWidth : 175,
maxWidth : 400,
collapsible : true,
animCollapse : true,
margins : '0 0 0 5',
layout : 'accordion',
items : [ {
contentEl : 'west',
title : '<b>Books</b>',
html : '<div id="west" class="x-hide-display"><ul> <li>New Book</li> <li>Search Book</li> </ul></div>',
iconCls : 'nav'
}, {
title : 'Purchase Order',
iconCls : 'settings'
}, {
title : 'Total Sales',
iconCls : 'info'
} ]
},
panel = Ext.create('Ext.tab.Panel', {
region : 'center',
id : 'panel',
deferredRender : false,
activeTab : 0
}) ]
});
app.js
Ext.application({
name: 'Book',
models: ['Book'],
stores: ['Books','BookCategories','BookSubCategories'],
controllers: ['NewBook', 'SearchBook'],
autoCreateViewport: true,
launch: function() {
Ext.create('Book.view.Viewport');
}
}
);
Your center region config is incorrect since you have defined it as panel variable, but not actually made it a child of the viewport items.
Instead, use this approach:
new Ext.Viewport({
layout: 'border',
items: [{
region: 'north',
html: '<h1 class="x-panel-header">Page Title</h1>',
autoHeight: true,
border: false,
margins: '0 0 5 0'
},{
region: 'west',
stateId : 'navigation-panel',
id : 'west-panel',
title : 'Navigation Menu',
split : true,
width : 200,
minWidth : 175,
maxWidth : 400,
collapsible : true,
animCollapse : true,
margins : '0 0 0 5',
layout : 'accordion',
items : [ {
contentEl : 'west',
title : '<b>Books</b>',
html : '<div id="west" class="x-hide-display"><ul> <li>New Book</li> <li>Search Book</li> </ul></div>',
iconCls : 'nav'
}, {
title : 'Purchase Order',
iconCls : 'settings'
}, {
title : 'Total Sales',
iconCls : 'info'
}]
// the west region might typically utilize a TreePanel or a Panel with Accordion layout
},{
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title
items: [{
title: 'Tab 1'
},{
title: 'Tab 2'
}]
}]
});
This displays correctly, you should see how you can adapt this to your view definition.
The problem is solved by removing contentEl : 'center2', tag from my NewBook view.
contentEl uses the target element as its body content (the panel could still be rendered to any other element)

In ExtJS 4.2.2, why does loadRecord() load data, but form does not reflect new data?

Using ExtJS 4.2.2
I have a grid, and when I right click the grid and select Modify from my context menu, a Window with a form is created, and on render, I get the grid selected row record and use the form loadRecord to load the record.
Firebug shows the record was loaded into the form fields, but in the rendered form the fields are enpty.
Any ideas?
Here is some code that illustrates the issue.
If you put a breakpoint at the line with var test = 'test'; you will see the data is loaded into the form's textfields, but then continue past the break point and see the textfields do not reflect the data.
Ext.onReady(function() {
Ext.define('com.myCompany.MyGridModel', {
extend : 'Ext.data.Model',
fields : [{
name : 'name',
type : 'string'
}, {
name : 'address',
type : 'string'
}, {
name : 'type',
type : 'string'
}]
});
var store = Ext.create('Ext.data.Store', {
model: 'com.myCompany.MyGridModel',
proxy: {
type: 'ajax',
url: 'centers.json',
reader: {
type: 'json',
root: 'centers'
}
}
});
store.load();
var grid = Ext.create('Ext.grid.Panel', {
layout: 'fit',
store: store,
columns: [{
text: 'Name',
dataIndex: 'name',
name: 'name'
}, {
text: 'IP Address',
dataIndex: 'address',
name: 'address'
}, {
text: 'Type',
dataIndex: 'type',
name: 'type'
}],
renderTo: Ext.getBody(),
listeners: {
itemcontextmenu : function(view, record, item, index, event){
var selectedItem = record;
event.preventDefault();
new Ext.menu.Menu({
items: [{
text : 'Modify',
handler : function(widget, event) {
Ext.create('Ext.window.Window', {
height : 380,
width : 540,
resizable : false,
closable: true,
modal: true,
layout :{
type : 'fit'
},
items : [{
xtype : 'form',
frame : true,
height : 250,
itemId : 'centerContentForm',
width : 400,
bodyPadding : 10,
items : [{
xtype : 'textfield',
itemId : 'txtName',
height : 30,
width : 401,
fieldLabel : 'Name',
name: 'name',
allowBlank : false
},{
xtype : 'textfield',
itemId : 'txtIPAddress',
height : 30,
width : 401,
fieldLabel : 'Address',
name: 'address',
allowBlank : false,
},{
xtype : 'textfield',
itemId : 'txtType',
height : 30,
width : 401,
fieldLabel : 'Type',
name: 'type',
allowBlank : false
}]
}],
listeners: {
render: function(win) {
win.down('form').loadRecord(selectedItem);
var test = 'test';
}
}
}).show();
} // end of right-click handler
}]
}).showAt(event.getXY());
}
}
});
grid.getView().refresh();
});
Instead of render event handler you should use afterrender event handler.
So your window listeners config should be:
listeners: {
afterrender: function(win) {
win.down('form').loadRecord(selectedItem);
}
}

Custom function call after Extjs 4 grid sort

I have an Extjs 4 grid with sort capability. i want to call a custum function after each time user presses sort button.
In my custom function i want to navigate to the first page of my grid (my grid uses pagination and it takes advantage of server-side sort) i think i must use store.loadPage(1) in my custom function (correct me if I'm wrong)
where should i put my custom function?
This is my Ext.OnReady() function:
Ext.onReady(function() {
Ext.tip.QuickTipManager.init();
var url = {
local: 'grid-filter.json', // static data file
remote: 'grid-filter.php'
};
var paging = true;
var encode = false;
var local = false;
Ext.define('UserDirectoryDataModel', {
extend : 'Ext.data.Model',
fields : [ 'uname', 'fname', 'lname', 'postcode', 'mail', {
name : 'pass'
}, 'hasAccess', 'isActive', 'lastVisit' , 'deleteUser'],
idProperty : 'uname'
});
var itemsPerPage = 20;
var store = Ext.create('Ext.data.Store', {
pageSize : itemsPerPage,
autoLoad: false,
local: false,
autoDestroy: true,
model : 'UserDirectoryDataModel',
autoSync : true,
sortOnLoad : true,
remoteSort:true,
sorters : {
property : 'uname',
direction : 'ASC'
},
listeners: {
beforeload: function(){
store.loadPage(1);
}
},
proxy : {
type : 'ajax',
url: (local ? url.local : url.remote),
api : {
read : 'read.php',
update : 'update.php'
},
reader : {
type : 'json',
root : 'users',
successProperty : 'success',
totalProperty : 'totalCount'
},
writer : {
type : 'json',
writeAllFields : true,
encode : false,
root : 'users'
},
afterRequest : function(request, success) {
if (request.action == 'update') {
if (success) {
Ext.MessageBox.alert('alert',
'data updated!');
}
}
}
}
});
store.load({
params:{
start:0,
limit: itemsPerPage
}
});
var filters = {
ftype: 'filters',
encode: encode, // json encode the filter query
local: local, // defaults to false (remote filtering)
filters: [
{
}
]
};
var createColumns = function (finish, start) {
var columns = [ {
text : "username",
dataIndex : 'uname',
width : 150,
filterable: true,
align : 'right'
}, {
text : "name",
dataIndex : 'fname',
width : 150,
align : 'right',
hidden : false,
sortable : true,
filterable: true,
editor : {
xtype : 'textfield',
allowBlank : false
}
}, {
text : "last name",
dataIndex : 'lname',
width : 150,
align : 'right',
sortable : true,
filterable: true,
editor : {
xtype : 'textfield',
allowBlank : false
}
}, {
text : "PostalCode",
dataIndex : 'postcode',
width : 110,
align : 'right',
sortable : true,
filterable: true,
editor : {
xtype : 'textfield',
allowBlank : false
}
}, {
text : "email",
dataIndex : 'mail',
width : 200,
align : 'right',
sortable : true,
filterable: true,
editor : {
xtype : 'textfield',
allowBlank : false
}
}, {
text : "password",
width : 150,
align : 'right',
sortable : false,
filterable: true,
hidden : true,
dataIndex : 'pass',
editor : {
xtype : 'textfield',
inputType : 'password',
allowBlank : true
}
}, {
text : "access to system",
dataIndex : 'hasAccess',
renderer:function(value){
if(value[0]=="1"){
return "has";
}else{
return "doens't have";
}
},
width : 100,
align : 'center',
sortable : false,
filterable: false
}, {
text : "active",
dataIndex : 'isActive',
renderer:function(value){
if(value==null)
return;
if(value[0]=="1"){
return "no";
}else if(value[0]=="0"){
return "yes";
}else if(value[0]=="2"){
return "Not in portal!";
}
},
width : 100,
align : 'center',
sortable : false,
filterable: false
}, {
text : "last visit",
dataIndex : 'lastVisit',
width : 120,
hidden : true,
align : 'right',
sortable : true,
filterable: true
}, {
text : " ",
dataIndex : 'uname',
renderer:function(value){
return "delete";
},
width : 120,
hidden : true,
align : 'right'
} ];
return columns.slice(start || 0, finish);
};
var pluginExpanded = true;
var grid = Ext.create('Ext.grid.Panel', {
border: false,
width : 1200,
height : 620,
title : '',
store: store,
disableSelection : false,
seltype : 'rowmodel',
loadMask : true,
viewConfig : {
id : 'gv',
trackOver : false,
stripeRows : false,
plugins : [ {
ptype : 'preview',
bodyField : 'excerpt',
expanded : true,
pluginId : 'preview'
} ]
},
columns: createColumns(),
features: [filters],
dockedItems: [Ext.create('Ext.toolbar.Paging', {
dock: 'bottom',
store: store
})],
plugins : [ Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit : 2
}) ],
renderTo : 'userdatagrid'
});
grid.child('pagingtoolbar').add([
{
text: 'show filters',
handler: function () {
var data = Ext.encode(grid.filters.getFilterData());
Ext.Msg.alert('show filters',data);
}
},{
text: 'delete filters',
handler: function () {
grid.filters.clearFilters();
}
}
]);
store.loadPage(1);
});
Or you could use this:
grid.on('sortchange', function() {
grid.getStore().loadPage(1);
});
Forget everything I wrote:
Server Side sorting in an ExtJS GridPanel
You should put your custom function in the grid event: sortchange.
I just re-read your question - I thought you have infinite paging.
If your sort is done server side, then yes, you need to call loadPage(1).
You also need to send the sort parameters.
listeners: {
sortchange: function(){
var grid = Ext.ComponentQuery.query('my-grid-alias')[0];
grid.getStore().loadPage(1);
}
}
I hope this helps.
I just put a loadPage(1) in the sortchange event, but it made twice server request(grid made the first one with sort parameters automatically), how could it be only once?
I figure out one solution, I set "remoteSort:false" in store and
"sortchange: {fn:function(){
var time = (new Date()).getTime()/1000;
// after {remoteSort:false} is set, sortchange event will be fired twice when column header is clicked, so I had to set a parameter for time record
if('undefined' == typeof(this.last_sort_time) || this.last_sort_time+1 < time){
this.getStore().loadPage(1);
this.last_sort_time = time;
}
}, scope:this}"
in grid.
But it not works fine, because the received data was reordered by the grid before displayed on it
At last, I solve the problem in this way:
Ext.override(Ext.grid.column.Column, {
doSort:function(){
var ds = this.up('tablepanel').store;
ds.currentPage = 1;
this.callParent(arguments);
}
});
And it works perfectly so far
sortchange event fires after request is send to the server. For solution look here
http://www.sencha.com/forum/showthread.php?145779-Reset-page-for-paginator-on-sort-change

Grid not displaying in window - ext js

I am new to ext js. And my requirement is OnClick of a button, it calls a js function which pops up a window.Within this window I have a formPanel and a grid embedded in it. In the window items properties, if I add grid, the window is not showing. If I keep only form variable, then the window is displayed.
items : [filterPIDForm,pidGrid] is not working whereas
items: [filterPIDForm] is working fine.
Below is the code snippet
<script type="text/javascript">
jQuery(document).ready(function(){
// eCube search
jQuery('#eCubeSearch').click(function(){
pidSearch();
});
});
function pidSearch()
{
var filterPIDForm = new Ext.form.FormPanel({
title : 'Job Filters',
floatable : false,
id : 'filterForm',
tabTip : 'woot',
labelAlign :'top',
region :'west',
collapsible : true,
bodyStyle : 'padding: 5px; background-color: #DFE8F6',
border : false,
// style : 'border-top: 1px solid #99BBE8;',
width : 220,
items : [
{
xtype : 'combo',
width : 200,
id :'emailCombo',
fieldLabel :'Filter by Owner',
valueField :'emailValue',
displayField :'emailDisplay',
mode :'local',
editable :false,
typeAhead :false,
triggerAction :'all'
},
{
xtype : 'combo',
width : 200,
id :'statusCombo',
fieldLabel :'Filter by Status',
valueField :'statusValue',
displayField :'statusDisplay',
mode :'local',
editable :false,
typeAhead :false,
triggerAction :'all'
//value :'ALL'
},
{
xtype : 'textfield',
fieldLabel : 'PID/Description Search',
width : 200,
id :'searchText'
}
],
buttons: [
{
text : 'Clear Filter(s)',
id : 'clear'
},
{
text : 'Apply Filter(s)',
id : 'apply'
}
]
});
var pidGrid = new Ext.grid.GridPanel({
title : 'Job List',
id : 'pidList',
columns: [
//new Ext.grid.RowNumberer(),
{
header : 'PID',
width : 70,
dataIndex : 'pid',
sortable : true
},
{
header : 'Description',
id : 'description',
dataIndex : 'description',
sortable : true
}
]
});
var win = new Ext.Window({
modal:true,
title: 'PID Search',
layout:'absolute',
id: 'eCubeSearchWin',
width:1000,
height:400,
resizable: false,
plain: false,
resizable: false,
border: true,
closeAction :'close',
items : [filterPIDForm,pidGrid],
//items : [filterPIDForm],
buttons : [
{
text : 'OK',
id : 'test'
},
{
text : 'Close',
handler : function(){
Ext.getCmp('eCubeSearchWin').close();
}
}
]
});
win.show();
}
</script>
try setting layout in window
var win = new Ext.Window({
renderTo : Ext.getBody(),
width : 500,
height : 500,
layout : 'border',
items : [{
items : filterPIDForm
,layout :'fit'
,region : 'north'
,height : 300
},{
items : pidGrid
,layout :'fit'
,region :'center'
}]
}).show();

Align components in the center in a Panel: EXT JS

I am new to ext JS and I am tryin gto place 3 components in a FormPanel but I don't know ho wto align them in the center.
Here is my code
var durationForm = new Ext.FormPanel({
border : false,
labelAlign : 'top',
frame : true,
bodyStyle : 'padding-left:475px;',
items: [{
items: [{
rowWidth : .5,
layout :'column',
items:[{
columnWidth : .13,
layout : 'form',
items : [getNewLabel('<br/><font size="3">Duration: </font>')]
},{
columnWidth : .20,
layout : 'form',
items : [fromDate()]
},{
columnWidth : .17,
layout : 'form',
items : [toDate()]
}]
}]
}]
});
durationForm.render(Ext.getBody());
This shows output like this
But I want components to be align in the center of the panel. Anyone know how to do it?
I have solved this problem by using 'table' layout:
{
layout : 'fit', // parent panel should have 'fit' layout
items : [ // and only one item
{
xtype : 'panel',
border : false, // optional
layout : {
type : 'table',
columns : 1,
tableAttrs : {
style : {
width : '100%',
height : '100%'
}
},
tdAttrs : {
align : 'center',
valign : 'middle',
},
},
items : [ // a single container for nested components
{
xtype : 'panel',
layout : 'fit',
cellId : 'cell_id', // this one will be placed as id for TD
items : [
{}, {}, {} // nested components
]
}
]
}
]
}
{
//...
layout:'hbox',
layoutConfig: {
padding:'5',
pack:'center',
align:'middle'
},
items:[{
columnWidth : .13,
layout : 'form',
items : [getNewLabel(...)]
},{
columnWidth : .20,
layout : 'form',
items : [fromDate()]
},{
columnWidth : .17,
layout : 'form',
items : [toDate()]
}]
//...
}
See this
Just in case someone comes along looking for the answer like I did and couldn't find it here, use xtype:'splitter' between each item like so -
items:[{
xtype:'something'
},
{
xtype:'splitter'
},
{
xtype:'something-else'
}
}]

Resources