SenchaTouch - Move items from one panel to another - extjs

To handle orientation change, my first move was to modify the main panel's layout type from hbox to vbox and vice versa depending on the orientation, but Sencha doesn't allow dynamic layout change for the moment, then I found an idea on the internet.
Someone suggested to create 2 panels, one hbox and the other vbox, and when there is an orientation change move items from one panel to another, and show/hide the correct one, say I have this code below :
{
xtype: 'panel'
id: 'landscape-panel',
layout: 'hbox'
items: [
// My items
],
}, {
xtype: 'panel',
id: 'portrait-panel',
layout: 'vbox',
hidden: true
}
How can I move landscape-panel items to portrait-panel ?

Works like a charm :
if (Ext.Viewport.getOrientation() == 'portrait') {
var backupItems = Ext.getCmp('login-landscape-panel').items.items.slice(0); // clone array
Ext.getCmp('login-portrait-panel').add(backupItems);
Ext.getCmp('login-landscape-panel').removeAll();
Ext.getCmp('login-landscape-panel').hide();
Ext.getCmp('login-portrait-panel').show();
} else {
var backupItems = Ext.getCmp('login-portrait-panel').items.items.slice(0); // clone array
Ext.getCmp('login-landscape-panel').add(backupItems);
Ext.getCmp('login-portrait-panel').removeAll();
Ext.getCmp('login-portrait-panel').hide();
Ext.getCmp('login-landscape-panel').show();
}

This is what i would do in ExtJs it's almost if not completely the same in touch
http://jsfiddle.net/Vandeplas/vx5739qn/
var viewport = Ext.create('Ext.container.Viewport', {
layout: 'border',
items: [{
xtype: 'panel',
itemId: 'landscape-panel',
layout: 'hbox',
items: [{
xtype: 'component',
width: 100,
height: 100,
html: '<div>component 1</div>'
}, {
xtype: 'component',
width: 100,
height: 100,
html: '<div>component 2</div>'
}]
}, {
xtype: 'panel',
itemId: 'portrait-panel',
layout: 'vbox',
hidden: true
}],
renderTo: Ext.getBody()
});
var orientationChange = function (orientation) {
var ppanel = viewport.down('#portrait-panel'),
lpanel = viewport.down('#landscape-panel'),
items,
isHorizontal = (orientation === 'H');
if (isHorizontal) {
items = ppanel.items.items;
if (items.length > 0) {
lpanel.add(items);
ppanel.removeAll(false);
}
} else {
items = lpanel.items.items;
if (items.length > 0) {
ppanel.add(items);
lpanel.removeAll(false);
}
}
ppanel.setVisible(!isHorizontal);
lpanel.setVisible(isHorizontal);
};
orientationChange('V');
//orientationChange('H');

Related

How to add an additional button to a column header (extjs 6.2)

i need to add a button to the column header besides the filters menu (like the blue mark on the photo)
A little hack like this could work. Just get the layout aligned to show content in left and right most parts of Container.
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [{
xtype: 'container',
items: [{
xtype: 'grid',
sortable: true,
columns: [{
flex: 1
}, {
text: "Age",
flex: 1
}],
listeners: {
afterrender: function (grid) {
var columns = grid.columnManager.getColumns();
var nameCol = columns[0];
var targetDom = nameCol.textInnerEl.dom;
var newPanel = Ext.create('Ext.container.Container', {
items: [{
xtype: 'label',
text: "Name"
}, {
xtype: 'button',
text: "DO IT"
}],
renderTo: targetDom
});
}
}
}]
}]
});
Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/29o8

How to optimize adding components to a view?

