Building the form

The new forms to enter data in Dedomenon are based on YUI. He is some info on how it is built:

In app/views/entities/entity_yui_form.rhtml , fields of the form (and only fields) are defined and added to the javascript array named fields. This is done by calling to_yui_formrow for each detail of the entity, which simply returns the javascript code needed to create the field.

In app/views/entities/list.rhtml and app/views/entities/add.rhtml, the form is displayed. With the code detailed above, only the field of the form are defined. In each place where the entry form is needed, we have to define it:

  1. Open the YUI block:
<% yui_block( :modules => [ "gallery-form" ], :use => [ 'gallery-form', 'anim']) do %>
  1. initialise the fields array and add you hidden fields:
var fields = [ ];
fields.push( new Y.HiddenField({
name:"instance_id",
value:"-1"}));
  1. render the entity_yui_form partial, which needs the @instance local variable

bc.<%= render :partial => “entity_yui_form”, :locals => { :instance => @instance } %>

  1. Add the suubmit buttons
fields.push ( { type : 'submit', label : 'Submit', id: 'commit'});
  1. define the form with the event listeners you need. You can do it in javascript, or simply use the helper to display the default form. The helper needs to arguments: the content_box (div in which the form will be displayed) and the list_id (div which will contain the list we display after adding an entry):
<%= default_entity_form( :form_content_box => "testForm", :list_id => @list_id) %>

The fields in the form

Each field in the form corresponds to a detail attached to the entity (or detail_value attached to the instance if we are editing an existing entry). Each detail has a to_form_row or to_yui_form_row, which will define its field(s) in the form.
Actually, each detail/detail_value defines 2 fields: one visible and one hidden. The hidden field is passing information to the save_entity method such as the detail_value_id. Both fields are linked by their name attribute: “#{detail.name}[#{i.to_s}][id]” and “#{detail.name}[#{i.to_s}][name]”.

The id of the value field is created by the method form_field_id which takes the same args as the to_form_row method:
bc. var email_field = new Y.TextField({
id: “#{form_field_id(i,o)}_value”,
validator : YUI.madb.get_detail_validator(#{detail.id}),
name:“#{detail.name+”[“i.to_s”]“}[value]”,
value:“#{value}”,
label:“#{detail.name }”})

Validation

All fields of a form have a validator defined. The default one just returns true and accepts all values without contacting the server.
When a validator is specified with Y.madb.get_detail_validator, the validation is done server-side, by sending a request to /app/entities/check_detail_value_validity passing 2 parameters in the url: detail_id and detail_value. The server returns 1 in case of success, 0 in case of error (invalid value).
In the javascript code generated by the to_form_row method of the detail class, it is easy to add validation to the field: just add the validator config value (as in the code displayed here above for the email_field) to the function returned by get_detail_validator(detail_id), which is a javascript method made available in dedomenon.

The validation is done by calling the class method valid? of the detail. For the email details, it is simply done with a regular expression:

 def self.valid?(value, o={})
                if value.nil? or value=="" or value.match(/^[_\w-]+(\.[_\w-]+)*@[\w-]+(\.\w+)*(\.[a-z]{2,3})$/)
                        return true
                end
                return false
  end