View Full Version : Docking layout?

5 Dec 2012, 11:43 AM
Does any sort of dockable layout functionality exist in ExtJS? Something like described here (http://blogs.telerik.com/blogs/posts/08-07-25/beta-version-of-rad-controls-for-silverlight-2-available.aspx). Even something third-party or in plugin form is fine.


7 Dec 2012, 8:09 AM
You mean the ability when you drag to use arrow buttons?

7 Dec 2012, 8:36 AM
I mean the ability to dock windows in a user-defined configuration, as shown in the screenshot, as in Visual Studio, and Eclipse.

The arrows are helpful but just one way of dealing with this this. Eclipse uses a different method. The method doesn't matter.

10 Dec 2012, 9:00 PM
I would call this not pretty at all and not efficient and not reusable, but maybe a start?
Lets you drag a toolbar from side to side to side and re-dock it (with its owning container only).


Ext.widget('panel', {
renderTo: Ext.getBody()
, title: 'User defined docking'
, height: 350
, width: 350
, dockedItems: [{
xtype: 'toolbar'
, dock: 'top'
, items: [{
text: 'test button'
, listeners: {
afterrender: function (tb) {
var proxy
, tbOwner = tb.ownerCt;

function getProxy() {
if (!proxy) {
proxy = tb.ownerCt.el.createChild({
tag: 'div'
, html: '<div style="width:50px;height:50px;background-color:rgba(15,15,15,.5);"></div>'
//, html: 'some drag text'
return proxy;

tb.tracker = new Ext.create('Ext.dd.DragTracker', {
el: tb.el
, dir: false
, tolerance: 10
, onStart: function () {
var p = getProxy();
, onDrag : function () {
var threshold = 90;
var x = this.getXY()[0];
var y = this.getXY()[1];
var LEFT = x - tbOwner.el.getLeft();
var TOP = y - tbOwner.el.getTop() - tbOwner.header.el.getHeight();
var RIGHT = tbOwner.el.getWidth() - x + tbOwner.el.getLeft();
var BOTTOM = tbOwner.el.getHeight() - y + tbOwner.el.getTop();

tbOwner.removeDocked(tb, false);

this.dir = false;

if (TOP < threshold) { this.dir = 'top'; }
if (RIGHT < threshold) { this.dir = 'right'; }
if (LEFT < threshold) { this.dir = 'left'; }
if (BOTTOM < threshold) { this.dir = 'bottom'; }

if (this.dir !== false) {
var indicators = tbOwner.query('[myCtType="indicator"]');
Ext.each(indicators, function (ind) {
if (ind.dock != this.dir) { tbOwner.removeDocked(ind, true); }
var exists = tbOwner.down('#temp-ind-' + this.dir);

if (!exists) {
xtype: 'container'
, myCtType: 'indicator'
, itemId: 'temp-ind-' + this.dir
, dock: this.dir
, height: (this.dir == 'top' || this.dir == 'bottom') ? 40 : undefined
, width: (this.dir == 'top' || this.dir == 'bottom') ? undefined : 40
, style: {
background: 'yellow'
, border: '1px solid red'

Ext.apply(this.dragRegion, {
top: this.getXY()[1] - 25
, left: this.getXY()[0] - 25
//, right: 300
//, bottom: -50

var bd = tbOwner.body.getRegion();
bd.right = bd.right - 50;
bd.bottom = bd.bottom - 50;

, onEnd : function () {
getProxy().hide({ duration: 150 });

tb.dock = this.dir;

var indicators = tbOwner.query('[myCtType="indicator"]');
Ext.each(indicators, function (ind) {
tbOwner.removeDocked(ind, true);

10 Dec 2012, 9:32 PM
Very cool man! Definitely a good start.

10 Dec 2012, 9:36 PM
This always seemed like a cool thing to have - that and tear-away tabs, but I'd just not taken the time to start trying to put something like it together.

10 Dec 2012, 10:13 PM
I've seen a tear-away tab plugin for ExtJS 3 where you can re-dock tabs to other tab panels or undock them into their own windows. It wasn't perfect, but it was pretty darn good.

10 Dec 2012, 10:33 PM
The problem with the tab ripping is a lot of the behaviour is going to be app dependent, so it's difficult to implement in a generic manner.

I'd agree that something similar to what @slemmon implemented would make for a nifty official example one day.

11 Dec 2012, 11:13 PM
Still tinkering, but here's what I've got to date:

Now it's a plugin that's applied per draggable docked item.

Stuff I'd like to still do (or figure out):
Optional CSS config for the container
Optional indicator config (draw path, fill color, stroke color, etc.)
In the config pass in participating containers for the drop
Indicate drops not only by edge, but as inserts between existing other docked items
Optional delegate for drag handling
Prevent drag when not dragged from the root el / delegate handler
Allow tear away to floating container/window
Optional config/CSS for the drag proxy
Opt-in participating drag locations per container (i.e. ['top', 'bottom'])
Give some indication on the drag proxy what sides are opted in for the given container
Sort out the border stuff per docked item once re-docked
Figure out how to re-orient items on a vertical toolbar when originally horizontal (and visa versa)
Have this work for tabs in a tab.Bar component (or maybe that's another whole plugin)

But now I must sleep instead.

16 Dec 2012, 12:42 AM
Still not final, but here's my progress to date:

Only the top toolbar is draggable and only if you start dragging from the toolbar itself, not an item on the toolbar (so it doesn't interfere with things like sliders, though I think I'll have an opt-out config for that at some point).
You can now drag and drop on all edges and even between other existing docked items.
You can specify a redockGroup on a container as well as in the plugin and the dragged docked item will be dockable in the participating container.
You can specify which sides are dockable using redockEdges as a config on the container. Omitting the config enables all 4 sides.

All the functionality isn't there like I want it, yet, and there are some bugs. Including a bug I believe I found with addDocked when you specify a position - but need to test more and with 4.2 beta before reporting it.

16 Dec 2012, 10:03 AM
Very cool, guys!

16 Dec 2012, 5:08 PM
Ok. Probably where I'll end with this one. Needs some finessing and some optional CSS configs and such and maybe some custom events, but works.