I’ve updated the MODS editor, mentioned before. New features include:

  • tabs
  • moving items up or down
  • improved navigation: when you insert or move an item, it will be highlighted to let you know what you did (still buggy, though)

You can download the source. I’m using some features from the latest version of Cocoon Forms, so this no longer works in Cocoon 2.1.5; but all you have to do is compile Cocoon 2.1.7 and copy the jar file for the Cocoon Forms block back into Cocoon 2.1.5, if you don’t want to migrate to 2.1.7.

As I said in my last post, vertical scrolling is the bane of using Cocoon Forms. The new tabs and the highlighting of new elements should help with that. It’s all still ugly and buggy but we’re getting closer.

Scroll to Changed Element

For Cocoon enthusiasts, here’s how I got Cocoon Forms to scroll to the changed element:

  • Add a widget to hold the id of the action that caused the form to be submitted. In the model, add:

    <fd:field id="lastSubmitter"> <fd:datatype base="string"/> </fd>

    In the template, make it a hidden field:

    <ft:widget id="lastSubmitter"> <fi:styling type="hidden"/> </ft:widget>

    This gives a place to store the id of the submitting action, and pass it to a client-side script.

  • Give every action in the model an event listener:

    <fd:on-activate> <javascript> saveLastSubmitter(event); </javascript> </fd:on-activate>

    The function “saveLastSubmitter” goes in the flowscript, mods-binding.js:

    function saveLastSubmitter(event) { element = event.source; form = element.getForm(); lastSubmitter = element.id; while (element.getParent().id != '') { element = element.getParent(); lastSubmitter = element.id + "." + lastSubmitter; } form.getChild("lastSubmitter").value = lastSubmitter; }

    This climbs up through the ancestors of the submitter, concatenating their ids into a string like this: “names.0.nameparts.0.insertWidget”. This is the format used by Cocoon Forms for input field ids. The final id is stowed in the “lastSubmitter” widget, so it will be passed in the hidden field defined above.

  • Add some client-side code: put these lines at the end of the function form_onload() in form-lib.js:

    var d = document; var lastSubmitterName = d.getElementById("lastSubmitter").value; if (lastSubmitterName != '') { d.getElementById(lastSubmitterName).scrollIntoView(false); }

    This pulls the id of the submitter out of the hidden field, finds the element it specifies, and scrolls that element into view.

There’s some further jiggery to get it to highlight the right element in different circumstances, not yet fully debugged. Suggestions for improvements gladly received!