extjs6 layout run failed.. border layout, center region, hbox inside vbox - extjs

In my extjs6 version 6.0.0.640 project, I am getting layout run failed when I populate my grid and chart.
My panel's layout is set to border. In the center region I have a fit layout. Then trying to have 3 rows, but in one of the rows I want to put in a hbox. So far my layout is like this. If I remove the hbox it works, but I want to put multiple items in one of my rows.
Ext.define('ExtApplication4.view.historical.Historical', {
extend: 'Ext.panel.Panel',
xtype: 'app-historical',
controller: 'historical',
itemId: 'historicalItemId',
requires: [
'ExtApplication4.view.historical.HistoricalController',
'ExtApplication4.util.GlobalVar',
'Ext.chart.*'
],
title: 'Historical',
layout: {
type: 'border'
},
defaults: {
split: true,
bodyPadding: 15
},
items: [
{
title: 'Accounts',
region: 'west',
margin: '5 0 0 0',
width: 100,
//html: 'this is the menu account area',
dockedItems: [
{
xtype: 'toolbar',
dock: 'left',
//cls: 'myBgCls',
style: 'padding: 0; margin: 0;'
//items: [
// {
// xtype: 'combobox',
// itemId: 'comboboxClientItemID',
// emptyText: 'Select Client...',
// editable: false,
// displayField: 'clientName',
// valueField: 'clientName',
// bind: {
// store: '{myClientListStore}',
// selection: '{selectedClientListModel}'
// },
// listeners: {
// select: 'onComboboxSelect'
// },
// queryMode: "local"
// }
//]
}
]
},
{
title: 'Main Content',
region: 'center',
layout: {
type: 'fit'
},
items: [
{
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
{
xtype: 'button'
},
{
flex: 1,
title: 'Sector',
xtype: 'grid',
ui: 'featuredpanel-framed',
itemId: 'attributionSectorGridID',
cls: 'custom-grid',
margin: '0px 0px 0px 0px',
bind: {
store: '{myAttributionGroupedStore}'
},
columns: [
{
header: 'Sector',
dataIndex: 'Sector',
flex: 1
},
{
header: 'P&L',
dataIndex: 'DailyPL',
renderer: function (value) {
var newVal;
var calc = value.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
if (value > 0) {
newVal = '<span style="color:green">' + "$" + calc + '</span>';
} else if (value < 0) {
newVal = '<span style="color:red">' + "$" + calc + '</span>';
} else {
newVal = "$" + calc;
}
return newVal;
},
align: 'right',
flex: 1
}
]
},
{
xtype: 'panel',
flex: 3,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [
{
title: 'Winners',
xtype: 'grid',
ui: 'featuredpanel-framed',
itemId: 'attributionWinnersGridID',
cls: 'custom-grid',
margin: '5px 0px 0px 0px',
bind: {
store: '{myAttributionWinnersStore}'
},
columns: [
{
header: 'Sector',
dataIndex: 'Sector',
flex: 1
},
{
header: 'Market',
dataIndex: 'ShortDesc',
flex: 1
},
{
header: 'P&L',
dataIndex: 'DailyPl',
renderer: function (value) {
var newVal;
var calc = value.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
if (value > 0) {
newVal = '<span style="color:green">' + "$" + calc + '</span>';
} else if (value < 0) {
newVal = '<span style="color:red">' + "$" + calc + '</span>';
} else {
newVal = "$" + calc;
}
return newVal;
},
align: 'right',
flex: 1
}
]
}
]
}
]
}
]
}
]
});

If "Layout Run Failed" after adding a hbox layout, check all items of the container you added the hbox layout on. The items in an hbox layout require a width, either as fixed width, as percentage or using flex (the latter only works if the width of the container can be derived from somewhere).
In your case, the grid seems not to have a width. Usually, the grid width would be calculated by adding up all the column widths (the default width of a column being 100), but since at least one column has a flex set, this does not work in your case.
Similarly, if it failed after adding a vbox layout, one of the items of the container with said layout does not have a height.

Related

Ext table layout

