From f7320a4b47d0685b3661372b4e7ff2812291c54a Mon Sep 17 00:00:00 2001
From: Romain Courteaud <romain@nexedi.com>
Date: Thu, 2 Oct 2014 13:52:34 +0000
Subject: [PATCH] Implement interaction between the header and the page
 content.

Move loading notification in the header (drop JQM global notification).
Inform user when some changes were made in the form.
Add form submit notification.
Allow to trigger the form submit from the header button.
Do not submit any form if one gadget field validation constraint fails. Display the error next to the label.
---
 .../rjs_gadget_erp5_appcache.xml              |   6 +-
 .../rjs_gadget_erp5_floatfield_js.xml         |   9 +-
 .../rjs_gadget_erp5_form_js.xml               |  59 ++++++++-
 .../rjs_gadget_erp5_header_html.xml           |   8 +-
 .../rjs_gadget_erp5_header_js.xml             | 117 ++++++++++++++++--
 .../web_page_module/rjs_gadget_erp5_html.xml  |   4 +-
 .../web_page_module/rjs_gadget_erp5_js.xml    |  45 +++++--
 .../rjs_gadget_erp5_listfield_js.xml          |   9 +-
 .../rjs_gadget_erp5_pt_form_dialog_html.xml   |   8 +-
 .../rjs_gadget_erp5_pt_form_dialog_js.xml     |  10 +-
 .../rjs_gadget_erp5_pt_form_list_js.xml       |  19 ++-
 ...gadget_erp5_pt_form_view_editable_html.xml |  15 +--
 ...s_gadget_erp5_pt_form_view_editable_js.xml |  52 ++++++--
 .../rjs_gadget_erp5_pt_formpage_js.xml        |  10 +-
 .../rjs_gadget_erp5_stringfield_html.xml      |   8 +-
 .../rjs_gadget_erp5_stringfield_js.xml        |  73 ++++++++++-
 .../rjs_gadget_erp5_textareafield_js.xml      |  10 +-
 17 files changed, 378 insertions(+), 84 deletions(-)

diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml
index c84d5c5812..b364848678 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_appcache.xml
@@ -102,7 +102,7 @@
             <value> <string encoding="cdata"><![CDATA[
 
 CACHE MANIFEST\n
-# generated on Mon, 29 Sep 2014 14:23:16 +0000\n
+# generated on Thu, 02 Oct 2014 12:06:38 +0000\n
 # XXX + fonts\n
 # images/ajax-loader.gif\n
 CACHE:\n
@@ -322,7 +322,7 @@ NETWORK:\n
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58588.9950.37290</string> </value>
+                <value> <string>937.64214.42636.62720</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -340,7 +340,7 @@ NETWORK:\n
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1412000596.45</float>
+                        <float>1412254043.5</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_floatfield_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_floatfield_js.xml
index 67528293fb..d5185c12bb 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_floatfield_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_floatfield_js.xml
@@ -120,6 +120,9 @@
       );\n
       input.setAttribute(\'name\', field_json.key);\n
       input.setAttribute(\'title\', field_json.title);\n
+      if (field_json.required === 1) {\n
+        input.setAttribute(\'required\', \'required\');\n
+      }\n
       if (field_json.editable !== 1) {\n
         input.setAttribute(\'readonly\', \'readonly\');\n
         input.setAttribute(\'data-wrapper-class\', \'ui-state-disabled ui-state-readonly\');\n
@@ -256,7 +259,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>sven</string> </value>
+                <value> <string>romain</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -270,7 +273,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.48460.49347.43246</string> </value>
+                <value> <string>937.51520.38687.48861</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -288,7 +291,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411576355.41</float>
+                        <float>1412082125.19</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
index 6f71d99a26..5f97ef84af 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_form_js.xml
@@ -130,6 +130,27 @@
     })\n
 \n
     .declareAcquiredMethod("aq_put", "jio_put")\n
+\n
+    .allowPublicAcquisition("notifyInvalid", function (param_list, scope) {\n
+      return this.getDeclaredGadget(scope)\n
+        .push(function (gadget) {\n
+          return gadget.getElement();\n
+        })\n
+        .push(function (gadget_element) {\n
+          gadget_element.previousElementSibling.querySelector("span").textContent = " (" + param_list[0] + ")";\n
+        });\n
+    })\n
+\n
+    .allowPublicAcquisition("notifyValid", function (param_list, scope) {\n
+      /*jslint unparam:true*/\n
+      return this.getDeclaredGadget(scope)\n
+        .push(function (gadget) {\n
+          return gadget.getElement();\n
+        })\n
+        .push(function (gadget_element) {\n
+          gadget_element.previousElementSibling.querySelector("span").textContent = "";\n
+        });\n
+    })\n
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
@@ -172,9 +193,11 @@
                   var field_queue = new RSVP.Queue(),\n
                     sandbox = "public",\n
                     field_url = \'gadget_erp5_field_readonly.html\',\n
+                    // Don\'t change the structure without changing notifyValid and notifyInvalid\n
                     field_element = document.createElement("div"),\n
                     gadget_element = document.createElement("div"),\n
                     label_element = document.createElement("label"),\n
+                    error_element = document.createElement("span"),\n
                     renderered_field = rendered_form[field[0]];\n
 \n
                   field_element.className = "ui-field-contain";\n
@@ -185,6 +208,8 @@
 //                   field_element.setAttribute(\'data-role\', \'fieldcontain\');\n
                   label_element.setAttribute(\'for\', renderered_field.key);\n
                   label_element.textContent = renderered_field.title;\n
+                  // error_element.setAttribute(\'class\', \'ui-state-error ui-corner-all\');\n
+                  label_element.appendChild(error_element);\n
                   if (group[0] !== "bottom") {\n
                     field_element.appendChild(label_element);\n
                   }\n
@@ -196,6 +221,8 @@
                     field_url = \'gadget_erp5_field_list.html\';\n
                   } else if (renderered_field.type === \'StringField\') {\n
                     field_url = \'gadget_erp5_field_string.html\';\n
+                  } else if (renderered_field.type === \'RelationStringField\') {\n
+                    field_url = \'gadget_erp5_field_relation_string.html\';\n
                   } else if (renderered_field.type === \'TextAreaField\') {\n
                     field_url = \'gadget_erp5_field_textarea.html\';\n
                   } else if (renderered_field.type === \'FloatField\') {\n
@@ -284,6 +311,34 @@
         .push(function () {\n
           return data;\n
         });\n
+    })\n
+\n
+\n
+    .declareMethod("checkValidity", function () {\n
+      var form_gadget = this,\n
+        k,\n
+        field_gadget,\n
+        count = form_gadget.props.gadget_list.length,\n
+        result = true,\n
+        queue = new RSVP.Queue();\n
+\n
+      function extendData(field_validity) {\n
+        result = result && field_validity;\n
+      }\n
+\n
+      for (k = 0; k < count; k += 1) {\n
+        field_gadget = form_gadget.props.gadget_list[k];\n
+        // XXX Hack until better defined\n
+        if (field_gadget.checkValidity !== undefined) {\n
+          queue\n
+            .push(field_gadget.checkValidity.bind(field_gadget))\n
+            .push(extendData);\n
+        }\n
+      }\n
+      return queue\n
+        .push(function () {\n
+          return result;\n
+        });\n
 \n
     });\n
 \n
@@ -424,7 +479,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58318.16438.37768</string> </value>
+                <value> <string>937.64263.33357.15633</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -442,7 +497,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411999896.88</float>
+                        <float>1412254860.94</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_html.xml
index 6d8c678a6a..7d5b506e6a 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_html.xml
@@ -116,6 +116,7 @@
     <script src="RSVP.js" type="text/javascript"></script>\n
     <script src="renderjs.js" type="text/javascript"></script>\n
     <script src="handlebars.js" type="text/javascript"></script>\n
+    <script src="gadget_global.js" type="text/javascript"></script>\n
 \n
     <!-- custom script -->\n
     <script src="gadget_erp5_header.js" type="text/javascript"></script>\n
@@ -126,6 +127,9 @@
     <script id="header-link-template" type="text/x-handlebars-template">\n
        <a role="button" href="{{url}}" class="responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}">{{title}}</a>\n
     </script>\n
+    <script id="header-button-template" type="text/x-handlebars-template">\n
+       <form><button type=\'submit\' class=\'responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}\'>{{title}}</button></form>\n
+    </script>\n
 \n
     <script id="sub-header-template" type="text/x-handlebars-template">\n
         {{#each sub_header_list}}\n
@@ -306,7 +310,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.54262.65313.31897</string> </value>
+                <value> <string>937.58644.46215.53674</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -324,7 +328,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411993212.79</float>
+                        <float>1412241646.76</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_js.xml
index 3d6fb5b2d0..5dd26f34c0 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_header_js.xml
@@ -102,8 +102,8 @@
             <value> <string encoding="cdata"><![CDATA[
 
 /*jslint nomen: true, indent: 2, maxerr: 3 */\n
-/*global window, rJS, Handlebars, document */\n
-(function (window, rJS, Handlebars, document) {\n
+/*global window, rJS, Handlebars, document, loopEventListener */\n
+(function (window, rJS, Handlebars, document, loopEventListener) {\n
   "use strict";\n
 \n
   /////////////////////////////////////////////////////////////////\n
@@ -121,12 +121,16 @@
                          .getElementById("header-title-link-template")\n
                          .innerHTML,\n
     header_title_link_template = Handlebars.compile(header_title_link_source),\n
-\n
 \n
     sub_header_source = gadget_klass.__template_element\n
                          .getElementById("sub-header-template")\n
                          .innerHTML,\n
     sub_header_template = Handlebars.compile(sub_header_source),\n
+\n
+    header_button_source = gadget_klass.__template_element\n
+                         .getElementById("header-button-template")\n
+                         .innerHTML,\n
+    header_button_template = Handlebars.compile(header_button_source),\n
     header_link_source = gadget_klass.__template_element\n
                          .getElementById("header-link-template")\n
                          .innerHTML,\n
@@ -139,6 +143,12 @@
     // Init local properties\n
     .ready(function (g) {\n
       g.props = {};\n
+      g.stats = {\n
+        loaded: false,\n
+        modified: false,\n
+        submitted: true,\n
+        options: {}\n
+      };\n
     })\n
 \n
     // Assign the element to a variable\n
@@ -153,12 +163,49 @@
           g.props.title_element = element.querySelector("h1");\n
         });\n
     })\n
+\n
+    .ready(function (g) {\n
+      return g.render(g.stats.options);\n
+    })\n
 \n
     .declareAcquiredMethod("whoWantToDisplayThis", "whoWantToDisplayThis")\n
     .declareAcquiredMethod("jio_get", "jio_get")\n
+    .declareAcquiredMethod("triggerSubmit", "triggerSubmit")\n
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
+    .declareMethod(\'notifyLoading\', function () {\n
+      if (this.stats.loaded) {\n
+        this.stats.loaded = false;\n
+        return this.render(this.stats.options);\n
+      }\n
+    })\n
+    .declareMethod(\'notifyLoaded\', function () {\n
+      if (!this.stats.loaded) {\n
+        this.stats.loaded = true;\n
+        return this.render(this.stats.options);\n
+      }\n
+    })\n
+    .declareMethod(\'notifyChange\', function () {\n
+      if (!this.stats.modified) {\n
+        this.stats.modified = true;\n
+        return this.render(this.stats.options);\n
+      }\n
+    })\n
+    .declareMethod(\'notifySubmitting\', function () {\n
+      if (this.stats.submitted) {\n
+        this.stats.submitted = false;\n
+        return this.render(this.stats.options);\n
+      }\n
+    })\n
+    .declareMethod(\'notifySubmitted\', function () {\n
+      if (!this.stats.submitted) {\n
+        this.stats.submitted = true;\n
+        // Change modify here, to allow user to redo some modification and being correctly notified\n
+        this.stats.modified = false;\n
+        return this.render(this.stats.options);\n
+      }\n
+    })\n
     .declareMethod(\'render\', function (options) {\n
       var gadget = this,\n
         possible_left_link_list = [\n
@@ -171,6 +218,10 @@
         possible_right_link_list = [\n
           [\'edit_url\', \'Edit\', \'edit\']\n
         ],\n
+        possible_right_button_list = [\n
+          [\'save_action\', \'Save\', \'check\'],\n
+          [\'submit_action\', \'Proceed\', \'share\']\n
+        ],\n
         possible_sub_header_list = [\n
           [\'tab_url\', \'Tabs\', \'eye\'],\n
           [\'jump_url\', \'Jump\', \'plane\'],\n
@@ -187,10 +238,12 @@
         count = 0,\n
         left_link,\n
         right_link,\n
+        right_button,\n
+        default_right_icon = "",\n
         title_link = {title: "ERP5"},\n
         sub_header_list = [],\n
         alphabet = "abcdefghijklmnopqrstuvwxyz";\n
-\n
+      gadget.stats.options = options;\n
       // Handle main title\n
       if (options.hasOwnProperty("page_title")) {\n
         title_link.title = options.page_title;\n
@@ -227,6 +280,20 @@
       }\n
 \n
       // Handle right link\n
+      if (!gadget.stats.loaded) {\n
+        default_right_icon = "spinner";\n
+        // Show default loading information\n
+        right_link = {\n
+          title: "Loading",\n
+          icon: default_right_icon,\n
+          url: "",\n
+          class: "ui-disabled"\n
+        };\n
+      } else if (!gadget.stats.submitted) {\n
+        default_right_icon = "spinner";\n
+      } else if (gadget.stats.modified) {\n
+        default_right_icon = "warning";\n
+      }\n
       for (i = 0; i < possible_right_link_list.length; i += 1) {\n
         if (options.hasOwnProperty(possible_right_link_list[i][0])) {\n
           klass = "";\n
@@ -235,17 +302,27 @@
           }\n
           right_link = {\n
             title: possible_right_link_list[i][1],\n
-            icon: possible_right_link_list[i][2],\n
+            icon: default_right_icon || possible_right_link_list[i][2],\n
             url: options[possible_right_link_list[i][0]],\n
             class: klass\n
           };\n
           count += 1;\n
         }\n
       }\n
-      if (right_link === undefined) {\n
-        gadget.props.right_link.innerHTML = "";\n
-      } else {\n
+      for (i = 0; i < possible_right_button_list.length; i += 1) {\n
+        if (options.hasOwnProperty(possible_right_button_list[i][0])) {\n
+          right_button = {\n
+            title: possible_right_button_list[i][1],\n
+            icon: default_right_icon || possible_right_button_list[i][2]\n
+          };\n
+        }\n
+      }\n
+      if (right_button !== undefined) {\n
+        gadget.props.right_link.innerHTML = header_button_template(right_button);\n
+      } else if (right_link !== undefined) {\n
         gadget.props.right_link.innerHTML = header_link_template(right_link);\n
+      } else {\n
+        gadget.props.right_link.innerHTML = "";\n
       }\n
 \n
       // Handle sub header\n
@@ -274,10 +351,28 @@
       gadget.props.sub_header_ul.innerHTML = sub_header_template({\n
         sub_header_list: sub_header_list\n
       });\n
+    })\n
+\n
+    //////////////////////////////////////////////\n
+    // handle button click\n
+    //////////////////////////////////////////////\n
+    .declareService(function () {\n
+      var form_gadget = this;\n
+\n
+      function formSubmit() {\n
+        return form_gadget.triggerSubmit();\n
+      }\n
 \n
+      // Listen to form submit\n
+      return loopEventListener(\n
+        form_gadget.props.element,\n
+        \'submit\',\n
+        false,\n
+        formSubmit\n
+      );\n
     });\n
 \n
-}(window, rJS, Handlebars, document));
+}(window, rJS, Handlebars, document, loopEventListener));
 
 ]]></string> </value>
         </item>
@@ -414,7 +509,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58590.25550.25514</string> </value>
+                <value> <string>937.64299.47970.64017</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -432,7 +527,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1412000590.73</float>
+                        <float>1412256721.33</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_html.xml
index c5f8bf4ec2..055cc1636c 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_html.xml
@@ -283,7 +283,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58476.63930.3566</string> </value>
+                <value> <string>937.59751.29793.48025</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -301,7 +301,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1412000194.01</float>
+                        <float>1412251612.53</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_js.xml
index 048fd66ee6..2a8e8c906c 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_js.xml
@@ -282,6 +282,31 @@
       return displayError(this, param_list[0]);\n
     })\n
 \n
+    .allowPublicAcquisition(\'notifySubmitting\', function () {\n
+      return this.getDeclaredGadget("header")\n
+        .push(function (header_gadget) {\n
+          return header_gadget.notifySubmitting();\n
+        });\n
+    })\n
+\n
+    .allowPublicAcquisition(\'notifySubmitted\', function () {\n
+      return this.getDeclaredGadget("header")\n
+        .push(function (header_gadget) {\n
+          return header_gadget.notifySubmitted();\n
+        });\n
+    })\n
+    .allowPublicAcquisition(\'notifyChange\', function () {\n
+      return this.getDeclaredGadget("header")\n
+        .push(function (header_gadget) {\n
+          return header_gadget.notifyChange();\n
+        });\n
+    })\n
+    .allowPublicAcquisition(\'triggerSubmit\', function () {\n
+      return this.getDeclaredGadget("pg")\n
+        .push(function (page_gadget) {\n
+          return page_gadget.triggerSubmit();\n
+        });\n
+    })\n
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
@@ -299,10 +324,14 @@
     // Render the page\n
     .declareMethod(\'render\', function (options) {\n
       var gadget = this,\n
+        header_gadget,\n
         main_gadget;\n
-      return new RSVP.Queue()\n
+      return gadget.getDeclaredGadget("header")\n
+        .push(function (declared_gadget) {\n
+          header_gadget = declared_gadget;\n
+          return header_gadget.notifyLoading();\n
+        })\n
         .push(function () {\n
-          $.mobile.loading(\'show\');\n
 \n
           // By default, init the header options to be empty (ERP5 title by default + sidebar)\n
           gadget.props.header_argument_list = [{}];\n
@@ -327,9 +356,6 @@
 \n
         .push(function (result) {\n
           main_gadget = result;\n
-          return gadget.getDeclaredGadget("header");\n
-        })\n
-        .push(function (header_gadget) {\n
           return header_gadget.render.apply(header_gadget, gadget.props.header_argument_list);\n
         })\n
         .push(function () {\n
@@ -344,14 +370,13 @@
                   element.removeChild(element.firstChild);\n
                 }\n
                 element.appendChild(fragment);\n
-                $.mobile.loading(\'hide\');\n
-                return $(element).trigger("create");\n
+                $(element).trigger("create");\n
+                return header_gadget.notifyLoaded();\n
               });\n
           }\n
         })\n
 \n
         .push(undefined, function (error) {\n
-          $.mobile.loading(\'hide\');\n
           return displayError(gadget, error);\n
         });\n
     });\n
