I’ve spent most of the last week developing the MODS XForm. You can take a look at its current incarnation here. The implementation of the form itself is not terribly difficult, although the nested repeats can get a little tricky. The real time sink is in trying to create a form that makes sense and is easy to use. MODS itself is a little maddening, particularly if you want to create a form that allows users to utilize the full range of available elements and attributes. An input box for every element and attribute would be confusing intimidating, and would likely lead to a lot of bad data entry. For my own sanity I’m not implementing the full element set, but it would be relatively easy to add additional elements into the form based on an institutional/project needs.
In an effort to control data entry, limit empty elements and increase consistency I’ve worked on adding as many drop downs as possible. I try not to send users to other resources to look up authority controlled values. I also really like the “optional fields” box, that allows users to add additional elements/attributes into a simple template. This cleans up the interface, eliminates the need to strip empty elements from the data on submission, and makes it easy to add new elements into an already existing record.
One of the areas I’ve been struggling with is inserting elements based on a users selection from a select1 list. For example, in the name element each name can be associated with one or more roles. Roles in MODS look like this:
<mods:role> <mods:roleTerm authority="marcrelator" type="code">ctg</mods:roleTerm> <mods:roleTerm authority="marcrelator" type="text">Cartographer</mods:roleTerm> </mods:role>
This is a controlled field, with a text based value and a code value (why the code value isn’t an optional element on roleTerm, is a bit of a mystery to me) . It seems natural that a user should be able to select from the list of text values : Author, Artist, Cartographer, etc. and have the appropriate mods:role inserted into the data. It also seemed natural that xforms:copy would be the perfect way to do this.
In theory the code would look something like this:
<xforms:select1 ref="mods:role">
<xforms:label>Test Role</xforms:label>
<xforms:itemset nodeset="instance('roleShort')/mods:role">
<xforms:label ref="mods:roleTerm[@type='text']"/>
<xforms:copy ref="."/>
</xforms:itemset>
</xforms:select1>
Except with this code you end up with a nested mods:role:
<mods:role> <mods:role> <mods:roleTerm authority="marcrelator" type="code">ctg</mods:roleTerm> <mods:roleTerm authority="marcrelator" type="text">Cartographer</mods:roleTerm> </mods:role> </mods:role>
If you change the xforms:copy to xforms:copy ref=”child::*”, you only get the first child, not all the children of mods:role. I’m not sure if this is a bug in the way the xpath is implemented, but I couldn’t find a way around it. Instead I abandoned the idea of using xforms:copy and used this approach instead. Although a little more complicated, it works without a hitch. The code on the select1 looks like this:
<xforms:select1 ref="instance('role')/mods:roleTerm">
<xforms:label>Test Role</xforms:label>
<xforms:itemset nodeset="instance('roleShort')/mods:role">
<xforms:label ref="mods:roleTerm[@type='text']"/>
<xforms:value ref="mods:roleTerm[@type='text']"/>
</xforms:itemset>
</xforms:select1>
<xforms:trigger>
<xforms:label> Add Role </xforms:label>
<xforms:insert ev:event="DOMActivate" context="instance('metadata')"
nodeset="instance('metadata')/mods:name/mods:role" at="index('name')" position="after"
origin="instance('roleShort')/mods:role[mods:roleTerm = instance('role')/mods:roleTerm]"/>
</xforms:trigger>
You could also include the insert within the select1 and have it triggered by a change in value. I will most likely be using a similar approach to allow users to insert subject headings from a controlled vocabulary list. Something else I like in terms of a user interface is this example from Orbeon where the user highlights the line they want to edit, and are only presented with an input box when they select edit. I would use this for values that I do not expect to change much (for our collection). A rights statement, the language element, the note that includes information about UVM as the publisher of the digital version, ect.
I think I should be able to finish up the functionality of the form this week, and hopefully be able to pretty it up a little before we put it into production with our next collection. I think may move to the tabbed look for this form as well, because I think having all the elements on one page can get confusing. I do have had a user who prefers this approach though. She says it allows her to base the subject headings on the description/abstract, without having to toggle back and forth. So I may need to put some more thought into presentation.
October 30, 2007 at 5:53 pm |
[...] work I couldn’t see anyway around using xforms:copy, which I have found to be a little tricky in the past. To avoid the issues I ran into when using xforms:copy to insert directly into the main instance, I [...]