I'm trying to create a container that has four items, and what I need is the container to be the one that scroll instead of each individual item, also I want every item to have it's own height so if the four items are bigger than the screen the user can scroll down through the container to see the other items info...
JSFiddle:
http://jsfiddle.net/martuanez/7GV3b/
My code:
var store = {
type: 'store',
fields: ['label', 'value'],
data: [{
label: 'label',
value: 'value',
}, {
label: 'label',
value: 'value',
}, {
label: 'label',
value: 'value',
},
]
};
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: ('SF' || 'SenchaFiddle'),
launch: function () {
Ext.define('MyApp.view.Contacts.ContactsDetailsView', {
xtype: 'ContactsDetailsView',
extend: 'Ext.Container',
config: {
layout: {
type: 'vbox',
padding: 3
},
defaults: {
scrollable: {
direction: 'horizontal',
directionLock: true
},
height: 500,
layout: 'fit'
},
scrollable: 'vertical',
itemCls: 'details-list-container',
items: [{
xtype: 'dataview', //add xtype
itemId: 'detailItem',
loadingText: 'Loading keys...',
emptyText: '<div>No keys found.</div>',
store: store,
onItemDisclosure: false,
itemTpl: '<br/>item 1:<br/> {label}<br/>{value}<br/><br/>',
itemCls: 'details-list',
selectedItemCls: '',
disableSelection: true,
pressedCls: ''
}, {
xtype: 'list',
itemId: 'detailKeys',
store: store,
loadingText: 'Loading keys...',
emptyText: '<div>No keys found.</div>',
onItemDisclosure: false,
itemTpl: 'item 2: {label}{value}<br/>',
itemCls: 'details-list',
selectedItemCls: '',
disableSelection: true,
pressedCls: ''
}, {
xtype: 'list', //add xtype
itemId: 'detailuserdefs',
store: store,
loadingText: 'Loading userdefs...',
onItemDisclosure: false,
itemTpl: 'item 3: {label}{value}<br/>',
itemCls: 'details-list',
selectedItemCls: '',
disableSelection: true,
pressedCls: ''
}, {
xtype: 'list',
itemId: 'detailOthers',
store: store,
loadingText: 'Loading userdefs...',
onItemDisclosure: true,
itemTpl: 'item 4: {label}{value}<br/>',
itemCls: 'details-list'
}
]
}
});
Ext.Viewport.add(Ext.create('MyApp.view.Contacts.ContactsDetailsView'));
}
});
I´ve finally make it work, i set scrollable to false in the defaults section of the container and a height on the child items.
One thing that happened is that when setting scrollable to false in the childs, not in the defaults, sencha didn't recognize the height, this is a bug that they claim they have fixed already, actual version by the time i'm writting this 2.2, version i'm working on 2.1.1
Note: I also managed to set dinamic heights on each item, i did this by setting it apart and adding the items later by doing myContainer.add(itemWithDinamicHeight);
;)
Cheers!
Related
I have an ExtJS form constructed within a grid's tbar which allows for filtering of grid results.
The structure is, visually:
A combobox for specifying date type
A combobox for specifying date range type
then potentially either:
Nothing
or
A combobox containing specific date values
or
Two datepickers
ended with a textfield for further filtering on text values within the results.
All form fields are arranged horizontally ("column" layout).
One of the date range types is "All", which removes the need for the combobox with specific date values or datepickers, both options taking up the same space. In the interest of visual consistency the text filter is to stay in the same place regardless of what is between it and the date range type combobox.
I would assume that there would be some property that can be applied to place the textfield dependent on the date range combobox, and I've seen AlignTo which looks promising, but not directly related to a textField.
Can AlignTo or similar be used to set a form field a set distance from another form field, and if so how?
Example code:
xtype: 'form',
id: 'gridFilterForm',
url: '<?= $site_url ?>Production/Schedule',
layout: 'column',
standardSubmit: true,
// The fields
defaultType: 'textfield',
items: [
{
xtype: 'combobox',
id: 'dateFilterPicker',
store: dateFilterPickStore,
querymode: 'local',
editable: false,
fieldLabel: 'Filter Type:',
labelWidth: 45,
labelAlign:'top',
displayField:'name',
valueField:'value',
value: '<?= $this->data['filterDateType'] ?>',
listeners: {
change: loadProductionItems
}
},
{
xtype: 'combobox',
id:'dateRangePick',
store: dateRangePickStore,
queryMode: 'local',
editable: false,
fieldLabel: 'Filter On:',
labelAlign:'top',
labelWidth: 45,
displayField: 'name',
valueField: 'value',
value: '<?= $this->data['filterDateRange'] ?>',
listeners:{
change: changeStoresAndFilters
},
width: 65,
allowBlank: false
},{
xtype: 'combobox',
id:'dateRangeFrom',
fieldLabel: 'Range:',
labelAlign:'top',
editable: false,
labelWidth: 45,
store: dateRangeStore,
queryMode: 'remote',
displayField: 'Name',
valueField: 'Id',
columnWidth:.60,
listeners: {
select: function(value){
// actions
}
}
},{
xtype:'datefield',
id: 'fromDatePicker',
fieldLabel: 'From',
labelAlign:'top',
editable: false,
labelWidth: 40,
hidden: true,
disabled: true,
columnWidth:.30,
format: 'd M Y',
listeners: {
select: function(){
// actions
}
}
},{
xtype:'datefield',
id: 'toDatePicker',
fieldLabel: 'To',
labelAlign:'top',
editable: false,
labelWidth: 30,
hidden: true,
disabled: true,
columnWidth:.30,
format: 'd M Y',
listeners: {
select: function(){
// actions
}
}
},{
xtype: 'textfield',
id: 'searchTextBox',
fieldLabel: 'Search Text:',
labelAlign:'top',
labelWidth: 70,
columnWidth:.30,
listeners: {
change: function(){
// actions
}
}
}
]
Managed some form of a workaround:
Firstly, works only with explicit width columns: [code]columnWidth[/code] changes to [code]width[/code] and width values become numbers of pixels.
Have a displayfield, just before the text field, that can occupy the same width as the combobox/datepickers it "replaces", and have it be hidden until it is needed (i.e. both the combobox or datepickers are hidden), with various hide() and show() calls.
Remarkably simple, but I'd have thought there was better layout control in ExtJS and wouldn't have needed additional elements.
code:
... //combobox and datepickers
{
id: 'spacer',
xtype: 'displayfield',
width: 240
},
... // textfield search box
My problem is, even if I used "layout: 'fit'" in all my children items within a boarder layout, they just shrinks into a small box rather than fill the parent, as described in fit layout.
I want the EDS.view.selector.Container to fill the "navigation" section of my boarder layout.
(Code excerpt)
Ext.define('EDS.view.selector.Container', {
extend: 'Ext.panel.Panel',
alias : 'widget.selectorcontainer',
layout: 'fit',
initComponent: function(){
this.items = [
{
xtype: 'tabpanel',
defaults: {
bodyPadding: 10
},
layout: 'fit',
items:[
{
title: 'Organization',
id: 'selector-organization',
tag: 'div',
html: 'div here',
height: '100%',
}
]
}
],
this.callParent();
},
});
(Controller)
init: function(){
console.log('controller.init()');
new Ext.Viewport({
title: 'Data Analysis',
layout: 'border',
defaults: {
collapsible: true,
split: true,
bodyStyle: 'padding: 15px',
},
items: [{
title: 'Navigation',
region:'west',
margins: '5 0 0 0',
cmargins: '5 5 0 0',
width: 600,
minSize: 100,
maxSize: 250,
items: [
{
id: 'selector-container',
xtype: 'selectorcontainer',
layout: 'fit',
}
]
},{
title: 'Main Content',
collapsible: false,
region:'center',
margins: '5 0 0 0'
}]
});
}
You did not set up layout for wrapper containers in your border layout:
items: [{
title: 'Navigation',
region:'west',
layout: 'fit',
...
items: [
]
},{
title: 'Main Content',
collapsible: false,
region:'center',
layout: 'fit',
...
}]
Remember: In ExtJS any plain JS object that goes into items property of a container will be converted into some type of Ext component with xtype defined by defaultType property of that container. In most cases it will be panel.
I'm trying to build my container in the initialize() function by creating all my components then calling this.setItems([...]). For some reason, my components are being placed on top of each other, rather than after each other in the vbox.
I am able to grab the top component and move it down, as is shown in the attached image.
Simplified view with two components:
Ext.define("Sencha.view.DynamicView", {
extend: 'Ext.Container',
xtype: 'dynamic-view',
requires: [],
config: {
layout: {
type: 'vbox'
},
flex: 1,
cls: 'view-container',
store: null
},
createRadioSet: function() {
this.radioFieldSet = Ext.create('Ext.form.FormPanel', {
flex: 1,
items: [{
xtype: 'fieldset',
title: 'About You',
defaults: {
xtype: 'radiofield',
labelWidth: '40%'
},
instructions: 'Favorite color?',
items: [{
name: 'color',
value: 'red',
label: 'Red'
},
{
name: 'color',
value: 'green',
label: 'Green'
}
]
}]
});
return this.radioFieldSet;
},
createCheckboxSet: function() {
this.checkboxFieldSet = Ext.create('Ext.form.FormPanel', {
flex: 1,
items: [{
xtype: 'fieldset',
title: 'Check all that apply',
defaults: {
xtype: 'checkboxfield',
labelWidth: '40%'
},
instructions: 'Tell us all about yourself',
items: [{
name: 'firstName',
value: 'First',
label: 'First Name'
},
{
name: 'lastName',
value: 'Last',
label: 'Last Name'
}
]
}]
});
return this.checkboxFieldSet;
},
initialize: function() {
this.callParent(arguments); // #TDeBailleul - fixed
var r1 = this.createRadioSet();
var cbSet1 = this.createCheckboxSet();
// this.add(cbSet1);
// this.add(r1);
this.setItems([r1, cbSet1]);
}
});
My problem was that I was adding my components incorrectly in a tab controller. I'm including an example that creates buttons on one tab and the checkboxes on another tab.
Ext.Loader.setConfig({
enabled : true
});
Ext.application({
name : ('SF' || 'SenchaFiddle'),
createRadioSet: function () {
this.radioFieldSet = Ext.create('Ext.form.FormPanel', {
height: '300px',
width: '300px',
items: [
{
xtype: 'fieldset',
title: 'Title',
defaults: {
xtype: 'radiofield',
labelWidth: '40%'
},
instructions: 'Favorite color?',
items: [
{
name: 'color',
value: 'red',
label: 'Red'
},
{
name: 'color',
value: 'green',
label: 'Green'
}
]
}
]
});
return this.radioFieldSet;
},
createButton: function(i) {
return Ext.create('Ext.Button', {
text: 'hello' + i,
height: '50px',
width: '100px'
});
},
launch: function () {
var tabPanel = Ext.create('Ext.tab.Panel', {
layout: 'card',
padding: 2,
tabBarPosition: 'bottom',
items: [
{
id: 'tab1',
title: 'Home',
layout: 'hbox',
xtype: 'container',
iconCls: 'home'
},
{
id: 'tab2',
title: 'More',
layout: 'hbox',
xtype: 'container',
iconCls: 'star'
}
]
});
Ext.Viewport.add(tabPanel);
var a,b;
for (var i = 0; i < 3; i++) {
a = this.createButton(i);
b = this.createRadioSet();
// tabPanel.getAt(0).add(b); // Reference the proper component: Tab 1
Ext.getCmp('tab1').add(a);
Ext.getCmp('tab2').add(b);
}
}
});
this is code and link on screenshot
Ext.define('SD.view.SDDetail', {
extend: 'Ext.window.Window',
alias: 'widget.sddetail',
title: "Создание заявки",
height: 620,
width: 850,
layout: 'fit',
border: false,
modal: true,
isDemandReadOnly: false,
changeStatusOnly: false,
initComponent: function () {
var me = this;
var user = TR.user;
var f = new Ext.form.FormPanel({
xtype: 'form',
labelWidth: 60
, frame: true
, items: [{
fieldLabel: 'Text'
, xtype: 'textfield'
, anchor: '-18'
}, {
layout: 'column'
, defaults: {
columnWidth: 0.5
//, layout: 'form'
, border: false
, xtype: 'panel'
, bodyStyle: 'padding:0 18px 0 0'
}
, items: [{
defaults: { anchor: '100%' }
, items: [{
xtype: 'combo'
, fieldLabel: 'Combo 1'
, store: ['Item 1', 'Item 2']
}, {
xtype: 'datefield'
, fieldLabel: 'Date'
}]
}, {
defaults: { anchor: '100%' }
, items: [{
xtype: 'combo'
, fieldLabel: 'Combo 2'
, store: ['Item 1', 'Item 2']
}, {
xtype: 'timefield'
, fieldLabel: 'Time'
}]
}]
}, {
fieldLabel: 'Text Area'
, xtype: 'textarea'
, anchor: '-18 -80'
}]
});
this.items = [f];
this.tbar = {
xtype: 'toolbar',
height: 27,
items: [
{
xtype: "tbspacer"
}, "-", {
xtype: "tbspacer"
},
{
text: "Прикрепленные файлы",
icon: "Content/images/btnAttach.gif",
disabled: true,
handler: function (btn, e) { ShowAttachments(r.id, true, me.isDemandReadOnly); }
}, "-", {
xtype: "tbspacer"
}, {
text: "История статусов",
icon: "Content/images/btnHistory.gif",
disabled: true,
handler: function (btn, e) { ShowStatusesHistory(r.id, true); }
}, "-", {
xtype: "tbspacer"
}, {
text: "Информация по сопроводительной карточке",
icon: "Content/images/btnComplect.gif",
disabled: true,
handler: function (btn, e) { ShowComponents(r.id, true, me.isDemandReadOnly); }
}, "-", {
icon: "Content/images/btnPrint.gif",
text: "Сопроводительная карточка изделия",
disabled: true,
handler: function (btn, e) { DemandCardForm(r.id); }
}
]
};
this.buttons = [
{
text: "Сохранить",
action: 'save'
, disabled: me.isDemandReadOnly || user.SdUserViewOnly
}, {
xtype: "button",
text: "Отмена",
handler: function (btn, e) {
me.close();
}
}
];
// me.on('show', function () {
// me.down('kontragentcombo').focus(false, 250);
// });
me.callParent(arguments);
}
http://s002.radikal.ru/i198/1208/e2/7a153ca9b116.jpg
when i uncomment layout: 'form' i have error
namespace is undefined
[Прерывать на этой ошибке]
if (namespace === from || namespace.substring(0, from.length) === from) {
i whant this http://i032.radikal.ru/1208/51/e9b8ba1c1f30.jpg
but have error, what i must do?
layout is not defined in the items of the panel. It's part of the panel's properties (see the docs: Form Panel). Put it before the items.
As a suggestion - it would be easier to see it if your lines had consistent comma layout.
I have a panel which is fullscreen;
PortalDashboard.views.Dashboardcard = Ext.extend(Ext.Panel, {
fullscreen: true,
title: 'Dashboard',
html: '',
cls: 'card5',
iconCls: 'team',
layout: Ext.Viewport.orientation == 'landscape' ? {
type: 'hbox',
pack: 'center',
align: 'stretch'
} : {
type: 'vbox',
align: 'stretch',
pack: 'center'
},
monitorOrientation: true,
listeners: {
orientationchange : this.onOrientationChange,
},
styleHtmlContent: false,
initComponent: function () {
Ext.apply(this, {
items: [
{
xtype: 'dashboardbox',
items: [rep1, rep2, rep3]
}, {
xtype: 'dashboardbox',
items: [rep4, rep5, rep6]
}]
});
PortalDashboard.views.Dashboardcard.superclass.initComponent.apply(this, arguments);
}
})
So the panel has a hbox layout with 2 child panels. The child panels actually take up the full amount of horizontal space, but not vertically.
I can set the min-height in the css, which gets respected on in chrome and safari on my pc... but the ipad ignores it.
The child panels are defined as;
PortalDashboard.views.DashboxBox = Ext.extend(Ext.Panel, {
cls: 'dashbox',
monitorOrientation: true,
listeners: {
orientationchange : this.onOrientationChange,
},
layout: Ext.Viewport.orientation == 'landscape' ? {
type: 'vbox',
align: 'stretch',
pack: 'center'
} : {
type: 'hbox',
align: 'stretch',
pack: 'center'
},
defaults: {
flex: 1
}
});
Ext.reg('dashboardbox', PortalDashboard.views.DashboxBox);
I've had this before with a TabPanel parent of some sub panels. Try layout: 'fit' in your parent panel. (Although I'm not sure if adding it to your current list of layout options will work or if it needs to be set by itself.)