var c1;
c1 = new dojo.dnd.Source("container1");
var dndNode = dojo.doc.createElement("div");
dndNode.id = dojo.dnd.getUniqueId();
dojo.addClass(dndNode, "dojoDndItem");
dndNode.innerHTML = "Item <strong>A</strong>";
dojo.byId("container1").appendChild(dndNode);
c1 = new dojo.dnd.Source("container1");
var dndNode = dojo.doc.createElement("div");
dndNode.id = dojo.dnd.getUniqueId();
dojo.addClass(dndNode, "dojoDndItem");
dndNode.innerHTML = "Item <strong>A</strong>";
dojo.byId("container1").appendChild(dndNode);
when i try that in "dojotoolkit/dojo/tests/dnd/test_dnd.html" i get following error:
source.getItem(nodes[i].id) has no properties
what does the error mean and what can i do?
btw.. actually i want to get a widget into the container... but i get the same error when i try the small example above

You can use a node creator
You can use a node creator function and insertNodes(). A node creator is a function that knows how to add nodes to your source. (So it would make the div in your example above.) When you create your Source, you pass your node creator as a param. Then call insertNodes() on your Source, passing it any data that the node creator needs to make your nodes. Have a look at the flickr example:
http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/tests/dnd/flickr...
The book used to discuss the node creator, but it's been removed.
dnd.Source with default creator
I am trying to understand the default behaviour of dojo 0.9 dnd.
And I have a question about the defaut creator in dnd.Source. Why can't we easily add a dynamically created node to a dojo.dnd.Source ?
I have made this example :
dojo.require("dojo.parser"); // scan page for widgets and instantiate them dojo.require("dojo.dnd.source"); dojo.require("dijit.layout.ContentPane"); function init(){ var source= new dojo.dnd.Source("container1"); var div= dojo.doc.createElement("div"); div.innerHTML= "dynamic div"; source.insertNodes(false, [div]); } dojo.addOnLoad(init);
And I get as a result [object HTMLDivElement] text that I can drag, but I would have prefered the real node instead of text.
Is it planned to have an easy way to add DOM nodes to a dojo.dnd.Source ?
Regards,
That's why there a creator...
The node is not enough. DnD should know the logical type of the item to govern dragging and dropping. And usually nodes represent some data items, like database records, so you need to provide a mapping for that. With old DnD, which was node-based, people ended up attaching a bunch of custom properties to nodes to get this information. E.g., at some point you want to know how user rearranged a list, or what she selected in her shopping cart — that's where it all becomes interesting.
The creator returns an object with three members: node, data, and type. The data member is completely opaque, and it is up to you to interpret it. DnD guarantees, that it is carried around together with your visual representation. If you can derive data and type from a node, or you have some sensible defaults, you can easily write up a creator, which takes a node, and returns the required triplet. Just make sure that your nodes are compatible with a container, and you are not placing <th> inside of <span>. ;-)
"The book used to discuss
"The book used to discuss the node creator, but it's been removed."
I moved it here: http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-...
write your own creator
the default creator just makes sth like "toString()" and if u pass it a node, then it makes a "object HTMLDivElement" out of it
instead u should write your own creator... here is an "hello world" example:
var nodeCreator = function(item){
var node;
// doe whatever u wanna do... just make any markup
node = dojo.doc.createElement("div");
node.id = dojo.dnd.getUniqueId();
node.innerHTML = item;
// return the stuff
return {node: node, data: "whatever", type: []};
};
// here u link your own creator to the container
c1 = new dojo.dnd.Source("container1", {creator: nodeCreator});
// here u call the creator by passing an array of "items"
c1.insertNodes(null, ["hello", "world"]);
btw... big thx sbutler for helping out :)
but for a widget?
when i try to make this example above for a widget:
var widgetCreator = function(item){
// dndItem node containing the widget
var node = dojo.doc.createElement("div");
node.id = dojo.dnd.getUniqueId();
// node to be replaced by the widget
var replaceNode = dojo.doc.createElement("div");
replaceNode.id = "replaceNode";
// append replacement node to the dndItem node
node.appendChild(replaceNode);
// create the widget
var myCustomWidget = new foo.widget.Bar({ cacheContent: false }, "replaceNode");
// return the dndItem node containing the widget
return {node: node, data: "muh", type: ["kuh"]};
};
// create the dndSource "container1" and link it to the creator
c1 = new dojo.dnd.Source("container1", {creator: widgetCreator});
// call the creator once (only 1 item in the array)
c1.insertNodes(null, ["callTheWidgetJustOnce"]);
...then the widget is at the wished position and it is DND´able... but
1) it is invisible as long as i click any other item at "container1" (when i click the widget appears)
2) everytime i click anywhere at the browser, the whole website is refreshed
rly wondering y???
RE : but for a widget?
Thanks for your help matsuri,
This is exactly what I want to do, dynamically adding widgets in a dnd.source to make widgets dndable.
Any idea ?
There is a Dijit forum...
...where you should ask questions about widgets.
I tried to create 'dijit'
djConfig="parseOnLoad: true, isDebug: true"></script>
<script type="text/javascript">
dojo.require("dojo.dnd.source");
dojo.require("dijit.Dialog");
dojo.require("dojo.parser");
dojo.require("dijit.form.Button");
// widget creator function
var widgetCreator = function(item){
var node = dojo.doc.createElement("div");
node.id = dojo.dnd.getUniqueId();
var button1 = new dijit.form.Button({label: '<i>'+item+'</i>', onClick: function(){alert('hi')}});
node.appendChild(button1.domNode);
return {node: node, data: item, type: ["kuh"]};
};
function init()
{
// create the dndSource "container1" and link it to the creator
c1 = new dojo.dnd.Source("container1", {creator: widgetCreator,accept: ["kuh"]});
c2 = new dojo.dnd.Source("container2", {creator: widgetCreator,accept: ["kuh"]});
// call the creator once (only 1 item in the array)
c1.insertNodes(null, ["Say Hi Button"]);
c1.insertNodes(null, ["Say Hi Button"]);
c1.insertNodes(null, ["Say Hi Button"]);
}
dojo.addOnLoad(init);
</script>
<body>
<div id='container1' style="border:2px black; width: 200px;height:200px">fsdf</div>
<div id='container2' style="border:2px black;; width: 200px;height:200px" >fsdfsfsdf</div>
</body>
i dont know
@jfcunat: well.. i didnt spend more time on that problem, but if i know the solution, i will post it in this thread
@eugene: this problem touches both, dijits and dnd but the core problem is not how to call widgets dynamically... furthermore, its about how to handle the DND stuff
thanks ashish
your example works... great!
I need your help
Hi everbody,
I need your help! I tried to append dynamically some images to a DnD-source, but I get the error of the initial post.
var node_creator = function(data, hint) {
var image = dojo.doc.createElement("img");
dojo.connect(image, 'onmouseover', mouseOver);
dojo.connect(image, 'onmouseout', mouseOut);
dojo.connect(image, 'onmousedown', mouseDown);
dojo.connect(image, 'onmouseup', mouseUp);
image.src = data;
image.id = dojo.dnd.getUniqueId();
return {node: image, data: data, type: []};
};
c1 = new dojo.dnd.Source("sourceLayer1", {creator: node_creator, copyOnly: true});
function searchSlides() {
dojo.xhrGet({
url: "ajax.php",
handleAs: "json",
load: function(response, ioArgs) {
c1.selectAll();
c1.deleteSelectedNodes();
c1.clearItems();
c1.insertNodes(null, response);
return response;
}
});
}
Does anybody know, why?