I have a user bean with a Set of Role Beans.
In my form to add/edit a user bean, I display a drop down list populated with existing Roles.
I have a button that when clicked, adds a Role repeater with hidden fields for id and name, and output widgets to display them to the user.
The problem is some odd behavior - If I load the form, add a role, then remove it, then add it again, it saves properly.
If I load the form, add a role, and hit save, it saves a new Role with NULL values.
I am starting to think I simply am missing something fundamental about the binding framework.
I am using cocoon 2.1.6
UserModel:
<?xml version="1.0" encoding="ISO-8859-1"?>
<fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
<fd:widgets>
<fd:output id="id" readonly="true" required="true">
<fd:label>Id</fd:label>
<fd:datatype base="integer"/>
</fd:output>
<fd:field id="login" required="true">
<fd:label>Login</fd:label>
<fd:datatype base="string"/>
</fd:field> <fd:field id="password" required="true">
<fd:label>Password</fd:label>
<fd:datatype base="string"/>
</fd:field> <fd:field id="firstName" required="true">
<fd:label>First Name</fd:label>
<fd:datatype base="string"/>
</fd:field> <fd:field id="lastName" required="true">
<fd:label>Last Name</fd:label>
<fd:datatype base="string"/>
</fd:field> <fd:field id="email" required="true">
<fd:label>Email</fd:label>
<fd:datatype base="string"/>
</fd:field> <fd:field id="roleId">
<fd:label>Resource</fd:label>
<fd:datatype base="string"/>
<fd:selection-list src="cocoon:/role_list" dynamic="true"/>
</fd:field> <fd:repeater id="resources">
<fd:widgets>
<fd:field id="id">
<fd:datatype base="integer"/>
</fd:field>
<fd:field id="name">
<fd:label>Name</fd:label>
<fd:datatype base="string"/>
</fd:field>
<fd:field id="description">
<fd:label>Description</fd:label>
<fd:datatype base="string"/>
</fd:field>
<fd:booleanfield id="select">
<fd:label>Select</fd:label>
</fd:booleanfield>
</fd:widgets>
</fd:repeater> <fd:action id="addresource" action-command="x">
<fd:label>Add resource</fd:label>
</fd:action> <fd:action id="removeresource" action-command="x">
<fd:label>Remove selected resources</fd:label>
</fd:action></fd:widgets> </fd:form>
User Binding:
<?xml version="1.0"?>
<fb:context xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" path="/">
<fb:value id="id" path="id"/>
<fb:value id="login" path="login"/>
<fb:value id="password" path="password"/>
<fb:value id="firstName" path="firstName"/>
<fb:value id="lastName" path="lastName"/>
<fb:value id="email" path="email"/>
<fb:repeater id="resources" parent-path="." row-path="roles">
<fb:identity>
<fb:value id="id" path="id"/>
</fb:identity>
<fb:on-bind>
<fb:value id="id" path="id" />
<fb:value id="name" path="name" />
</fb:on-bind> <fb:on-delete-row>
<fb:delete-node />
</fb:on-delete-row><fb:on-insert-row>
<fb:insert-bean classname="com.kismetsoftware.authenticator.model.Role" addmethod="addRole"/>
</fb:on-insert-row>
</fb:repeater>
</fb:context>
userTemplate:
<?xml version="1.0"?>
<page xmlns:ft="http://apache.org/cocoon/forms/1.0#template" xmlns:cinclude="http://apache.org/cocoon/include/1.0" xmlns:fi="http://apache.org/cocoon/forms/1.0#instance">
<title>#{title}</title>
<ft:form-template action="#{$continuation/id}.continue" method="POST">
<fi:group>
<fi:styling type="tabs"/>
<fi:items>
<fi:group>
<fi:label>User Details</fi:label>
<fi:styling layout="columns"/>
<fi:items>
<ft:widget id="login"/>
<ft:widget id="password"/>
<ft:widget id="firstName"/>
<ft:widget id="lastName"/>
<ft:widget id="email"/>
<ft:widget id="roleId"/>
<ft:widget id="addresource"><fi:styling /></ft:widget>
</fi:items>
</fi:group>
</fi:items>
</fi:group>
<p></p>
<table cellpadding="5" cellspacing="0" border="0">
<tr class="forms-repeaterrow">
<th>Resources:</th>
</tr>
<ft:repeater-widget id="resources">
<tr>
<td valign="absmiddle"><ft:widget id="id"><fi:styling type="hidden"/></ft:widget><ft:widget id="select"/></td>
<td valign="absmiddle"><ft:widget id="name"><fi:styling type="hidden"/></ft:widget><ft:widget id="name"><fi:styling type="output"/></ft:widget></td>
</tr>
</ft:repeater-widget>
</table>
<table cellpadding="4" cellspacing="0" border="0" width="100%">
<tr>
<td align="center"><hr /></td>
</tr>
<tr>
<td align="center"><ft:widget id="removeresource"/></td>
</tr>
</table>
<table cellpadding="4" cellspacing="0" border="0" width="100%">
<tr>
<td align="center" colspan="2"><hr /></td>
</tr>
</table>
<input type="submit" value="#{buttonText}"/>
</ft:form-template>
</page>edit User flow:
// Load the javascript Cocoon Forms library (v2)
cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/v2/Form.js");// Global Data Access Objects
var appCtx = cocoon.context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
var service = appCtx.getBean("authenticatorService");
function edit_user_form()
{
var reslist = new java.util.ArrayList();
var id = cocoon.request.get("id");// Look up our Entry var bean = service.getUserById(id);
// Create The Form
var form = new Form("forms/userModel.xml");// Set Some Form Specific Text Fields var model = form.getWidget(); model.buttonText = "Save"; model.title = "Edit User";
model.addresource.onClick = function()
{
if (reslist.contains(model.roleId.value))
{
// already in the list
model.roleId.setValidationError("User already has this resource.");
}
else
{
reslist.add(model.roleId.value);
model.resources.addRow();
}
}
model.removeresource.onClick = function()
{
model.resources.removeRow(function(row)
{
if(row.select.value){reslist.remove(row.name.value)}
return row.select.value;
});
} model.resources.onAddRow = function(row)
{
var resource = service.getRoleByName(model.roleId.value);
row.id.value =resource.id;
row.name.value =resource.name;
row.description.value =resource.description;
}
// Bind The Form To The Bean And Display It form.createBinding("forms/userBinding.xml");
// Load The Bean To The Form form.load(bean);
// Show Form To User
form.showForm("internal/show-form/user");// Save The Form Data To The Bean form.save(bean);
// Save Bean To Database service.updateUser(bean);
// Send The User Their Result
cocoon.redirectTo("user_summary_view");
}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
