PDA

View Full Version : DataView Drag and Drop in tree?



danielbertini
15 Oct 2010, 5:11 PM
Hello, is possible drag items from dataview and drop in tree?
I have this code:



folders = new Ext.tree.TreePanel({
useArrows: false,
autoScroll: true,
animate: true,
enableDD: true,
containerScroll: true,
border: false,
dataUrl: base_url+'cms/folder/getDir',
root: {
nodeType: 'async',
text: 'Raiz',
draggable: false,
id: '0',
iconCls: 'rootnode'
},
dropConfig:{
onNodeDrop: function(n, dd, e, data){
var node_from = data.node;
var node_from_id = node_from.attributes.id;
var node_from_text = node_from.attributes.text;
var node_to = n.node;
var node_to_id = node_to.attributes.id;
var node_to_text = node_to.attributes.text;
updateParent(node_from, node_from_id, node_from_text, node_to, node_to_id, node_to_text);
return true;
}
},
listeners:{
click:function(n){
var add_button = Ext.getCmp('folder-add-button');
var edit_button = Ext.getCmp('folder-edit-button');
var remove_button = Ext.getCmp('folder-remove-button');
node_selected = n.attributes.id;
if(n.attributes.id!='0'){
edit_button.enable();
remove_button.enable();
}
else{
edit_button.disable();
remove_button.disable();
}
}
},
tbar: new Ext.Toolbar({
enableOverflow: true,
items:[
{text:'Adicionar', id:'folder-add-button', disabled:false, iconCls:'add', handler:function(){ loadApplication(base_url+'cms/folderAdd', 'app-folder-add'); }}, '-',
{text:'Editar', id:'folder-edit-button', disabled:true, iconCls:'edit', handler:function(){ loadApplication(base_url+'cms/folderEdit', 'app-folder-edit'); }}, '-',
{text:'Remover', id:'folder-remove-button', disabled:true, iconCls:'remove', handler:function(){ action('remove'); }}
]
})
});

folders.getRootNode().expand();

var navWest = new Ext.Panel({
title: 'Pastas',
region: 'west',
split: true,
layout: 'fit',
width: 220,
minSize: 220,
maxSize: 400,
collapsible: true,
margins: '5 0 5 5',
cmargins: '5 5 5 5',
items: [folders]
});



var xd = Ext.data;

var store = new Ext.data.JsonStore({
url: base_url+'cms/folder/getImages',
baseParams: {folder_id:node_selected},
remoteSort: true,
autoLoad: true,
autoDestroy: true,
fields:[
{name:'id'},
{name:'name'}
]
});

var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<div class="thumb"><img src="'+base_url+'imagemanager/{name}"></div>',
'</div>',
'</tpl>',
'<div class="x-clear"></div>'
);

var navCenter = new Ext.Panel({
title: 'Imagens',
region: 'center',
margins: '5 5 5 0',
cmargins: '5 5 5 5',
autoScroll: true,
id: 'images-view',
bodyStyle: 'padding-bottom:10px;',
items: new Ext.DataView({
store: store,
tpl: tpl,
autoHeight: true,
enableDD: true,
layout: 'fit',
multiSelect: true,
overClass: 'x-view-over',
itemSelector: 'div.thumb-wrap',
emptyText: 'Nenhuma imagem encontrada.',
listeners: {
selectionchange: {
fn: function(dv,nodes){
var l = nodes.length;
var s = l > 1 ? 's' : '';
if(l==1){
navCenter.setTitle('Imagens ('+l+' selecionada'+s+')');
}
else{
navCenter.setTitle('Imagens (Nenhuma selecionada)');
}
if(l>=1){
navCenter.setTitle('Imagens ('+l+' selecionada'+s+')');
}
else{
navCenter.setTitle('Imagens (Nenhuma selecionada)');
}
}
}
}
}),
prepareData:function(data){
data.shortName = Ext.util.Format.ellipsis(data.name, 12);
return data;
},
tbar: new Ext.Toolbar({
enableOverflow: true,
items:[
{text:'Enviar', id:'upload-add-button', disabled:false, iconCls:'upload', handler:function(){ loadApplication(base_url+'cms/cms/upload', 'app-upload-add'); }}
]
})
});

var container = new Ext.Container({
layout: 'border',
items: [navWest,navCenter]
});

Animal
15 Oct 2010, 11:00 PM
Yes. Create a DragZone which upon mousedown, identifies which DataView node is being mousedowned upon, and "loads" the DD object with the associated Record data to then be accessed in your TreePanel.

This is illustrated in the examples in your examples directory examples/dragdropzones.html. It is very fulsomely commented if you click the "View Source" button.

The docs have been worked on to explain things, so take a read through the DragZone API.

danielbertini
27 Oct 2010, 6:29 AM
Hello Animal!

Get it to work following the example, but only works if I disable settings dropConfig the tree, the problem is that necessary to make the items in DateView be draggable to the folders and folders can also be moved into other folders.

