rdowling
10 Apr 2012, 6:28 AM
I am trying to create a draggable grid inside of a TabPanel item inside of a TabPanel inside of a Viewport (Viewport > TabPanel > items[] > gridpanel), bound by the fullpage TabPanel container. I could put the following grid panels into windows, getting draggability out of the box, and then add this window to a TabPanel, but the Extjs4 layout documentation seems to explicitly warn against this: "Overnesting is a common problem. An example of overnesting occurs when a GridPanel is added to a TabPanel by wrapping the GridPanel inside a wrapping Panel (that has no layout specified) and then add that wrapping Panel to the TabPanel. The point to realize is that a GridPanel is a Component which can be added directly to a Container."
-- Note: Data and example code heavily lifted from sencha designed example I put together; pls ignore that the grids are empty. --
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="/ext/resources/css/ext-all.css" />
<script src="/ext/bootstrap.js"></script>
<script type="text/javascript">
Ext.onReady( function() {
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
items:
[
{ xtype: 'tabpanel',
activeTab: 0,
items:
[
{ xtype: 'panel',
title: 'Tab 1',
items:
[
{ xtype: 'gridpanel',
title: 'Grid Panel One',
closable: true,
collapsible: true, animCollapse: true,
resizable: true,
constrain: true,
headerPosition: 'top',
height: 300,
width: 500,
draggable: true,
columns:
[
{ xtype: 'gridcolumn',
text: 'String'
},
{ xtype: 'numbercolumn',
text: 'Number'
},
{ xtype: 'datecolumn',
text: 'Date'
},
{ xtype: 'booleancolumn',
text: 'Boolean'
}
],//columns
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ptype: 'gridviewdragdrop'
})
]//plugins
}//viewConfig
},//gridpanel1
{ xtype: 'gridpanel',
title: 'Grid Panel Two',
closable: true,
collapsible: true, animCollapse: true,
resizable: true,
constrain: true,
headerPosition: 'top',
height: 300,
width: 500,
draggable: true,
columns:
[
{ xtype: 'gridcolumn',
text: 'String'
},
{ xtype: 'numbercolumn',
text: 'Number'
},
{ xtype: 'datecolumn',
text: 'Date'
},
{ xtype: 'booleancolumn',
text: 'Boolean'
}
],//columns
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ptype: 'gridviewdragdrop'
})
]//plugins
}//viewConfig
} //gridpanel
]//tabpanel1.items[]
},//tabpanel1
{ xtype: 'panel',
title: 'Tab 2'
},//tabpanel2
{ xtype: 'panel',
title: 'Tab 3'
}//tablpanel3
]//tabpanel.items[]
}//tabpanel
]//Viewport.items[]
});//Viewport
});//onReady
</script>
</head>
<body>
</body>
</html>
This code results in a grid that is draggable (clickable and draggable), but snaps back into the original position as it's dropped (unclicked). What's the best way forward, from a code-to-work as well as a best-practice (if I'm reading the Extjs cautioning I quoted above)? Taking a look at the Window source, I could add the code below to DD, but that does not seems appropriate here (i.e. I am creating a default Grid class to inherit my components from):
initDraggable: function() {
var me = this,
ddConfig;
if (!me.header) {
me.updateHeader(true);
}
/*
* Check the header here again. If for whatever reason it wasn't created in
* updateHeader (preventHeader) then we'll just ignore the rest since the
* header acts as the drag handle.
*/
if (me.header) {
ddConfig = Ext.applyIf({
el: me.el,
delegate: '#' + me.header.id
}, me.draggable);
// Add extra configs if Window is specified to be constrained
if (me.constrain || me.constrainHeader) {
ddConfig.constrain = me.constrain;
ddConfig.constrainDelegate = me.constrainHeader;
ddConfig.constrainTo = me.constrainTo || me.container;
}
me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']);
}
}
Is there a mixin available that I'm not aware of, or if not would it be appropriate to create a mixin from the above code?
-- Note: Data and example code heavily lifted from sencha designed example I put together; pls ignore that the grids are empty. --
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="/ext/resources/css/ext-all.css" />
<script src="/ext/bootstrap.js"></script>
<script type="text/javascript">
Ext.onReady( function() {
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
items:
[
{ xtype: 'tabpanel',
activeTab: 0,
items:
[
{ xtype: 'panel',
title: 'Tab 1',
items:
[
{ xtype: 'gridpanel',
title: 'Grid Panel One',
closable: true,
collapsible: true, animCollapse: true,
resizable: true,
constrain: true,
headerPosition: 'top',
height: 300,
width: 500,
draggable: true,
columns:
[
{ xtype: 'gridcolumn',
text: 'String'
},
{ xtype: 'numbercolumn',
text: 'Number'
},
{ xtype: 'datecolumn',
text: 'Date'
},
{ xtype: 'booleancolumn',
text: 'Boolean'
}
],//columns
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ptype: 'gridviewdragdrop'
})
]//plugins
}//viewConfig
},//gridpanel1
{ xtype: 'gridpanel',
title: 'Grid Panel Two',
closable: true,
collapsible: true, animCollapse: true,
resizable: true,
constrain: true,
headerPosition: 'top',
height: 300,
width: 500,
draggable: true,
columns:
[
{ xtype: 'gridcolumn',
text: 'String'
},
{ xtype: 'numbercolumn',
text: 'Number'
},
{ xtype: 'datecolumn',
text: 'Date'
},
{ xtype: 'booleancolumn',
text: 'Boolean'
}
],//columns
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ptype: 'gridviewdragdrop'
})
]//plugins
}//viewConfig
} //gridpanel
]//tabpanel1.items[]
},//tabpanel1
{ xtype: 'panel',
title: 'Tab 2'
},//tabpanel2
{ xtype: 'panel',
title: 'Tab 3'
}//tablpanel3
]//tabpanel.items[]
}//tabpanel
]//Viewport.items[]
});//Viewport
});//onReady
</script>
</head>
<body>
</body>
</html>
This code results in a grid that is draggable (clickable and draggable), but snaps back into the original position as it's dropped (unclicked). What's the best way forward, from a code-to-work as well as a best-practice (if I'm reading the Extjs cautioning I quoted above)? Taking a look at the Window source, I could add the code below to DD, but that does not seems appropriate here (i.e. I am creating a default Grid class to inherit my components from):
initDraggable: function() {
var me = this,
ddConfig;
if (!me.header) {
me.updateHeader(true);
}
/*
* Check the header here again. If for whatever reason it wasn't created in
* updateHeader (preventHeader) then we'll just ignore the rest since the
* header acts as the drag handle.
*/
if (me.header) {
ddConfig = Ext.applyIf({
el: me.el,
delegate: '#' + me.header.id
}, me.draggable);
// Add extra configs if Window is specified to be constrained
if (me.constrain || me.constrainHeader) {
ddConfig.constrain = me.constrain;
ddConfig.constrainDelegate = me.constrainHeader;
ddConfig.constrainTo = me.constrainTo || me.container;
}
me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']);
}
}
Is there a mixin available that I'm not aware of, or if not would it be appropriate to create a mixin from the above code?