@@ -493,7 +518,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.59906.57015.45841</string> </value>
+                <value> <string>937.64000.63491.17493</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -511,7 +536,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1412080420.18</float>
+                        <float>1412256764.71</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.xml
index 4a3a0c1cd3..ddb7c0337d 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.xml
@@ -146,6 +146,9 @@
         });\n
       }\n
       select.innerHTML += tmp;\n
+      if (field_json.required === 1) {\n
+        select.setAttribute(\'required\', \'required\');\n
+      }\n
       if (field_json.editable !== 1) {\n
         select.setAttribute(\'readonly\', \'readonly\');\n
         select.setAttribute(\'data-wrapper-class\', \'ui-state-readonly\');\n
@@ -284,7 +287,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>sven</string> </value>
+                <value> <string>romain</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -298,7 +301,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.51405.48576.10854</string> </value>
+                <value> <string>937.59950.62249.34679</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -316,7 +319,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411570828.74</float>
+                        <float>1412243487.09</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_html.xml
index 5587c0a955..1c893dc846 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_html.xml
@@ -127,12 +127,12 @@
     <h1></h1>\n
     <!-- XXX action, method, fieldset -->\n
     <form class="dialog_form">\n
+      <button type="submit" class="ui-btn ui-btn-b ui-btn-inline\n
+        ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>\n
       <div data-gadget-url="gadget_erp5_form.html"\n
               data-gadget-scope="erp5_form"\n
               data-gadget-sandbox="public">\n
       </div>\n
-      <!--button type="submit" class="ui-btn ui-btn-b ui-btn-inline\n
-        ui-icon-action ui-btn-icon-right"></button-->\n
     </form>\n
   </body>\n
 </html>
@@ -272,7 +272,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.54178.14656.62515</string> </value>
+                <value> <string>937.54178.32965.53043</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -290,7 +290,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411735830.16</float>
+                        <float>1412240451.98</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_js.xml
index a66019132e..b285bebcb1 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_dialog_js.xml
@@ -141,6 +141,9 @@
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
+    .declareMethod(\'triggerSubmit\', function () {\n
+      this.props.element.querySelector(\'button\').click();\n
+    })\n
     .declareMethod(\'render\', function (options) {\n
       var erp5_document = options.erp5_document,\n
         form_options = options.erp5_form || {},\n
@@ -180,7 +183,8 @@
           return form_gadget.renderPageHeader({\n
             cancel_url: all_result[1],\n
             page_title: options.erp5_document.title,\n
-            breadcrumb_url: all_result[2]\n
+            breadcrumb_url: all_result[2],\n
+            submit_action: true\n
           });\n
         });\n
     })\n
@@ -377,7 +381,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58416.46801.34491</string> </value>
+                <value> <string>937.64201.40983.3993</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -395,7 +399,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411990143.42</float>
+                        <float>1412251248.98</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_list_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_list_js.xml
index 91f907d159..25fa6521ca 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_list_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_list_js.xml
@@ -131,10 +131,19 @@
 \n
       return new RSVP.Queue()\n
         .push(function () {\n
+          var new_content_action = options.erp5_document._links.action_object_new_content_action;\n
+          if (new_content_action !== undefined) {\n
+            new_content_action = gadget.whoWantToDisplayThisPage({name: new_content_action.name});\n
+          } else {\n
+            new_content_action = "";\n
+          }\n
+\n
           return RSVP.all([\n
             gadget.getDeclaredGadget("erp5_searchfield"),\n
             gadget.getDeclaredGadget("erp5_form"),\n
-            gadget.whoWantToDisplayThisPage({name: options.view, page: "breadcrumb"})\n
+            gadget.whoWantToDisplayThisPage({name: options.view, page: "breadcrumb"}),\n
+            new_content_action,\n
+            gadget.whoWantToDisplayThisPage({page: "action", name: options.view})\n
           ]);\n
         })\n
         .push(function (all_gadget) {\n
@@ -144,9 +153,9 @@
             gadget.renderPageHeader({\n
               jump_url: "",\n
               cut_url: "",\n
-              actions_url: "",\n
+              actions_url: all_gadget[4],\n
               export_url: "",\n
-              add_url: "",\n
+              add_url: all_gadget[3],\n
               page_title: options.erp5_document.title,\n
               breadcrumb_url: all_gadget[2]\n
             })\n
@@ -291,7 +300,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.54284.12675.3652</string> </value>
+                <value> <string>937.64086.34377.7560</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -309,7 +318,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411742227.2</float>
+                        <float>1412257173.84</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_html.xml
index a7f79a0d0b..f73279d6b2 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_html.xml
@@ -130,14 +130,9 @@
 \n
     <!-- XXX action, method, fieldset -->\n
     <!-- XXX needs a theme -->\n
-    <form class="save_form ui-body-c">\n
-      <!--button type="submit" class="ui-btn ui-btn-b ui-btn-inline\n
-        ui-icon-edit ui-btn-icon-right">Save</button-->\n
-\n
-      <!--div class="action_list ui-controlgroup ui-controlgroup-horizontal ui-corner-all">\n
-        <div class="ui-controlgroup-controls">\n
-        </div>\n
-      </div-->\n
+    <form class="save_form ui-body-c" novalidate>\n
+      <button type="submit" class="ui-btn ui-btn-b ui-btn-inline\n
+        ui-icon-edit ui-btn-icon-right ui-screen-hidden">Save</button>\n
 \n
       <div data-gadget-url="gadget_erp5_form.html"\n
               data-gadget-scope="erp5_form"\n
@@ -282,7 +277,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.51523.55.16605</string> </value>
+                <value> <string>937.59883.50986.57548</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -300,7 +295,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411991218.07</float>
+                        <float>1412085640.69</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_js.xml
index 77c675f924..80b03d8e70 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_form_view_editable_js.xml
@@ -132,9 +132,15 @@
     .declareAcquiredMethod("whoWantToDisplayThisPage", "whoWantToDisplayThisPage")\n
     .declareAcquiredMethod("whoWantToDisplayThis", "whoWantToDisplayThis")\n
     .declareAcquiredMethod("renderPageHeader", "renderPageHeader")\n
+    .declareAcquiredMethod("notifySubmitting", "notifySubmitting")\n
+    .declareAcquiredMethod("notifySubmitted", "notifySubmitted")\n
+\n
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
+    .declareMethod(\'triggerSubmit\', function () {\n
+      this.props.element.querySelector(\'button\').click();\n
+    })\n
     .declareMethod(\'render\', function (options) {\n
       var erp5_document = options.erp5_document,\n
         form_gadget = this;\n
@@ -144,18 +150,27 @@
 \n
       return form_gadget.getDeclaredGadget("erp5_form")\n
         .push(function (erp5_form) {\n
-          var form_options = options.erp5_form || {};\n
+          var form_options = options.erp5_form || {},\n
+            new_content_action;\n
 \n
           form_options.erp5_document = options.erp5_document;\n
           form_options.form_definition = options.form_definition;\n
           form_options.view = options.view;\n
+\n
+          new_content_action = options.erp5_document._links.action_object_new_content_action;\n
+          if (new_content_action !== undefined) {\n
+            new_content_action = form_gadget.whoWantToDisplayThisPage({name: new_content_action.name});\n
+          } else {\n
+            new_content_action = "";\n
+          }\n
 \n
           return RSVP.all([\n
             erp5_form.render(form_options),\n
             form_gadget.whoWantToDisplayThis(options.jio_key),\n
             form_gadget.whoWantToDisplayThisPage({page: "tab", name: options.view}),\n
             form_gadget.whoWantToDisplayThisPage({page: "action", name: options.view, editable: true}),\n
-            form_gadget.whoWantToDisplayThisPage({page: "breadcrumb", name: options.view, editable: true})\n
+            form_gadget.whoWantToDisplayThisPage({page: "breadcrumb", name: options.view, editable: true}),\n
+            new_content_action\n
           ]);\n
         })\n
         .push(function (all_result) {\n
@@ -165,10 +180,11 @@
             cut_url: "",\n
             actions_url: all_result[3],\n
             delete_url: "",\n
-            add_url: "",\n
+            add_url: all_result[5],\n
             view_url: all_result[1],\n
             page_title: options.erp5_document.title,\n
-            breadcrumb_url: all_result[4]\n
+            breadcrumb_url: all_result[4],\n
+            save_action: true\n
           });\n
         });\n
 \n
@@ -176,16 +192,30 @@
 \n
 \n
     .declareService(function () {\n
+      ////////////////////////////////////\n
+      // Form submit listening\n
+      ////////////////////////////////////\n
       var form_gadget = this;\n
 \n
       function formSubmit() {\n
+        var erp5_form;\n
         return form_gadget.getDeclaredGadget("erp5_form")\n
-          .push(function (erp5_form) {\n
-            return erp5_form.getContent();\n
+          .push(function (gadget) {\n
+            erp5_form = gadget;\n
+            return erp5_form.checkValidity();\n
           })\n
-          .push(function (data) {\n
-            data._id = form_gadget.props.id;\n
-            return form_gadget.aq_put(data, {"_view": form_gadget.props.view});\n
+          .push(function (validity) {\n
+            if (validity) {\n
+              return erp5_form.getContent()\n
+                .push(function (data) {\n
+                  data._id = form_gadget.props.id;\n
+                  return RSVP.all([\n
+                    form_gadget.aq_put(data, {"_view": form_gadget.props.view}),\n
+                    form_gadget.notifySubmitting()\n
+                  ]);\n
+                })\n
+                .push(form_gadget.notifySubmitted.bind(form_gadget));\n
+            }\n
           });\n
       }\n
 \n
@@ -333,7 +363,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58431.61718.64460</string> </value>
+                <value> <string>937.64076.58625.38690</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -351,7 +381,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411991083.0</float>
+                        <float>1412257242.7</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_formpage_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_formpage_js.xml
index a6a48f3fef..7023567b72 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_formpage_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_pt_formpage_js.xml
@@ -132,6 +132,12 @@
     /////////////////////////////////////////////////////////////////\n
     // declared methods\n
     /////////////////////////////////////////////////////////////////\n
+    .declareMethod(\'triggerSubmit\', function () {\n
+      return this.getDeclaredGadget(\'fg\')\n
+        .push(function (g) {\n
+          return g.triggerSubmit();\n
+        })\n
+    })\n
     .declareMethod("render", function (options) {\n
       var gadget = this,\n
         element = gadget.props.element,\n
@@ -319,7 +325,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.58334.39803.33518</string> </value>
+                <value> <string>937.58335.7310.17476</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -337,7 +343,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411985226.68</float>
+                        <float>1412239088.85</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_html.xml
index 143ae54e17..8486da87d7 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_html.xml
@@ -117,6 +117,8 @@
     <script src="renderjs.js" type="text/javascript"></script>\n
     <!-- custom script -->\n
     <script src="gadget_erp5_field_string.js" type="text/javascript"></script>\n
+    <script src="gadget_global.js" type="text/javascript"></script>\n
+\n
 \n
   </head>\n
   <body>\n
@@ -245,7 +247,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>sven</string> </value>
+                <value> <string>romain</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -259,7 +261,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.51417.2754.60177</string> </value>
+                <value> <string>937.51526.35217.14489</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -277,7 +279,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411576712.22</float>
+                        <float>1412257603.97</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_js.xml
index 9f8a184c67..7a82faee75 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_stringfield_js.xml
@@ -99,9 +99,9 @@
         </item>
         <item>
             <key> <string>text_content</string> </key>
-            <value> <string>/*global window, rJS */\n
+            <value> <string>/*global window, rJS, RSVP, loopEventListener */\n
 /*jslint indent: 2, maxerr: 3 */\n
-(function (window, rJS) {\n
+(function (window, rJS, RSVP, loopEventListener) {\n
   "use strict";\n
 \n
   rJS(window)\n
@@ -111,6 +111,11 @@
           gadget.element = element;\n
         });\n
     })\n
+\n
+    .declareAcquiredMethod("notifyValid", "notifyValid")\n
+    .declareAcquiredMethod("notifyInvalid", "notifyInvalid")\n
+    .declareAcquiredMethod("notifyChange", "notifyChange")\n
+\n
     .declareMethod(\'render\', function (options) {\n
       var input = this.element.querySelector(\'input\'),\n
         field_json = options.field_json || {};\n
@@ -120,6 +125,9 @@
       );\n
       input.setAttribute(\'name\', field_json.key);\n
       input.setAttribute(\'title\', field_json.title);\n
+      if (field_json.required === 1) {\n
+        input.setAttribute(\'required\', \'required\');\n
+      }\n
       if (field_json.editable !== 1) {\n
         input.setAttribute(\'readonly\', \'readonly\');\n
         input.setAttribute(\'data-wrapper-class\', \'ui-state-readonly\');\n
@@ -133,9 +141,62 @@
         result = {};\n
       result[input.getAttribute(\'name\')] = input.value;\n
       return result;\n
+    })\n
+\n
+    .declareMethod(\'checkValidity\', function () {\n
+      var result;\n
+      result = this.element.querySelector(\'input\').checkValidity();\n
+      if (result) {\n
+        return this.notifyValid()\n
+          .push(function () {\n
+            return result;\n
+          });\n
+      }\n
+      return result;\n
+    })\n
+\n
+    .declareService(function () {\n
+      ////////////////////////////////////\n
+      // Check field validity when the value changes\n
+      ////////////////////////////////////\n
+      var field_gadget = this;\n
+\n
+      function notifyChange() {\n
+        return RSVP.all([\n
+          field_gadget.checkValidity(),\n
+          field_gadget.notifyChange()\n
+        ]);\n
+      }\n
+\n
+      // Listen to input change\n
+      return loopEventListener(\n
+        field_gadget.element.querySelector(\'input\'),\n
+        \'change\',\n
+        false,\n
+        notifyChange\n
+      );\n
+    })\n
+\n
+    .declareService(function () {\n
+      ////////////////////////////////////\n
+      // Inform when the field input is invalid\n
+      ////////////////////////////////////\n
+      var field_gadget = this;\n
+\n
+      function notifyInvalid(evt) {\n
+        return field_gadget.notifyInvalid(evt.target.validationMessage);\n
+      }\n
+\n
+      // Listen to input change\n
+      return loopEventListener(\n
+        field_gadget.element.querySelector(\'input\'),\n
+        \'invalid\',\n
+        false,\n
+        notifyInvalid\n
+      );\n
     });\n
 \n
-}(window, rJS));</string> </value>
+}(window, rJS, RSVP, loopEventListener));</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
@@ -256,7 +317,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>sven</string> </value>
+                <value> <string>romain</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -270,7 +331,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.51382.41153.54784</string> </value>
+                <value> <string>937.64311.60842.27084</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -288,7 +349,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411568284.24</float>
+                        <float>1412257626.39</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_textareafield_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_textareafield_js.xml
index f0623aa7e3..de0a40ba61 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_textareafield_js.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_textareafield_js.xml
@@ -118,7 +118,9 @@
       textarea.value = field_json.value || field_json.default || "";\n
       textarea.setAttribute(\'name\', field_json.key);\n
       textarea.setAttribute(\'title\', field_json.title);\n
-\n
+      if (field_json.required === 1) {\n
+        textarea.setAttribute(\'required\', \'required\');\n
+      }\n
       if (field_json.editable !== 1) {\n
         textarea.setAttribute(\'readonly\', \'readonly\');\n
         textarea.className += "ui-state-readonly";\n
@@ -254,7 +256,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>sven</string> </value>
+                <value> <string>romain</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -268,7 +270,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>937.51406.65298.39270</string> </value>
+                <value> <string>937.59950.21418.24371</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -286,7 +288,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1411570045.73</float>
+                        <float>1412257665.71</float>
                         <string>GMT</string>
                       </tuple>
                     </state>
-- 
2.30.9