From c27b1d1bd21bd56db09391645a01cd849cfd8a41 Mon Sep 17 00:00:00 2001
From: Romain Courteaud <romain@nexedi.com>
Date: Fri, 14 Oct 2016 09:30:56 +0000
Subject: [PATCH] [erp5_web_renderjs_ui] Reimplement list field

Try to reduce number of DOM modifications.
Display value even if not present in the item list.
---
 .../rjs_gadget_erp5_appcache.xml              |   6 +-
 .../rjs_gadget_erp5_listfield_html.html       |  10 -
 .../rjs_gadget_erp5_listfield_html.xml        |   8 +-
 .../rjs_gadget_erp5_listfield_js.js           | 205 +++++------
 .../rjs_gadget_erp5_listfield_js.xml          |   4 +-
 .../rjs_gadget_html5_select_html.html         |  23 ++
 .../rjs_gadget_html5_select_html.xml          | 324 ++++++++++++++++++
 .../rjs_gadget_html5_select_js.js             | 142 ++++++++
 .../rjs_gadget_html5_select_js.xml            | 320 +++++++++++++++++
 9 files changed, 899 insertions(+), 143 deletions(-)
 create mode 100644 bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.html
 create mode 100644 bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.xml
 create mode 100644 bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.js
 create mode 100644 bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.xml

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 864edc783a..fa640bb4c5 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
@@ -220,6 +220,8 @@ gadget_html5_input.html\n
 gadget_html5_input.js\n
 gadget_html5_textarea.html\n
 gadget_html5_textarea.js\n
+gadget_html5_select.html\n
+gadget_html5_select.js\n
 gadget_erp5_global.js\n
 gadget_jio.html\n
 gadget_jio.js\n
@@ -363,7 +365,7 @@ NETWORK:\n
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>954.27350.45081.38075</string> </value>
+                <value> <string>954.38476.56174.42734</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -381,7 +383,7 @@ NETWORK:\n
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1475763290.3</float>
+                        <float>1476437355.22</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.html b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.html
index 778ec46dd7..9bc16dad6a 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.html
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.html
@@ -8,20 +8,10 @@
     <!-- renderjs -->
     <script src="rsvp.js" type="text/javascript"></script>
     <script src="renderjs.js" type="text/javascript"></script>
-    <script src="handlebars.js" type="text/javascript"></script>
     <!-- custom script -->
     <script src="gadget_erp5_field_list.js" type="text/javascript"></script>
 
-    <script id="option-template" type="text/x-handlebars-template">
-      <option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
-    </script>
-
-    <script id="selected-option-template" type="text/x-handlebars-template">
-      <option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
-    </script>
-
   </head>
   <body>
-    <select />
   </body>
 </html>
\ No newline at end of file
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.xml
index 0b7bd8e27d..d7ad097bd5 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.xml
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_html.xml
@@ -220,7 +220,7 @@
             </item>
             <item>
                 <key> <string>actor</string> </key>
-                <value> <string>super_sven</string> </value>
+                <value> <string>zope</string> </value>
             </item>
             <item>
                 <key> <string>comment</string> </key>
@@ -234,7 +234,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>939.43978.9403.31744</string> </value>
+                <value> <string>954.37505.27238.51626</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -252,8 +252,8 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1419418540.22</float>
-                        <string>GMT</string>
+                        <float>1476431000.28</float>
+                        <string>UTC</string>
                       </tuple>
                     </state>
                   </object>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.js