You know how I can fix this?
Thanks!



node_selected = 0;
total_progress = 0;

folders = new Ext.tree.TreePanel({
useArrows: false,
autoScroll: true,
animate: true,
enableDD: true,
ddGroup: 'organizerDD',
containerScroll: true,
border: false,
dataUrl: base_url+'cms/folder/getDir',
root: {
nodeType: 'async',
text: 'Raiz',
id: '0',
iconCls: 'rootnode'
},
/*
dropConfig:{
onNodeDrop: function(n, dd, e, data){
var node_from = data.node;
var node_from_id = node_from.attributes.id;
var node_from_text = node_from.attributes.text;
var node_to = n.node;
var node_to_id = node_to.attributes.id;
var node_to_text = node_to.attributes.text;
updateParent(node_from, node_from_id, node_from_text, node_to, node_to_id, node_to_text);
return true;
}
},
*/
listeners:{
click:function(n){
var add_button = Ext.getCmp('folder-add-button');
var edit_button = Ext.getCmp('folder-edit-button');
var remove_button = Ext.getCmp('folder-remove-button');
node_selected = n.attributes.id;
if(n.attributes.id!='0'){
edit_button.enable();
remove_button.enable();
}
else{
edit_button.disable();
remove_button.disable();
}
store.load({params:{start:0, limit:9999, folder_id:n.attributes.id}});
store.on('load', function(){ n.expand(); msg.hide(); });
}
},
tbar: new Ext.Toolbar({
enableOverflow: true,
items:[
{text:'Adicionar', id:'folder-add-button', disabled:false, iconCls:'add', handler:function(){ loadApplication(base_url+'cms/folderAdd', 'app-folder-add'); }}, '-',
{text:'Editar', id:'folder-edit-button', disabled:true, iconCls:'edit', handler:function(){ loadApplication(base_url+'cms/folderEdit', 'app-folder-edit'); }}, '-',
{text:'Remover', id:'folder-remove-button', disabled:true, iconCls:'remove', handler:function(){ action('remove'); }}
]
})
});

folders.getRootNode().expand();

var navWest = new Ext.Panel({
title: 'Pastas',
region: 'west',
split: true,
layout: 'fit',
width: 220,
minSize: 220,
maxSize: 400,
collapsible: true,
margins: '5 0 5 5',
cmargins: '5 5 5 5',
items: [folders]
});

var xd = Ext.data;

store = new Ext.data.JsonStore({
url: base_url+'cms/folder/getImages',
baseParams: {folder_id:node_selected},
remoteSort: true,
autoLoad: true,
autoDestroy: true,
fields:[
{name:'id'},
{name:'name'}
]
});

var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<div class="thumb"><img src="'+base_url+'imagemanager/{name}"></div>',
'</div>',
'</tpl>',
'<div class="x-clear"></div>'
);

var view = new Ext.DataView({
id: 'images-view-data',
store: store,
tpl: tpl,
autoHeight: true,
enableDD: true,
layout: 'fit',
multiSelect: true,
overClass: 'x-view-over',
itemSelector: 'div.thumb-wrap',
loadingText: 'Pesquisando imagens...',
plugins: new Ext.DataView.DragSelector({dragSafe:true}),
listeners: {
selectionchange: {
fn: function(dv,nodes){
var l = nodes.length;
var s = l > 1 ? 's' : '';
if(l==1){
navCenter.setTitle('Imagens ('+l+' selecionada'+s+')');
}
else{
navCenter.setTitle('Imagens (Nenhuma selecionada)');
}
if(l>=1){
navCenter.setTitle('Imagens ('+l+' selecionada'+s+')');
Ext.getCmp('image-delete').enable();
}
else{
navCenter.setTitle('Imagens (Nenhuma selecionada)');
Ext.getCmp('image-delete').disable();
}
}
}
}
});

var navCenter = new Ext.Panel({
id: 'images-view',
title: 'Imagens',
region: 'center',
margins: '5 5 5 0',
cmargins: '5 5 5 5',
autoScroll: true,
bodyStyle: 'padding-bottom:10px;',
items: [view],
prepareData:function(data){
data.shortName = Ext.util.Format.ellipsis(data.name, 12);
return data;
},
tbar: new Ext.Toolbar({
enableOverflow: true,
items:[
{text:'Enviar', id:'image-upload', disabled:false, iconCls:'upload', handler:function(){ loadApplication(base_url+'cms/cms/upload', 'app-upload-add'); }}, '-',
{text:'Remover', id:'image-delete', disabled:true, iconCls:'remove', handler:function(){ deletePicture(); }}
]
})
});

var container = new Ext.Container({
layout: 'border',
items: [navWest,navCenter]
});

dashboard.add({ id:'imageManager', title:'Gerenciador de Imagens', iconCls:'imagemanager', items:container, layout:'fit', closable:true }).show();