First of all, I have about 1000-1500 records and I need to show them in a grid in custom style. But, first row has to contain checkbox and a form(combo,textfield), which is below that checkbox.
Similar to:
row1: checkbox
combo, textfield, textfield
row2: checkbox
combo, textfield, textfield
...
So, I could not use grid for this approach(Because I have to use 'colum render function' to each row and it causes re-render whole grid again even if change one row).
That's why I tried to add each component to a panel dynamically. But the main problem is that whenever I add the components to the panel, it takes too long . For example, it takes 4.5 s for only 100 records. I can't even imagine how long would it take for 1500 records.
Please check this fiddle. You will understand the exact problem. please do not forget the check console.time:
https://fiddle.sencha.com/#fiddle/13g0
And sample codes:
console.time('FakeGrid');
Ext.suspendLayouts();
var fakeGrid = Ext.create('Ext.panel.Panel', {
title: 'Fake grid Panel',
renderTo: Ext.getBody(),
});
var records = [];
for(var i=0; i < 10; i++) {
records.push({
id: 'Check'+ i,
reg: 'Reg' + i
})
}
Ext.each(records, function(rec) {
var regionPanel = {
xtype: 'fieldset',
collapsible: true,
border: false,
title: rec.reg,
layout: 'vbox',
items: []
};
Ext.each(records, function(rec) {
var hBoxPanel = {
xtype: 'panel',
layout: 'hbox',
items: [{
xtype: 'checkbox',
boxLabel: rec.id
}]
};
var fakeSubPanel = Ext.create('Ext.panel.Panel', {
layout: 'hbox',
items: [{
xtype: 'combobox',
fieldLabel: 'Combo'
}, {
xtype: 'textfield',
fieldLabel: 'field1'
}, {
xtype: 'textfield',
fieldLabel: 'field2'
}]
});
var sitePanel = {
xtype: 'panel',
layout: 'vbox',
//margin: '5 0 0 31',
items: [hBoxPanel, fakeSubPanel]
};
regionPanel.items.push(sitePanel);
}); //Ext.each
fakeGrid.add(regionPanel);
}); //Ext.each
Ext.resumeLayouts(true);
console.timeEnd('FakeGrid');
If you have any suggestion, please enlight me with your ideas. Thank you so much!

Pass data between views in ExtJS

I am reading data from store and populating main girdView. When any of the row is clicked, a windows appear and I want to fill the fieldset in that window with the same record which is clicked.
Can anyone tell me how to do it?
My popup window is like:
{
extend: 'Ext.window.Window',
height: 500,
width: 1500,
minWidth :1500,
maxWidth :1500,
layout: 'fit',
controller: 'PopUpWindowController',
initComponent: function () {
var me = this;
//console.log(me.myExtraParams);
var Store = Ext.getStore('mainStore');
Ext.applyIf(me, {
/* items: [{
xtype: 'form',
bodyPadding: 10,
region: 'center'
}]*/
});
me.callParent(arguments);
},
items: [
{
xtype: 'panel',
title : 'Projektierung',
bodyStyle : 'padding:5px',
width : 1880,
autoHeight : true,
items:
[
{
xtype : 'kopfdatenView', // Have to populate this view
}
]
}]}
and in Main view I am calling it as:
{
region: 'center',
xtype: 'gridpanel',
listeners : {
itemdblclick: function(dv, record, item, index, e) {
var extra = record.data;
win = Ext.create('App.view.PopUpWindow');
console.log(win.myExtraParams);
win.on('show', function(win) {
win.setTitle(record.get('ID'));
});
win.show();
}
},
columns: [
****
],
store: 'mainStore',
height: 100,
width: 400,
}
I want to populate fieldset in kopfdatenView. Kindly help
You directly pass your record to your window on creation :
win = Ext.create('App.view.PopUpWindow', {
myRecord: record
});
And then inside the window's initComponent function (before the callParent) :
this.title = this.myRecord.get('ID');
You can do something like this:
win = Ext.create('App.view.PopUpWindow', {
params: record
});
Then, in your PopUpWindowController you can retrieve 'params' in the render event (for example).

Cannot get the object of a tabpanel

