I am working on code like the following.
01: var c1 = new dojo.dnd.Source('container1', {copyOnly:true}); // container1 is a div
02: var c2 = new dojo.dnd.Source('container2'); // container2 is a div
03: var list = [];
04: for (var i = 0; i < 3; i++) { list.push( dojo.create('div') ); }
05: c1.insertNodes(false, list);
06:
07: function checkDndCopy(nodes, target){
08: dojo.forEach(nodes, function(node){ alert(node.id); } );
09: }
10: dojo.subscribe("/dnd/drop", function(){
11: var mgr = dojo.dnd.manager();
12: checkDndCopy(mgr.nodes, mgr.target);开发者_JAVA技巧
13: });
The nodes inserted to the c1 at line 05 have id of "dojoUnique1, donoUnique2, dojoUnique3". On a event of drag and drop a node from c1 to c2, a onDndDrop event is fired and the subscribe method defined in line10-13 is invoked.
I expected that newly copied node appears in the nodes (for example) at line 08. But this is not true. When dojoUnique1 is target of drag and drop, nodes at line 08 contains only dojoUnique1.
I want to modify some attributes of newly copied nodes on the event of onDndDrop. Please let me know how such a thing is realized.
I'm not sure, if it is the only (and best) way, but you may write your own node creator to override dropped node and avatar creation. Example below extends your code and makes dropped nodes red:
var c1 = new dojo.dnd.Source('container1', {copyOnly:true }); // container1 is a div
var c2 = new dojo.dnd.Source('container2', { creator: nodeCreator } ); // container2 is a div
function nodeCreator(item, hint) {
var node = dojo.create("div", { innerHTML: item });
if (hint != "avatar") {
dojo.style(node, 'color', 'red');
}
return { node: node, data: item };
}
You can find more information about writing own creators here and in google
First, as a rule of thumb try to avoid using DnD topics especially for local things — they are cumbersome to use because by the time your function is called parameters can be modified or even destroyed by other processors (as you already discovered). Use local events and/or override methods. If you want to do something to newly inserted nodes just override onDrop
(or onDropExternal
, or onDropInternal
, if you want to handle only specific drops).
Another useful hint: newly inserted nodes are selected.
Let's code it up:
var c1 = new dojo.dnd.Source('container1', {copyOnly:true});
var c2 = new dojo.dnd.Source('container2');
// ...
// the decorator technique
function paintRed(source){
var old_onDrop = source.onDrop;
source.onDrop = function(){
// we don't care about actual parameters
// (we will pass them in bulk)
// let's do a drop:
old_onDrop.apply(this, arguments);
// now all dropped items are inserted and selected in c2
// let's iterated over all selected items:
this.forInSelectedItems(function(item, id){
// print the id
console.log(id);
// paint it red
dojo.style(id, "color", "red");
});
};
}
// now let's decorate c2
paintRed(c2);
// now c2 paints all dropped nodes red
If you allow to rearrange lists and want to do the modifications only for external drops (e.g., from c1 to c2), you should override onDropExternal
. The code will be the same.
Because this example doesn't rely on original items, you can do it with topics but you may need some extra code if you want to do it conditionally (e.g., for c2, but not c1). If you don't care about any other things, it is actually pretty easy too:
dojo.subscribe("/dnd/drop", function(source, nodes, copy, target){
// warning: by the time this function is called nodes
// can be copied/modified/destroyed --- do not rely on them!
// but we don't need them here
target.forInSelectedItems(function(item, id){
// print the id
console.log(id);
// paint it red
dojo.style(id, "color", "red");
});
});
Based on the way of using custom creator, I found following.
var d;
d = dojo.doc.createElement('div');
var c01 = new dojo.dnd.Source(d, { 'copyOnly': true, 'accept': [], 'creator': myCreator});
var arr = [];
for(i=0; i<3; i++){
d = dojo.create('div'); // dnd items
// define contents and properties of d
arr.push( d );
}
c01.insertNodes(false, divArr);
d = dojo.doc.createElement('div');
var c02 = new dojo.dnd.Source(d, { 'creator': myCreator});
function myCreator(item, hint){
var node = dojo.doc.createElement('div');
node.id = dojo.dnd.getUniqueId();
var mgr = dojo.dnd.manager();
// from dojo.dnd.manager(), it is possible to find which one to create
// the follwoing condition is just a sample
if(hint != 'avatar' &&
mgr.source && mgr.target // these are null when creating newly inserted one
mgr.source.node && mgr.target.node // by inspecting these nodes, one can know
// whether the item is newly copied one
){
dojo.style(node, 'color', 'red');
// one can get mouse position from mgr and set the node position
}
var copyItem = createCopyItem( item );
dojo.place(copyItem, node, 'last');
return { node: node, data: copyItem, type:[ /* what you want */ ] };
}
Function createCopyItem() is out of scope. It is necessary to copy item
and modify the new object because item
cannot be placed both under its original parentNode and under node
created in myCreator().
精彩评论