function updateParent(node_from, node_from_id, node_from_text, node_to, node_to_id, node_to_text){
if(node_from_id != node_to_id){
if(node_from_id != 0){
Ext.Msg.show({
title:'Aviso:',
msg:'Tem certeza que deseja mover a pasta <b>'+node_from_text+'</b> para <b>'+node_to_text+'</b>?',
buttons:Ext.Msg.YESNO,
fn:function(btn){
if(btn=='yes'){
var mask = Ext.MessageBox.wait('Por favor, aguarde...', 'Movendo');
Ext.Ajax.request({
params:{
node_from_id:node_from_id,
node_to_id:node_to_id
},
url:base_url+'cms/folder/updateParent',
method: 'post',
success: function(form,action){
node_id = 0;
node_from.remove();
node_to.reload();
Ext.getCmp('folder-edit-button').disable();
Ext.getCmp('folder-remove-button').disable();
mask.hide();
},
failure: function(form,action){
mask.hide();
switch (action.failureType) {
case Ext.form.Action.CLIENT_INVALID:
Ext.Msg.alert('Erro:', 'Ocorreu uma falha de comunicação com o cliente/servidor. Tente novamente, caso o erro persista entre em contato com o atendimento.');
break;
case Ext.form.Action.CONNECT_FAILURE:
Ext.Msg.alert('Erro:', 'Ocorreu uma falha de conexão. Tente novamente, caso o erro persista entre em contato com o atendimento.');
break;
case Ext.form.Action.SERVER_INVALID:
Ext.Msg.alert('Erro:', 'Ocorreu uma falha no sistema. Reporte este problema ao atendimento.');
break;
default:
Ext.Msg.alert('Erro:', 'Ocorreu uma falha no sistema. Reporte este problema ao atendimento.');
}
}
});

}
}
});
}
}
}

function deletePicture(){
var view = Ext.getCmp('images-view-data');
var records = view.getSelectedRecords();
var total = records.length;
if(total==1){ var msg = 'Tem certeza que deseja remover esta imagem? '; } else { var msg = 'Tem certeza que deseja remover estas imagens? '; }
Ext.Msg.show({
title: 'Aviso:',
msg: msg,
buttons: Ext.Msg.YESNO,
fn: function(btn){
if(btn=='yes'){
var ids = '';
Ext.each(records, function(i){
ids += i.get('id') + ',';
});
var mask = Ext.MessageBox.wait('Por favor, aguarde...', 'Removendo');
Ext.Ajax.request({
url:base_url+'cms/image/delete',
method:'post',
params:{ids:ids},
success: function(result, action){
store.reload();
mask.hide();
}
});
}
}
});
}

ImageDragZone = function(view, config){
this.view = view;
ImageDragZone.superclass.constructor.call(this, view.getEl(), config);
};
Ext.extend(ImageDragZone, Ext.dd.DragZone, {
// We don't want to register our image elements, so let's
// override the default registry lookup to fetch the image
// from the event instead
getDragData : function(e){
var target = e.getTarget('.thumb-wrap');
if(target){
var view = this.view;
if(!view.isSelected(target)){
view.onClick(e);
}
var selNodes = view.getSelectedNodes();
var dragData = {
nodes: selNodes
};
if(selNodes.length == 1){
dragData.ddel = target;
dragData.single = true;
}else{
var div = document.createElement('div'); // create the multi element drag "ghost"
div.className = 'multi-proxy';
for(var i = 0, len = selNodes.length; i < len; i++){
div.appendChild(selNodes[i].firstChild.firstChild.cloneNode(true)); // image nodes only
if((i+1) % 3 == 0){
div.appendChild(document.createElement('br'));
}
}
var count = document.createElement('div'); // selected image count
count.innerHTML = i + ' imagens selecionadas';
div.appendChild(count);

dragData.ddel = div;
dragData.multi = true;
}
return dragData;
}
return false;
},

// this method is called by the TreeDropZone after a node drop
// to get the new tree node (there are also other way, but this is easiest)
getTreeNode : function(){
var treeNodes = [];
var nodeData = this.view.getRecords(this.dragData.nodes);
for(var i = 0, len = nodeData.length; i < len; i++){
var data = nodeData[i].data;
treeNodes.push(new Ext.tree.TreeNode({
text: data.name,
icon: '../view/'+data.url,
data: data,
leaf:false,
cls:'image-node'
}));
}
return treeNodes;
},

// the default action is to "highlight" after a bad drop
// but since an image can't be highlighted, let's frame it
afterRepair:function(){
for(var i = 0, len = this.dragData.nodes.length; i < len; i++){
Ext.fly(this.dragData.nodes[i]).frame('#8db2e3', 1);
}
this.dragging = false;
},

// override the default repairXY with one offset for the margins and padding
getRepairXY : function(e){
if(!this.dragData.multi){
var xy = Ext.Element.fly(this.dragData.ddel).getXY();
xy[0]+=3;xy[1]+=3;
return xy;
}
return false;
}
});

var dragZone = new ImageDragZone(view, {
containerScroll:true,
ddGroup: 'organizerDD'
});