You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by JD Daniels <jd...@kismetsoftware.com> on 2005/01/29 21:28:20 UTC
[CFORMS] Another post looking for binding help :(
Searching the mailing list for binding help shows an awful lot of
threads, I'm sorry if this is answered somewhere, but afters hours of
scanning, I can't figure out how to fix this......
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: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org