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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to