PDA

View Full Version : Extending Layouts?



sdt6585
5 Jul 2012, 1:55 PM
I've been trying to create a different layout similar to column layout, but I would like to avoid just floating all the elements since it leaves a lot of gaps when using field sets (jsfiddle (http://jsfiddle.net/sdt6585/NzsMg/8/embedded/result/)). I attempted to extend Ext.layout.container.Container and have more or less got the result I wanted (jsfiddle (http://jsfiddle.net/sdt6585/NzsMg/7/embedded/result/)), but I'm fairly sure that there must be a better way of doing it. Essentially all I'm doing right now is allowing the default behavior on the container to go off as normal, then taking all the dom elements, getting their max width, and creating however many columns can fit on the screen at that width. Finally, I just move all the dom elements to the shortest column in a loop. From reading the docs and perusing the stack during a layout, I think I'm correct in understanding that the layouts are supposed to be done on a cached dom object (context item?) to be committed after the layout process is complete. I would rather do this than let it all render then manipulate the dom directly. I attempted to override calculate in my layout to do so, but I can't figure out how to accurately predict the size of the component I'm rendering into and am probably missing something else since it just turns out strangely if I don't clean it up after it's rendered. If anyone has any tips, I would be most appreciative.

Here's my code, just comment out the last line of code "this.optimizeColumns();" to see the behavior using calculate, or if it's easier, jsfiddle (http://jsfiddle.net/sdt6585/NzsMg/9/).



Ext.define('Ext.ux.layout.container.Stack', {


extend: 'Ext.layout.container.Container',
alias: ['layout.ux.stack'],


type: 'stack',


constructor: function (config) {
var margin = config.margin || 0;
config.margin = undefined;
this.callParent(arguments);
this.margin = margin;
},


shortestColumn: function (columns) {
var index = 0;
var minHeight = columns[0].getHeight();
for (var i = 1, l = columns.length; i < l; i++) {
if (columns[i].getHeight() < minHeight) {
index = i;
minHeight = columns[i].getHeight();
}
}
return columns[index];
},


calculate: function (ownerContext) {
//Remove old divs
var divs = ownerContext.el.query('/div[@class="stack-col"]');
for (var i = 0, l = divs.length; i < l; i++) {
divs[i].remove();
}


//Find owner body
var body;
if (this.owner.getXType() === 'panel' ||
this.owner.getXType() === 'form') {
var el = ownerContext.el;
body = el.query('/div')[1];
} else {
body = ownerContext.el;
}


//Get Items
var items = ownerContext.childItems;
var itemEls = [];
var colWidth = 0;
//Get item elements and find max width
for (var i = 0, l = items.length; i < l; i++) {
var item = items[i];
//Max Width
var itemWidth = item.getStyle('width') + item.getMarginInfo().width;
if (itemWidth > colWidth) {
colWidth = itemWidth;
}
//Get reference
itemEls[i] = item.el;
}


//Create Columns
var columns = [];
var colCount = parseInt(this.owner.getWidth() / colWidth);
if (colCount === 0) {
colCount = 1;
}
for (var i = 0; i < colCount; i++) {
columns[i] = Ext.DomHelper.append(body,
'<div class="stack-col" style="margin: 0 ' + this.margin + 'px; float: left; width: ' + colWidth + 'px;"></div>',
true);
}
//Add items to columns
for (var i = 0, l = itemEls.length; i < l; i++) {
//Put it in the shortest column
var column = this.shortestColumn(columns);
column.appendChild(itemEls[i]);
}
},


optimizeColumns: function () {
console.log('Owner: ', this.owner);
//Find owner body
var body;
if (this.owner.getXType() === 'panel') {
var el = this.owner.getEl();
body = el.query('/div')[1];
console.log(body);
} else {
body = this.owner.getEl();
}


//Get Items
var items = this.owner.items.items;
var itemEls = [];
var colWidth = 0;
//Get item elements and find max width
for (var i = 0, l = items.length; i < l; i++) {
var item = items[i];
//Max Width
if (item.getOuterSize().width > colWidth) {
colWidth = item.getWidth();
}
//Get reference
itemEls[i] = item.getEl();
}


//Create Columns
var columns = [];
var colCount = parseInt(this.owner.getWidth() / colWidth);
if (colCount === 0) {
colCount = 1;
}
for (var i = 0; i < colCount; i++) {
columns[i] = Ext.DomHelper.append(body,
'<div cls="stack-col" style="margin: 0 ' + this.margin + 'px; float: left; width: ' + colWidth + 'px;"></div>',
true);
}
//Add items to columns
for (var i = 0, l = itemEls.length; i < l; i++) {
//Put it in the shortest column
var column = this.shortestColumn(columns);
column.appendChild(itemEls[i]);
}
},


finishedLayout: function (ownerContext) {
this.callParent(arguments);
this.optimizeColumns();
}
});