I have a table with two rows and two columns - but I want to order each row differently.
The first row: (first column - width:30px, second column - width:270px)
The second row: (first column - width:130px, second column - width:170px).
I can't extract the two rows to different containers. I need to change the table.
My code is:
var replacePanel = new Ext.Container({
id:'replacePanel',
layout:'table',
border: false,
layoutConfig:{columns: 2},
style: { "padding-bottom": "5px", margin: "5px 0 0 20px" ,"white-space":"normal"},
items:[
{
xtype: "checkbox",
name: 'replace_cb', id: 'replace_cb',
width: 15, style: "margin-top:5px;",
listeners: {
check: function (checkbox, checked) {
var settingsForm = Ext.ComponentMgr.get('settingsForm');
settingsForm.changedFormula = true;
replacePanel.findById("replace_column").setDisabled(!checked);
}
}
},
{
xtype: "label", width: 390,
text: getDomElement("profileSetting.customMetrics.useNewMetric").value,
style:'padding-left:5px; padding-right:5px; margin-top:5px'
},
{
xtype: "container", width:160, style: "margin-top:4px", items: [
{
xtype: "combo", width: 150,
name:'replace_column',
id:'replace_column',
allowBlank:false, editable: false, typeAhead: true, disabled: true,
triggerAction: 'all', lazyRender:true, mode: 'local',
store: new Ext.data.JsonStore({ id: 'storeForReplaceColumn', fields: ['id', 'displayText'] }),
valueField: 'id',
displayField: 'displayText',
listeners: {
afterrender: function(combo) {
if (Ext.isIE) {
Ext.get(combo.el.dom.parentNode).setWidth(160);
}
},
select : function() {
var settingsForm = Ext.ComponentMgr.get('settingsForm');
settingsForm.changedFormula = true;
}
}
}]
},
{
xtype: "container",
html: getDomElement("profileSetting.customMetrics.whenReplacingMetrics").value
}
]
});
Table layout is not very good choice in this case. I would go for vbox layout for rows and hbox layout for columns.
Pseudo code:
vbox
item 1 (hbox)
left cell
right cell
item 2 (hbox)
left cell
right cell

Flex Property - Restart the row

