PDA

View Full Version : Sortable Elements/Tabs



bryall
8 Sep 2010, 5:14 AM
I've been trying to figure out a way to do this for the last few days and haven't come up with anything.

Is it possible to have sortable elements connected through tabs with extjs? I'd prefer not to use plugins, but even the ones I found don't appear to be as flexible as needed.

I'm looking for functionality similar to http://jqueryui.com/demos/sortable/#connect-lists-through-tabs

Thanks in advanced

Condor
8 Sep 2010, 5:29 AM
Yes, you can do that, but you would have to write the drag&drop implementation for tabs yourself.

I recommend reading this (http://www.sencha.com/blog/2009/09/13/5-steps-drag-and-drop-with-ext-js/) to familiarize yourself with how drag&drop works in Ext.

bryall
8 Sep 2010, 5:33 AM
Thanks for the reply Condor, I've read that article a few times and tried to implement everything I need but failed each time. I don't see extjs supporting sorting natively. I also don't see how I could set the tabs as drop zones because I'll never know the id of each tab.

Condor
8 Sep 2010, 5:39 AM
A tab is not a dropzone. The entire TabPanel strip is a dropzone.

You have to wait for the TabPanel render event and create the dropzone with the strip as el (you can also specify an element instead of an id).

Animal
8 Sep 2010, 6:00 AM
Weird UI where the two lists are artificially separated by being on different tabs, and the drop MUST be through the tab selector?

Smacks of making it just so just "because".

Surely a side-by-side implementation is more intuitive?

http://dev.sencha.com/deploy/dev/examples/multiselect/multiselect-demo.html

bryall
8 Sep 2010, 6:08 AM
Condor I was able to get the the individual tabs as drop targets, so that will definitely make this useful. My only other concern is with the sorting of elements. I need to be able to sort DIVs because we're going for a portlet effect, I looked at the extjs portlets but it appeared they need to be in portals which we can't have.

Animal - Unfortunately I'm not using this functionality as a list, but rather as ports being transferred between tabs. So the multi-select stuff won't do. I have a working model of this in jquery but obviously ExtJS is going to be our preferred library.

Animal
8 Sep 2010, 6:11 AM
So you are dragging/dropping Containers between tabs?

Condor
8 Sep 2010, 6:12 AM
Are you really using divs or are you actually dragging Ext components?

bryall
8 Sep 2010, 6:23 AM
Condor it'll be using divs not an ext component

Animal
8 Sep 2010, 6:28 AM
So the TabPanel strip el has a DropZone made out of it, and the getTargetFromEvent finds the tab selector <li> that you are over.

The tabs themselves should be DragZones.

I don't like the concept of having to register a DD object for every draggable item as that blog entry suggests!

See the http://dev.sencha.com/deploy/dev/examples/dd/dragdropzones.html example

It shows a single DragZone and a single DropZone

The DragZone handles multiple draggables.

bryall
8 Sep 2010, 8:32 AM
After playing with it for a while I came up with a solution using the Sortable plugin.

I'll post my code below in the event it becomes useful to somebody in the future.


Ext.onReady(function() {
Ext.QuickTips.init();

var sortDivs = [];

var tabs = new Ext.TabPanel({
renderTo: 'tabs1',
width:450,
activeTab: 0,
defaults:{autoHeight: true},
items:[
{contentEl:'script', itemId:'script', title: 'Short Text <span id="tab-id" style="display:none;">script</span>'},
{contentEl:'markup', itemId:'markup', title: 'Long Text <span id="tab-id" style="display:none;">markup</span>'}
]
});

Ext.each(Ext.select("#tabs1 ul li").elements, function(el) {
var otherDDTarget = new Ext.dd.DropTarget(el, {
ddGroup: 'stuff',
notifyDrop: function(dd, e, data) {
var elId = data.ddel.id;
var appDivId = Ext.select('#'+this.id+' #tab-id').first().dom.textContent;

Ext.get(elId).appendTo(Ext.select("#" + appDivId).first());

tabs.setActiveTab(appDivId);

initSort(appDivId);
}
});
});

var initSort = function initSort(nDiv) {
new Ext.ux.Sortable({
container : nDiv,
dragGroups : [
'stuff'
]
});
if(!checkSortDivs(nDiv)) {
sortDivs.push(nDiv);
}
}

var checkSortDivs = function checkSortDivs(nDiv) {
var result = false;
if(sortDivs.length > 0) {
for(var i=0;i<sortDivs.length;i++) {
if(sortDivs[i] === nDiv) {
result = true;
break;
}
}
}
return result;
}

initSort('stuff');
});

Animal
8 Sep 2010, 10:02 AM
What if you add more tabs to that TabPanel?

This is why a DropZone is better.

And how do you drag? create a DD for each draggable?

Again, what if you add more tabs?

This is why a DragZone is better.

steffenk
8 Sep 2010, 10:39 AM
We use this plugin since a long time, and it works very well:
http://www.sencha.com/forum/showthread.php?104900-Enhanced-Usage-Example-of-the-TabPanel-Component-with-Drag-amp-Drop

The plugin also supports dd for tabgroups.

22289

steffenk
8 Sep 2010, 10:43 AM
But for the initial question i'm also a bit disappointed that dd with components is "easy", but native dd with dom is a problem. i also tried to implement the listsort with plain ul in HTML, and what i miss is to show the proxy in DOM while drag, i even had problems to get the underlying element while drag, as i used the complete ul as dropzone.