[Infusion-users] Layout Reorderer: afterMoveCallbackUrl compatible afterMove function?

Antranig Basman Antranig.Basman at colorado.edu
Sun Nov 22 04:37:52 UTC 2009

Hi there Chris - thanks for this excellent question.
One line of help is the 3rd argument to the afterMove callback - this 
consists of a jQuery containing the movable DOM elements of your 
Reorderer in their current DOM order. If you were using the 
ListLayoutHandler or GridLayoutHandler, it would have been simple for 
you to extract the information you require from these. However, since 
you are using the ModuleLayoutManager, please read on:

It is "widely accepted" that the current signature to afterMove is not 
universally helpful... although on the other hand that the current 
signature to *any* event is not universally helpful :) Actually in the 
next framework release there will be an interesting new system that, 
believe it or not, will allow you to choose any signature you want for 
an event. Until then, I suggest you do the following -

Your core problem is actually getting a reference to the reorderer 
instance itself which you construct from within your own listener. It is 
somewhat dizzying thinking about the order of operations, but the 
following simple-minded-looking approach will actually work:

var myReorderer = fluid.reorderLayout("#my-container", {
      selectors: {

blah blah

      afterMove: function () {
         var model = myReorderer.layoutHandler.getModel();
         $.ajax({ type: "POST", dataType: "application/json", url: 
"/server/reorder_layout", data: JSON.stringify(model) });

Javascript is funny that way... the symbolic binding out of the function 
body isn't dependent on any particular value being held in the variable
"myReorderer" at the time the function body is parsed - unlike many 
other languages I could mention.

There is no need to copy the "options.acquireModel" branch out since you 
know perfectly well that you never supplied such a function in your 
options, and that you are using the ModuleLayoutHandler which supports 
the getModel method. Also, I believe since we fixed your *other* bug, 
with the current release you can just supply the selector string 
"#my-container" the first argument :P

Thanks for bringing this unhappiness in the design of the Reorderer to 
our attention - it was (re)written at a time when our general 
understanding of how to do these things was not quite complete... we 
will try to fix things up in the next release (or perhaps the one 
following - we will have a lot of rewrites to do once our new IoC 
framework is ready) so that it has a well-defined "model" sitting at 
top-level inside its "that" like every decent component should.

Good luck,


Chris Hubick wrote:
> Hi,
> So, I have been using the Fluid Layout Reorderer 1.1.1 for some months
> now, and things have been working pretty great (thanks!).
> I just migrated my server processing from using Java Servlets to JAX-RS,
> which takes care of data-binding request entities based on Content-Type,
> cool.  Sadly, this broke my reordering, as my old Servlet just jammed
> the entity into a JSON parser and didn't care about the Content-Type,
> but apparently the Fluid Reorderer POST's to my afterMoveCallbackUrl
> using Content-Type: application/x-www-form-urlencoded, where
> application/json is now required for proper automatic binding.
> So, I thought I would upgrade to Infusion 1.1.2 and see if this was
> fixed, and/or file a bug - but then asking on IRC, I'm informed that
> afterMoveCallbackUrl is deprecated, and pointed to:
> http://wiki.fluidproject.org/display/fluid/Talking+to+the+Server+Using+The+afterMove+Event
> Now, that page lists two methods for communicating with the server, (1)
> forms, and (2) JSON (like was done with afterMoveCallbackUrl).  So, I
> want to continue to use the JSON method, but that page only documents
> the form based method :(
> So, I go code surfing to find the code for the existing callback
> function, to learn how it does things, and deep inside the
> fluid.reorderer definition in Reorderer.js I find:
> if (options.afterMoveCallbackUrl) {
>     thatReorderer.events.afterMove.addListener(function () {
>         var layoutHandler = thatReorderer.layoutHandler;
>         var model = layoutHandler.getModel? layoutHandler.getModel():
>              options.acquireModel(thatReorderer);
>         $.post(options.afterMoveCallbackUrl, JSON.stringify(model));
>     }, "postModel");
> }
> So, great, I have some very limited understanding of how that listener
> function works, at least as created *inside* the fluid.reorderer
> definition, where it has access to thatReorderer, etc.  The task then
> becomes, how do I adapt that code to work outside of that context, out
> on my page which instantiates my reorderer?  This is where I fail, and
> need help!
> Here is my current abomination:
> <script type="text/javascript">
> // <![CDATA[
> jQuery(document).ready(function () {
>   fluid.reorderLayout (fluid.container ("#my-container"), {
>     selectors: {
>       columns: "my-col",
>       modules: "my-col > my-module"
>     },
>     listeners: {
>       afterMove: function () {
>         var layoutHandler = fluid.reorderer.layoutHandler;
>         var model = layoutHandler.getModel ? layoutHandler.getModel() : fluid.reorderer.options.acquireModel(fluid.reorderer);
>         $.ajax({ type: "POST", dataType: "application/json", url: "/server/reorder_layout", data: JSON.stringify(model) });
>       }
>     }
>   });
> });
> // ]]>
> </script>
> So, the afterMove function get's called correctly, but obviously my
> adaptation of the code to gain a reference to the model is wrong.  So,
> my question is exactly that, how do I get a reference to the model, or
> even the layoutHandler?  AKA: Can someone please help me by filling in
> that function, so things will continue to work in the future as they did
> with afterMoveCallbackUrl (but with the correct Content-Type)?
> Much Thanks!

More information about the Infusion-users mailing list