I have a fieldcontainer which has several components. Each components has flex property as well. What I want to know that how can we break the row? As you can see the screen shot, 'FREE ARTICLE' field should start beginning of the new row but I don't know how can I specify this.
items: new Ext.Panel({
items: [
{
xtype: 'fieldset',
title: 'Artikel Sorgulama',
defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
height: '86px',
items: [
{
xtype: 'fieldcontainer',
layout: 'hbox',
defaultType: 'textfield',
fieldDefaults: {
labelAlign: 'top'
},
items: [
{
xtype: 'textfield',
id: 'articleNo',
flex: 1,
tabIndex: 1,
fieldLabel: 'ARTİKEL NO',
fieldStyle: 'text-align: right; font-size: 12pt',
margins: '0 10 0 0',
enableKeyEvents: true,
listeners: {
specialkey: function (field, e) {
if (field.getValue() != 'null') {
if (e.getKey() === e.ENTER || e.TAB) {
//articles.proxy.extraParams = {'article': field.getValue()};
articles.load({
params: {'article': field.getValue()},
callback: function () {
Ext.getCmp('articleDesc').setValue(articles.data.items[0].data['ART_DESC']);
}
});
}
}
},
focus: function (e) {
e.setValue('');
Ext.getCmp('articleDesc').setValue("");
articles.loadData([], false);
}
}
},
{
xtype: 'textfield',
id: 'articleDesc',
flex: 3,
fieldLabel: 'ARTİKEL TANIMI',
fieldStyle: 'font-size: 12pt',
readOnly: true
},
{
xtype: 'textfield',
fieldLabel: 'FREE ARTICLE',
flex: 0
}
]
}
]
},
You would need to use nested box layouts. The field container have a vbox layout. The first item in the fieldcontainer should be a container with an hbox layout (like your current code). The second item of the fieldcontainer should be the 3rd field (which will appear underneath due to the vbox layout).
Just don't add your free article field to the field container, but to the parent fieldset instead:
items: [
{
xtype: 'fieldset',
// ...
items: [
{
xtype: 'fieldcontainer',
layout: 'hbox',
// ...
}, {
xtype: 'textfield',
fieldLabel: 'FREE ARTICLE'
}
]
}
]

Displaying a grid inside the viewport on click - Ext JS

What I'm trying to do is add a grid that is 65% width of the panel created in my app.js
Ext.application({
name: 'AM',
appFolder: 'app',
controllers: [ 'Metadata', 'Print', 'Export' ],
launch: function() {
var types = Ext.create('AM.store.Type');
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 1000,
height: 600,
title: '<center>MetaCenter</center>',
layout: 'hbox',
style: { marginLeft: 'auto', marginRight: 'auto' },
items: [
{ xtype: 'panel', padding: 5, height: 500, width: '35%',
items: [
...
{ xtype: 'button', text: 'Search',
listeners: {
click: function() {
console.log('Search Button clicked');
//Code to create panel view?
}
},
],
}
I'm not explicitly creating a viewport, so I don't believe I could do a viewport.add('grid') function, but I'm not sure. Any ideas?
You could add the grid when creating the container, with hidden: true, then show it when the button is clicked:
{
layout: {
type: 'hbox',
align: 'stretch'
},
items: [
{
xtype: 'panel',
flex: 0.35,
items: [
...
{
xtype: 'button',
text: 'Search',
listeners: {
click: function(btn) {
btn.up('panel').nextSibling().show();
}
}
}
]
},
{
xtype: 'grid',
flex: 0.65,
hidden: true,
...
}
]
}

Ordering rownumberer after adding or deleting from the store ExtJS4.1

I have a extjs store which produces a grid. In the first column of the grid I have a rownumberer xtype to generate the serial number.
In the grid I can add(from other grid) or delete records through some action.While adding it copies the row number from the other grid. I want the rownumberer is to be sorted after every addition or removal.Please help.
items: [
{
xtype: 'grid',
id: 'allSurveyGrid',
store: alludfStore,
border: false,
width: 600,
height: 250,
layout: 'fit',
columns: [{
xtype: 'rownumberer'
}, {
header: 'Date',
sortable: false,
dataIndex: 'createdDt',
flex: 0.3
}, {
header: 'Question Name',
sortable: false,
dataIndex: 'questiontext',
flex: 1
}
],
selModel: {
mode: 'MULTI'
},
}, {
xtype: 'tbspacer',
height: 10
}, {
xtype: 'container',
header: false,
style: {
left: '465px'
},
layout: {
type: 'hbox'
},
items: [{
xtype: 'tbspacer',
width: 250
}, {
xtype: 'button',
text: '▼',
id: 'selectQn',
//flex: 1,
height: 40,
width: 40,
handler: function () {
//Elison : Delegate this to controller once the function is ready.
var allSurveyGrid = Ext.getCmp("allSurveyGrid");
var selModels = allSurveyGrid.getView().getSelectionModel().getSelection();
var selSurveyGrid = Ext.getCmp("addSurveyGrid");
var selectedSurveyStore = selSurveyGrid.getStore();
var countOfQuestion = 0;
if (selModels.length == 0) {
Ext.Msg.alert(' ' + 'ERROR', "Select atleast one question to add.");
return;
}
for (var c = 0; c < selectedSurveyStore.data.length; c++) {
item = selectedSurveyStore.data.items[c].data;
if (item.qName !== null && item.qName !== "") {
countOfQuestion = countOfQuestion + 1;
} else {
selectedSurveyStore.remove(selectedSurveyStore.getAt(c));
}
}
var finalCount = countOfQuestion + (selModels.length);
if (finalCount >= 16) {
Ext.Msg.alert(' ' + 'ERROR', "More than 15 UDF is not allowed");
return;
} else {
// selectedSurveyStore.add(selModels);
/* for(var x=0;x<selModels.length;x++){
selModels.getAt[0].set('questionId',selectedSurveyStore.data.length+1);
}*/
selectedSurveyStore.loadData(selModels, true);
selSurveyGrid.getView().refresh();
}
}
}, {
xtype: 'tbspacer',
width: 10
}, {
xtype: 'button',
text: '▲',
id: 'unSelectQn',
height: 40,
width: 40,
style: {
borderRadius: 0
},
//flex: 1,
handler: function () {
var selSurveyGrid = Ext.getCmp("addSurveyGrid");
var selModels = selSurveyGrid.getView().getSelectionModel().getSelection();
var selectedSurveyStore = selSurveyGrid.getStore();
selectedSurveyStore.remove(selModels);
},
}, {
xtype: 'tbspacer',
width: 250
}
]
}, {
xtype: 'tbspacer',
height: 10
}, {
xtype: 'grid',
id: 'addSurveyGrid',
store: addudfStore,
border: false,
width: 600,
height: 250,
layout: 'fit',
columns: [{
xtype: 'rownumberer'
}, {
header: 'Date',
sortable: false,
dataIndex: 'createdDt',
flex: 0.3
}, {
header: 'Question Name',
sortable: false,
dataIndex: 'questiontext',
flex: 1
}
],
selModel: {
mode: 'MULTI'
},
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop'
}
}
}
]
Try calling
grid.getView().refresh();
right after you add or remove an item from the grid.
https://www.sencha.com/forum/showthread.php?240240-Refresh-RowNumberer-after-store.insert()
FYI:
/**重写rownumber*/
Ext.override(Ext.grid.RowNumberer, {
renderer: function(value, metaData, record, rowIdx, colIdx, store) {
var rowspan = this.rowspan;
if (rowspan){
metaData.tdAttr = 'rowspan="' + rowspan + '"';
}
metaData.tdCls = Ext.baseCSSPrefix + 'grid-cell-special';
//return store.indexOfTotal(record) + 1;
return store.indexOf(record) + 1;
}
});
and,refresh the grid view after insert or delete,like this:
store.insert(0,newRecord);
headerFormGrid.getView().refresh();

How do I enable custom drag and drop (ext js 4.1.3)

Edit: I deleted the code that didn't matter for the question being asked
I am trying to mimic the example given in the documentation here: http://docs.sencha.com/ext-js/4-1/#!/example/dd/dragdropzones.html.
When I click and drag inside any of the divs created by the dataview, I start selecting text instead of dragging the dataview item.
I have put console.log() statements here and there to verify that the code is firing. All of the elements that are returned by the getDragData function hold information.
I have tried adding both "draggable: true" and "enableDrag: true". Neither one allowed me to drag the div. However, "draggable: true" did make it such that when I clicked and dragged I was no longer selecting text.
I believe this is the only code that pertains to the issue:
SearchDataView.js
Ext.require('Client.store.SearchStore');
Ext.define('Client.view.SearchDataView',
{
extend: 'Ext.view.View',
alias: 'widget.SearchDataView',
config:
{
store: Ext.create('Client.store.SearchStore'),
tpl: '<tpl for=".">' +
'<div class="search-wrapper">' +
'<div class="search-icon">' +
'<img src="../../Images/icons/Person50x50.jpg" />' +
'</div>' +
'<div class="search-text">' +
'<span class="title">{FirstName} {LastName}</span>' +
'<span class="address">address, city, state zip</span>' +
'<span class="info">DOB: 7/3/1970</span>' +
'</div>' +
'</div>' +
'</tpl>',
itemSelector: 'div.search-wrapper',
emptyText: 'Nobody in database',
deferEmptyText: false,
singleSelect: true,
listeners:
{
render: initializeSearchDragZone
}
}
}
);
function initializeSearchDragZone(v) {
v.dragZone = Ext.create('Ext.dd.DragZone', v.getEl(), {
getDragData: function (e) {
var sourceEl = e.getTarget(v.itemSelector, 10), d;
if (sourceEl) {
d = sourceEl.cloneNode(true);
d.id = Ext.id();
return v.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d,
searchData: v.getRecord(sourceEl).data,
sourceStore: v.store
}
}
},
getRepairXY: function () {
return this.dragData.repairXY;
}
});
}
Viewport.js
Ext.require('Client.view.SearchPanel');
Ext.require('Client.view.DesktopPanel');
Ext.define('Client.view.Viewport',
{
extend: 'Ext.container.Viewport',
initComponent: function () {
Ext.apply(this,
{
layout: 'border',
items:
[
{
region: 'north',
margins: 5,
height: 30,
xtype: 'container'
},
{
region: 'west',
margins: '0 5 0 5',
flex: .25,
collapsible: true,
titleCollapse: true,
xtype: 'SearchPanel'
},
{
region: 'center',
xtype: 'DesktopPanel'
},
{
region: 'east',
margins: '0 5 0 5',
width: 200,
collapsible: true,
titleCollapse: true,
collapsed: true
},
{
region: 'south',
margins: '0 5 5 5',
flex: .3,
split: true
}
]
}
);
this.callParent(arguments);
}
}
);
SearchPanel
Ext.require('Client.view.SearchForm');
Ext.require('Client.view.SearchDataView');
Ext.require('Client.view.AddTrashForm');
Ext.define('Client.view.SearchPanel',
{
extend: 'Ext.panel.Panel',
alias: 'widget.SearchPanel',
config:
{
items:
[
{
xtype: 'SearchForm'
},
{
xtype: 'SearchDataView'
},
{
xtype: 'AddTrashForm'
}
]
},
cls: 'searchpanel'
}
);
I added layout config to SearchPanel, and drag started working:
layout:
{
type: 'vbox',
align: 'stretch'
}
It changes some of my layout, so I will have to adjust css now, but drag is working.

Resources