index d015ff2368..046b06b2a6 100644
--- a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.js
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listfield_js.js
@@ -1,148 +1,103 @@
-/*global window, rJS, Handlebars, document, RSVP, loopEventListener*/
-/*jslint nomen: true, indent: 2, maxerr: 3 */
-(function (window, rJS, Handlebars, document, RSVP) {
+/*global window, rJS, loopEventListener*/
+/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
+(function (window, rJS) {
   "use strict";
 
-  /////////////////////////////////////////////////////////////////
-  // Handlebars
-  /////////////////////////////////////////////////////////////////
-  // Precompile the templates while loading the first gadget instance
-  var gadget_klass = rJS(window),
-    option_source = gadget_klass.__template_element
-                      .getElementById("option-template")
-                      .innerHTML,
-    option_template = Handlebars.compile(option_source),
-    selected_option_source = gadget_klass.__template_element
-                               .getElementById("selected-option-template")
-                               .innerHTML,
-    selected_option_template = Handlebars.compile(selected_option_source);
-
-  gadget_klass
-    .ready(function (g) {
-      return g.getElement()
-        .push(function (element) {
-          g.element = element;
-        });
+  rJS(window)
+    .setState({
+      tag: 'p'
     })
 
-    //////////////////////////////////////////////
-    // acquired method
-    //////////////////////////////////////////////
-    .declareAcquiredMethod("translateHtml", "translateHtml")
-    .declareAcquiredMethod("notifyValid", "notifyValid")
-    .declareAcquiredMethod("notifyInvalid", "notifyInvalid")
-    .declareAcquiredMethod("notifyChange", "notifyChange")
-    .declareMethod('getTextContent', function () {
-      var select = this.element.querySelector('select');
-      return select.options[select.selectedIndex || 0].text;
-    })
     .declareMethod('render', function (options) {
-      var i,
-        template,
-        gadget = this,
-        select = this.element.querySelector('select'),
-        field_json = options.field_json,
-        tmp = "",
-        wrap = document.createElement("select");
+      var field_json = options.field_json || {},
+        state_dict = {
+          value: field_json.value || field_json.default || "",
+          item_list: JSON.stringify(field_json.items),
+          editable: field_json.editable,
+          required: field_json.required,
+          name: field_json.key,
+          title: field_json.title
+        };
+      return this.changeState(state_dict);
+    })
 
-      select.setAttribute('name', field_json.key);
-      for (i = 0; i < field_json.items.length; i += 1) {
-        if (field_json.items[i][1] === field_json.default) {
-          template = selected_option_template;
-        } else {
-          template = option_template;
+    .onStateChange(function (modification_dict) {
+      var element = this.element,
+        url,
+        result,
+        i,
+        text_content,
+        item_list,
+        state = {};
+
+      for (i in this.state) {
+        if (this.state.hasOwnProperty(i)) {
+          state[i] = this.state[i];
         }
-        tmp += template({
-          value: field_json.items[i][1],
-          text: field_json.items[i][0]
-        });
       }
+      state.item_list = JSON.parse(this.state.item_list);
 
-      // need a <select> for transport
-      wrap.innerHTML = tmp;
-
-      return new RSVP.Queue()
-        .push(function () {
-          return gadget.translateHtml(wrap.outerHTML);
-        })
-        .push(function (my_translated_html) {
-          // XXX: no fan...
-          var select_div,
-            div = document.createElement("div");
-
-          div.innerHTML = my_translated_html;
-
-          select_div = div.querySelector("select");
-          select.innerHTML = select_div.innerHTML;
+      if (modification_dict.hasOwnProperty('editable')) {
+        if (this.state.editable) {
+          url = 'gadget_html5_select.html';
+        } else {
+          url = 'gadget_html5_element.html';
 
-          if (field_json.required === 1) {
-            select.setAttribute('required', 'required');
+          item_list = state.item_list;
+          for (i = 0; i < item_list.length; i += 1) {
+            if (item_list[i][1] === this.state.value) {
+              text_content = item_list[i][0];
+            }
           }
-          if (field_json.editable !== 1) {
-            select.setAttribute('readonly', 'readonly');
-            select.setAttribute('data-wrapper-class', 'ui-state-readonly');
-            // select.setAttribute('disabled', 'disabled');
-
+          if (text_content === undefined) {
+            text_content = '??? (' + this.state.value + ')';
           }
-        });
-    })
-    .declareMethod('checkValidity', function () {
-      var result;
-      result = this.element.querySelector('select').checkValidity();
-      if (result) {
-        return this.notifyValid()
-          .push(function () {
-            return result;
+          state.text_content = text_content;
+
+        }
+        result = this.declareGadget(url, {scope: 'sub'})
+          .push(function (input) {
+            // Clear first to DOM, append after to reduce flickering/manip
+            while (element.firstChild) {
+              element.removeChild(element.firstChild);
+            }
+            element.appendChild(input.element);
+            return input;
           });
+      } else {
+        result = this.getDeclaredGadget('sub');
       }
-      return result;
-    })
-    .declareMethod('getContent', function () {
-      var input = this.element.querySelector('select'),
-        result = {};
-      result[input.getAttribute('name')] = input.options[input.selectedIndex].value;
-      return result;
+      return result
+        .push(function (input) {
+          return input.render(state);
+        });
     })
 
-    .declareService(function () {
-      ////////////////////////////////////
-      // Check field validity when the value changes
-      ////////////////////////////////////
-      var field_gadget = this;
-
-      function notifyChange() {
-        return RSVP.all([
-          field_gadget.checkValidity(),
-          field_gadget.notifyChange()
-        ]);
+    .declareMethod('getContent', function () {
+      if (this.state.editable) {
+        return this.getDeclaredGadget('sub')
+          .push(function (gadget) {
+            return gadget.getContent();
+          });
       }
-
-      // Listen to input change
-      return loopEventListener(
-        field_gadget.element.querySelector('select'),
-        'change',
-        false,
-        notifyChange
-      );
+      return {};
     })
 
-    .declareService(function () {
-      ////////////////////////////////////
-      // Inform when the field input is invalid
-      ////////////////////////////////////
-      var field_gadget = this;
+    .declareMethod('getTextContent', function () {
+      return this.getDeclaredGadget('sub')
+        .push(function (gadget) {
+          return gadget.getTextContent();
+        });
+    })
 
-      function notifyInvalid(evt) {
-        return field_gadget.notifyInvalid(evt.target.validationMessage);
+    .declareMethod('checkValidity', function () {
+      if (this.state.editable) {
+        return this.getDeclaredGadget('sub')
+          .push(function (gadget) {
+            return gadget.checkValidity();
+          });
       }
-
-      // Listen to input change
-      return loopEventListener(
-        field_gadget.element.querySelector('select'),
-        'invalid',
-        false,
-        notifyInvalid
-      );
+      return true;
     });
 
-}(window, rJS, Handlebars, document, RSVP));
\ No newline at end of file
+}(window, rJS));
\ No newline at end of file
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 6d50a145fe..e39b11ca9c 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
@@ -230,7 +230,7 @@
             </item>
             <item>
                 <key> <string>serial</string> </key>
-                <value> <string>952.64761.25287.18397</string> </value>
+                <value> <string>954.38571.58992.44731</string> </value>
             </item>
             <item>
                 <key> <string>state</string> </key>
@@ -248,7 +248,7 @@
                     </tuple>
                     <state>
                       <tuple>
-                        <float>1470231990.11</float>
+                        <float>1476437096.88</float>
                         <string>UTC</string>
                       </tuple>
                     </state>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.html b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.html
new file mode 100644
index 0000000000..84ace7d89a
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+    <meta name="viewport" content="width=device-width, user-scalable=no" />
+    <title>HTML5 Select</title>
+    <!-- renderjs -->
+    <script src="rsvp.js" type="text/javascript"></script>
+    <script src="renderjs.js" type="text/javascript"></script>
+    <script src="handlebars.js" type="text/javascript"></script>
+    <!-- custom script -->
+    <script id="option-template" type="text/x-handlebars-template">
+      <option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
+    </script>
+
+    <script id="selected-option-template" type="text/x-handlebars-template">
+      <option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
+    </script>
+
+    <script src="gadget_html5_select.js" type="text/javascript"></script>
+  </head>
+  <body><select /></body>
+</html>
\ No newline at end of file
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.xml
new file mode 100644
index 0000000000..447193fddf
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_html.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Web Page" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Access_contents_information_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Anonymous</string>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Add_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Change_local_roles_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Modify_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_View_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Anonymous</string>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_md5</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>gadget_html5_select.html</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>rjs_gadget_html5_select_html</string> </value>
+        </item>
+        <item>
+            <key> <string>language</string> </key>
+            <value> <string>en</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Web Page</string> </value>
+        </item>
+        <item>
+            <key> <string>short_title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Gadget HTML5 Select</string> </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>001</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>document_publication_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>edit_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>processing_status_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>publish_alive</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476275989.52</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+            <item>
+                <key> <string>validation_state</string> </key>
+                <value> <string>published_alive</string> </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>edit</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value>
+                  <none/>
+                </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>serial</string> </key>
+                <value> <string>954.35895.54156.10325</string> </value>
+            </item>
+            <item>
+                <key> <string>state</string> </key>
+                <value> <string>current</string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476277011.48</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+  <record id="5" aka="AAAAAAAAAAU=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>detect_converted_file</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>external_processing_state</string> </key>
+                <value> <string>converted</string> </value>
+            </item>
+            <item>
+                <key> <string>serial</string> </key>
+                <value> <string>0.0.0.0</string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476275907.45</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.js b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.js
new file mode 100644
index 0000000000..b33c334baa
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.js
@@ -0,0 +1,142 @@
+/*global window, rJS, RSVP, Handlebars */
+/*jslint indent: 2, maxerr: 3, maxlen: 80, nomen: true */
+(function (window, rJS, RSVP, Handlebars) {
+  "use strict";
+
+  // How to change html selected option using JavaScript?
+  // http://stackoverflow.com/a/20662180
+
+  /////////////////////////////////////////////////////////////////
+  // Handlebars
+  /////////////////////////////////////////////////////////////////
+  // Precompile the templates while loading the first gadget instance
+  var gadget_klass = rJS(window),
+    option_source = gadget_klass.__template_element
+                      .getElementById("option-template")
+                      .innerHTML,
+    option_template = Handlebars.compile(option_source),
+    selected_option_source = gadget_klass.__template_element
+                               .getElementById("selected-option-template")
+                               .innerHTML,
+    selected_option_template = Handlebars.compile(selected_option_source);
+
+  gadget_klass
+    .setState({
+      editable: false,
+      value: undefined,
+      checked: undefined,
+      title: '',
+      item_list: [],
+      required: false
+    })
+
+    .declareMethod('render', function (options) {
+      var state_dict = {
+          value: options.value || "",
+          item_list: JSON.stringify(options.item_list),
+          editable: options.editable,
+          required: options.required,
+          name: options.name,
+          title: options.title
+        };
+      return this.changeState(state_dict);
+    })
+
+    .onStateChange(function (modification_dict) {
+      var i,
+        found = false,
+        template,
+        select = this.element.querySelector('select'),
+        item_list = JSON.parse(this.state.item_list),
+        tmp = "";
+
+      select.setAttribute('name', this.state.name);
+      if (this.state.title) {
+        select.setAttribute('title', this.state.title);
+      }
+
+      if (this.state.required) {
+        select.required = true;
+      } else {
+        select.required = false;
+      }
+
+      if (this.state.editable) {
+        select.readonly = true;
+      } else {
+        select.readonly = false;
+      }
+
+      if (modification_dict.hasOwnProperty('value') ||
+          modification_dict.hasOwnProperty('item_list')) {
+        for (i = 0; i < item_list.length; i += 1) {
+          if (item_list[i][1] === this.state.value) {
+            template = selected_option_template;
+            found = true;
+          } else {
+            template = option_template;
+          }
+          tmp += template({
+            value: item_list[i][1],
+            text: item_list[i][0]
+          });
+        }
+
+        if (!found) {
+          tmp += selected_option_template({
+            value: this.state.value,
+            text: '??? (' + this.state.value + ')'
+          });
+        }
+        select.innerHTML = tmp;
+      }
+    })
+
+    .declareMethod('getContent', function () {
+      var result = {},
+        select = this.element.querySelector('select');
+      if (this.state.editable) {
+        result[select.getAttribute('name')] =
+          select.options[select.selectedIndex].value;
+      }
+      return result;
+    })
+
+    .declareMethod('getTextContent', function () {
+      var select = this.element.querySelector('select');
+      return select.options[select.selectedIndex].text;
+    })
+
+    .declareAcquiredMethod("notifyValid", "notifyValid")
+    .declareMethod('checkValidity', function () {
+      var result = this.element.querySelector('select').checkValidity();
+      if (result) {
+        return this.notifyValid()
+          .push(function () {
+            return result;
+          });
+      }
+      return result;
+    })
+
+    .declareAcquiredMethod("notifyChange", "notifyChange")
+    .onEvent('change', function () {
+      return RSVP.all([
+        this.checkValidity(),
+        this.notifyChange()
+      ]);
+    }, false, false)
+    .onEvent('input', function () {
+      return RSVP.all([
+        this.checkValidity(),
+        this.notifyChange()
+      ]);
+    }, false, false)
+
+    .declareAcquiredMethod("notifyInvalid", "notifyInvalid")
+    .onEvent('invalid', function (evt) {
+      // invalid event does not bubble
+      return this.notifyInvalid(evt.target.validationMessage);
+    }, true, false);
+
+}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
diff --git a/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.xml b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.xml
new file mode 100644
index 0000000000..70623a37cd
--- /dev/null
+++ b/bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_html5_select_js.xml
@@ -0,0 +1,320 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Web Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Access_contents_information_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Anonymous</string>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Add_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Change_local_roles_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Modify_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_View_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Anonymous</string>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Associate</string>
+                <string>Auditor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_md5</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>gadget_html5_select.js</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>rjs_gadget_html5_select_js</string> </value>
+        </item>
+        <item>
+            <key> <string>language</string> </key>
+            <value> <string>en</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Web Script</string> </value>
+        </item>
+        <item>
+            <key> <string>short_title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Gadget HTML5 Select JS</string> </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>001</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>document_publication_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>edit_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>processing_status_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>publish_alive</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476275996.9</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+            <item>
+                <key> <string>validation_state</string> </key>
+                <value> <string>published_alive</string> </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>edit</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value>
+                  <none/>
+                </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>serial</string> </key>
+                <value> <string>954.38576.23571.27630</string> </value>
+            </item>
+            <item>
+                <key> <string>state</string> </key>
+                <value> <string>current</string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476437054.93</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+  <record id="5" aka="AAAAAAAAAAU=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
+    </pickle>
+    <pickle>
+      <tuple>
+        <none/>
+        <list>
+          <dictionary>
+            <item>
+                <key> <string>action</string> </key>
+                <value> <string>detect_converted_file</string> </value>
+            </item>
+            <item>
+                <key> <string>actor</string> </key>
+                <value> <string>zope</string> </value>
+            </item>
+            <item>
+                <key> <string>comment</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>error_message</string> </key>
+                <value> <string></string> </value>
+            </item>
+            <item>
+                <key> <string>external_processing_state</string> </key>
+                <value> <string>converted</string> </value>
+            </item>
+            <item>
+                <key> <string>serial</string> </key>
+                <value> <string>0.0.0.0</string> </value>
+            </item>
+            <item>
+                <key> <string>time</string> </key>
+                <value>
+                  <object>
+                    <klass>
+                      <global name="DateTime" module="DateTime.DateTime"/>
+                    </klass>
+                    <tuple>
+                      <none/>
+                    </tuple>
+                    <state>
+                      <tuple>
+                        <float>1476275907.43</float>
+                        <string>UTC</string>
+                      </tuple>
+                    </state>
+                  </object>
+                </value>
+            </item>
+          </dictionary>
+        </list>
+      </tuple>
+    </pickle>
+  </record>
+</ZopeData>
-- 
2.30.9