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!



Creative Commons License
Wow, this is great stuff. Do you know if the cforms stuff can be used outside or Cocoon? Or can Cocoon be used inside of a traditional servlet application? I’m new to Cocoon and intrigued, but I can’t commit to a full system overhaul right now. I’d love to be able to go from XML Schema to html form, back to XML and into the database for dynamic blog types. Cforms should be a big piece but I’m a little concerned about the commitment level. I suppose I have technology commitment issues. Thanks for the great posts and keep up the good work! Best, Joe Reger
2005
Joe Reger