I have a grid in the center region of a border layout. When a specific item is clicked in the grid, I need to change the center region to display a tab panel. I am having trouble getting the tabpanel object.
In the ctrlpanel file, on the grid listener, I am using componentQuery to get the tabpanel('ccmain') object. It returns undefined.
I was using componentQuery to get 'ccmain' in the centerpanel file(lays out center region) successfully, but when I moved this code to the ctrlpanel file(one of the items in centerpanel) it fails. ComponentQuery no longer returns the tabpanel 'ccmain'. ComponentQuery does return the centerpanel or the viewport. I attemped to do centerpanel or viewport.down to find 'ccmain', but that also returns undefined. If you can tell me how to get the tabpanel or what I am doing wrong, I would appreciate it. Thanks for your time.
ctrlPanel.js
Ext.define('ServcSol.view.CtrlPanel',{
extend: 'Ext.Panel',
alias: 'widget.ctrlPanel',
xtype: 'ctrlPanel',
itemId: 'ctrlPanel',
requires:[
'ServcSol.store.FacilityStore'
],
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'panel',
height: 750,
title: 'Control Panel',
items: [
{
xtype: 'gridpanel',
padding: '20 20 5 20',
store: 'WorkHistoryStore',
height: 590,
width: '100%',
border: true,
columns: [
{
width: 110,
dataIndex: 'wrkhistDate',
text: 'Due Date'
},
{
width: 100,
dataIndex: 'wrkType',
text: 'Work Type'
}
],
listeners : {
itemclick: function(dv, record, item, index, e)
{
if(record.get('wrkType') == 'Test')
{
var tabPanel = Ext.ComponentQuery.query('ccmain')[0];
console.log('tabPanel is: ', tabPanel);
var tabIndex = tabPanel.items.findIndex('id', 'hazard');
var center = Ext.ComponentQuery.query('centerpanel')[0];
center.getLayout().setActiveTab(tabIndex);
}
ccmain.js
Ext.define('ServcSol.view.ccMain', {
extend: 'Ext.tab.Panel',
itemId: 'ccmain',
alias: 'widget.ccmain',
xtype: 'ccmain',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'facility'
},
{
xtype: 'hazListing'
},
{
xtype: 'hazard'
},
{
xtype: 'testFormRP'
},
{
xtype: 'testFormDC'
}
]
});
this.callParent(arguments);
}
});
One of the reasons can be that ccmain is not instantiated as only instantiated components can be found by ComponentQuery.query. Then, even if ccmain would be found you cannot set its active item that way. Easiest is to assign tabs itemIds and then call setActiveTab:
tabPanel.setActiveTab(itemIdOfTheTab)

How to drag panels in main Panel

How to allow drag & drop panels in a main panel ?
I have a panel which contains one panel ( for the moment ) or somes panels and i want allow drag and drop for organize panels.
like this examples : http://examples.extjs.eu/freedrag.html
but i don't understand how to adapte this with my application .
My code :
( Is the Sticky items into tabobj tab.Panel then i want drag & drop )
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.Action',
'Ext.tab.*',
'Ext.button.*',
'Ext.form.*',
'Ext.layout.*'
]);
Ext.onReady(function() {
Ext.tip.QuickTipManager.init();
Ext.define('Mesclasses.objet.sticky', {
alias: ['widget.stick'],
extend: 'Ext.panel.Panel',
bodyStyle: {
background: 'yellow',
},
height: 150,
width: 150,
margin: '10 0 0 10',
draggable: true,
items: [{
xtype: 'label',
text: 'Title',
listeners: {
move: function (me, x, y, opt) {
alert('move');
}
}
}],
});
var item2 = Ext.create('Ext.Panel', {
title: 'Accordion Item 2',
html: '<empty panel>',
cls: 'empty'
});
var item3 = Ext.create('Ext.Panel', {
title: 'Accordion Item 3',
html: '<empty panel>',
cls: 'empty'
});
var item4 = Ext.create('Ext.Panel', {
title: 'Accordion Item 4',
html: '<empty panel>',
cls: 'empty'
});
var item5 = Ext.create('Ext.Panel', {
title: 'Accordion Item 5',
html: '<empty panel>',
cls: 'empty'
});
var accordion = Ext.create('Ext.Panel', {
region: 'west',
margins: '5 0 5 5',
split: true,
width: 210,
layout: 'accordion',
items: [item2, item3, item4, item5]
});
var paneltitle = Ext.create('Ext.panel.Panel', {
region: 'north',
html: '<h1 class="x-panel-header" id="title">Your Sticky World</h1>',
height: 40
});
var montab = Ext.create('Ext.tab.Tab', {
title: 'lol',
});
var tabobj = Ext.create('Ext.tab.Panel', {
region: 'center',
//xtype: 'tabpanel', // TabPanel itself has no title
activeTab: 0, // First tab active by default
items: [{
title: 'My Stickys',
xtype: 'panel',
items: [{
xtype: 'stick',
}]
}]
});
Ext.create('Ext.container.Viewport', {
layout: 'border',
renderTo: Ext.getBody(),
items: [
paneltitle,
accordion, {
region: 'south',
title: 'South Panel',
collapsible: true,
html: 'Information goes here',
split: true,
height: 100,
minHeight: 100
}, {
region: 'east',
title: 'East Panel',
collapsible: true,
split: true,
width: 150
},
tabobj]
});
});
Reviewing the sources of the page could help.
The main idea is, generally, to create Ext.dd.DDProxy for each panel you are dragging.
So, the following snippet could help you get the basic functionality working:
{
title: 'My Stickys',
xtype: 'panel',
items : [{
xtype : 'stick',
listeners : {
afterrender : function(stick){
stick.dd = new Ext.dd.DDProxy(stick.el.dom.id, 'group');
}
}
}]
}
Or, to be more generic (check the afterrender listener):
Ext.define('Mesclasses.objet.sticky',{
alias : ['widget.stick'],
extend : 'Ext.panel.Panel',
bodyStyle: {
background: 'yellow',
},
height : 150,
width : 150,
margin : '10 0 0 10',
draggable : true,
items: [{
xtype: 'label',
text : 'Title',
listeners : {
move : function(me,x,y,opt){
alert('move');
}
}
}],
listeners : {
afterrender : function(stick){
stick.dd = new Ext.dd.DDProxy(stick.el.dom.id, 'group');
}
}
});
Here is the render part you are mostly interested in (original page using ExtJS 3 though):
// runs after the window is rendered
,afterRender:function() {
// create items using template
Ext.Window.prototype.afterRender.apply(this, arguments);
this.tpl.overwrite(this.body, this);
// setup D&D
var items = this.body.select('div.draggable');
// loop through draggable items
items.each(function(el, ce, index) {
// create DDProxy
el.dd = new Ext.dd.DDProxy(el.dom.id, 'group');
// configure the proxy
Ext.apply(el.dd, {
win:this
,itemIndex:index
// runs on drag start
// create nice proxy and constrain it to body
,startDrag:function(x, y) {
var dragEl = Ext.get(this.getDragEl());
var el = Ext.get(this.getEl());
dragEl.applyStyles({border:'','z-index':this.win.lastZIndex + 1});
dragEl.update(el.dom.innerHTML);
dragEl.addClass(el.dom.className + ' dd-proxy');
this.constrainTo(this.win.body);
} // eo function startDrag
// runs on drag end
// save new position of item and fire itemdrag event to save state
,afterDrag:function() {
var el = Ext.get(this.getEl());
var div = this.win.divs[this.itemIndex];
div.x = el.getLeft(true);
div.y = el.getTop(true);
this.win.fireEvent('itemdrag', this);
} // eo function afterDrag
}) // eo apply
}, this); // eo each
} // eo function afterRender

Resources