Login Register

DND - howto get a created div into a source container?

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);

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:

// the creator function demands an argument
        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:

// widget creator function
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'

I tried to create 'dijit' widget inside nodecreator function. It works out fine for me. I am attaching the code. I hope this(or something very similar !) is what you were looking for . Seems the approach works well for dijit widget
<script type="text/javascript" src="dojo/dojo.js.uncompressed.js"
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.

// my Creator
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?