Hi all,
(Relative noob here, all the usual apologies...)
On Dojo 0.9, I'm looking for the "right" way to get notification when a node is being moved via dojo.dnd.move (e.g, when I've wrapped it in a Moveable and now the framework is helpfully letting the user move it). Looking at move.js, I don't see any explicit notification being done during the move (like the global dndMoveStart and dndMoveStop events for start and stop).
For now, I've modified my copy of move.js to publish a global event -- dndMoveUpdate -- which tells me the node is being moved. This was a simple matter of adding a moveNode method to Mover and then using it instead of calling dojo.marginBox directly in the two places that's done in move.js. But am I missing a better, more fundamental way to get this information? Some event on the div itself, for instance, or...? I did try "onmove" without success. I'm using Firefox 2, but obviously looking for a Dojo cross-browser solution.
If I'm not missing it, I'll submit a trac report and patch with my move.js change, but again, being new to Dojo and to the more advanced parts of JavaScript and the DOM, I just suspect I'm headed the wrong way.
Thanks in advance,
--
T.J. Crowder
tj at crowder software dot com

Two topics are supported for
Two topics are supported for move operations: start and stop. At present time there is no notification on every shift of the move target. I didn't do it because of two reasons:
But I can be wrong. ;-) Why do you need this functionality?
You can always file an enhancement ticket but remember that in order to attach your patch you need to file a CLA (see Developer section on the left side of this page).
Thanks, so I'm not missing something?
Hi Eugene,
Thanks! Yes, I've already sent in my CLA.
So I'm not missing some more fundamental way to do this? As you say, it seems a bit expensive to do it in a global event if there's already some event somewhere that the browser is raising. But I didn't find one.
Use Cases - One place where I wanted this was that I had two divs, both wrapped in Moveables, with a connector line between them. When either div is being moved, I wanted the notification so I could move the connector line as well, since it looks sloppy to wait until the move stops.
Another place was this: I was considering a Netvibes-like UI, where you have squares of content the user can rearrange as desired, which snap into place. This didn't immediately seem like a place I could use the full drag-and-drop stuff with containers, not least because the snapping would be based on where the node being dragged seemed to be vs. where the cursor was, but I'm still thinking that through.
One approach that works with things as they are is to hook the start event and when you see something start moving that you're interested in, connect to the mousemove event for the node; on the stop event, if you've hooked in, disconnect the link. But interestingly, it's a lot less smooth than when the notification comes from move.js.
The way I did this in my quick-and-dirty stuff was through a third global event, but I'm not at all sure that's the best way to do it. Here are the options I've thought of so far:
It seems like if the global publish thing isn't very expensive, we risk over-egging it by trying to make it optional in the various ways above...
Any thoughts?
Thanks again,
--
T.J. Crowder
tj at crowdersoftware dot com
Custom mover
It looks like you need a custom mover. Look at dojo.dnd.constrainedMover to see how it can be done cheaply. If you need to combine the functionality of constrained mover with your custom functionality, the easiest thing you can do is to clone the existing mover textually adding new functionality along the way. In any case it is a valid use case. I'll think about possible chaining of movers functionality (task #3695).
Regarding Netvibes-like UI, it can be done with the regular (proper) DnD. The only thing needed is a special source, which can show ghosts of dragged nodes. I had this use case in mind when designing the DnD, but didn't have enough time to implement it. If you want to do it --- be my guest. It should be relatively simple to implement by overwriting onDndSourceOver() and onMouseOver() methods of a source object to insert node ghosts during the DnD operation.
Deriving Mover
Hi Eugene,
I accidentally responded to your note by replying to the thread, rather than to your note -- sorry about that, please see below if you haven't already.
I was looking into this further, and I see that Mover and the specialized versions of it (and Moveable, for that matter) are raw JavaScript objects rather than objects created via dojo.declare. Is that an aspect of beta, or a design decision? My idea was to have a moveNode method on Mover, and have a Mover subclass that overrode moveNode, calling the base version (to actually do the work) and then doing its notification. But that's a lot harder with raw objects than with Dojo objects...
Thanks in advance,
--
T.J. Crowder
tj at crowdersoftware dot com
For all intents and purposes
For all intents and purposes they are practically the same. You can derive from them using dojo.declare. If you want to call the base class method, you can do it directly:
dojo.declare("Derived", Base, { method: function(){ // let's call the base class method first Base.prototype.method.call(this); // now we can do our custom stuff } });The same way you can do it with dojo.extend:
Derived = function(){ /* constructor */ }; dojo.extend(Derived, Base.prototype); dojo.extend(Derived, { method: function(){ // let's call the base class method first Base.prototype.method.call(this); // now we can do our custom stuff } });So it is basically the same. dojo.declare adds more plumbing than that, but ultimately it is the same thing, and you can mix and match them.
It was not a conscientious design decision --- I use "raw" objects, when I don't need any conveniences provided by dojo.declare. Otherwise I use dojo.declare.
Actually there is schism about the way to define classes. Some people feel that "raw" classes are more JavaScript-onic way to do it instead of relying on some opaque functions (like dojo.declare). There are some subtle things which cannot be done with dojo.declare. So we didn't set a Dojo guideline for that.
Thanks, I had tried that...
...without success, because I was really confused about something. But I've figured it out now -- Mover is a class and can be extended as above (provided you get the constructor function right), but constrainedMover, parentConstrainedMover, and boxConstrainedMover are not. They're just factory functions that create and return an anonymous specialization of Mover, rather than defining prototypes that can be extended. (This anonymous specialization is created by constrainedMover, which is used by the others.) Attempting to extend them as above fails, for obvious reasons. :-)
And I think the reason for this is that Moveable constructs the mover, rather than the programmer using the API, and so this was the only way to pass arguments into these things that create specializations (for instance, with parentConstrainedMover, to tell it what bounding box -- contents, padding, margins, etc. -- to use).
FWIW, I think this is confusing for the user of the API -- certainly, I found it confusing. I'd rather have a Mover class that has methods ("moveNode", possibly "constrainBox", whatever), where I supply the actual Mover instance rather than its constructor to Moveable. This allows for full derivation, and for classes like ParentConstrainedMover that have parameters to their constructors. Right now, my only way to get the Mover that does feedback *and* get the parentConstrainedMover logic is to create my own function (not class) that gets an instance from the function parentConstrainedMover, then overrides the instance's moveNode method (the one I've added to Mover), and explicitly calls dojo.dnd.Mover.prototype.moveNode -- which is the only named version of that, since everything else is an anonymous specialization. I'd rather use a subclass and this.inherited(). I think it's clearer to the user of the API, and more flexible.
Easy to say. :-) But if you're open to something like that, I'd be happy to submit some suggested changes to move.js for consideration.
Thanks again,
--
T.J. Crowder
tj at crowder software dot com
I am open to suggestions
I am open to suggestions. If you have good ideas and signed the CLA, don't hesitate to share. This is the open source at its best and we will all benefit from powerful yet simple DnD.
There is one thing I started to entertain recently: mover modifiers. Right now Moveable takes a mover parameter, which is a constructor for a mover. In most cases changes to the mover are minimal, and the default one would do, if we allow to modify it after creation by user-supplied functions.
function ModifyMover(mover, event){ // add more methods to the mover object // replace existing methods of the mover }Such modifiers can be easily chained combining several effects together.
So in Moveable.onMouseDown() the creation of the mover will be changed to something like this (pseudo-code):
var mover = new this.mover(this.node, e); dojo.forEach(this.modifiers, function(modifier){ modifier.call(this, mover, e); }, this);It will allow to custom-wire the newly created mover from user-supplied functions augmenting its behavior in any possible way.
Will something like that work for you?
Probably...
...but would we be reinventing the inheritance wheel? :-)
I'll send a suggstion -- what's the best way to do that, a trac ticket and attach the modified file (or a diff) to it?
--
T.J. Crowder
tj at crowder software dot com
It's a shortcut...
Think of it as a shortcut, which provides a dynamic way to create the "inheritance" chain, which operates on per-instance basis rather than on per-class basis.
Yes
Inheritance isn't the only, and isn't always the best, way to enhance things...
-- T.J.
Ready
Hi,
I've now done four different versions of this, the first three of which served -- in various ways -- to prove the wisdom of your original design. :-) The fourth I'm fairly happy with. Just let me know how to send it on for consideration...
--
T.J. Crowder
tj at crowder software dot com
Attach files to #3695 and
Attach files to #3695 and don't forget to write an explanation.
The trac information is here: http://dojotoolkit.org/book/dojo-book-0-4/part-9-dojo-community/filing-b...
The ticket itself is here: http://trac.dojotoolkit.org/ticket/3695
Done
Attached to ticket #3695. I think it's a useful set of enhancements, I've put a comment on the ticket giving the details...
-- T.J.
[OT] Forum Markup
Okay, so how did you get the nifty markup on your JavaScript examples? I tried the <js>, <code>, etc. listed on the submit page without luck -- all they seem to do is preserve leading whitespace on lines. Looking at the link for more information about formatting options didn't seem to reveal anything. The list of allowed HTML wouldn't quite be up to it.... Is there a magic incantation? :-)
Thanks in advance,
--
T.J. Crowder
tj at crowdersoftware dot com
Its currently buggy...
The filters we use to prevent normal users from screwing with HTML tags... makes the filter for the code blocks break (it filters at the markup that it would colorize....) We are looking into alternative means of filtering HTML (or less stringent rules for it) to allow this to work for normal users... generally we go and edit posts to make the markup work if we see large code blocks.
-Karl
Ah, I get it
Thanks Karl,
--
T.J. Crowder
tj at crowdersoftware dot com
Just use in the Full HTML
Just use
in the Full HTML input mode. The downside: you have to put manually all peskytoo.
Full HTML...
Not allowed by normal users (security/site defacement risk)... I am working on making the filter compatible with the HTML filter so everyone can use it though.
-Karl
Mover changes
Hiya,
To do this properly in a Mover, I'll need to make one of my changes to centralize the actual movement of the node (currently it occurs in two places). In the code I've already done (which is trivial), this is just a new moveNode method on Mover which is used when appropriate. I'll do a trac entry and post a patch for your consideration...and get more up-to-speed with deriving classes, to prove it works. :-) I've already done custom movers (did one to contrain to the viewport rather than the parent), but that didn't get into any of the fun stuff like overriding methods.
Thanks again,
--
T.J. Crowder
tj at crowdersoftware dot com
Thanks
I know this thread is quite old, but I just like to thank you for that hacked version of move.js, its exactly what I was looking for :)
NP
Glad it's working for you, thanks for letting me know. I've had absolutely no response from any of the committers, which was less than ideal.
--
T.J. Crowder
tj at crowder software dot com