Commit 5cacbd7c authored by Romain Courteaud's avatar Romain Courteaud

[erp5_web_renderjs_ui] Drop relation field select list if focus is lost

Display relation field select list if focus is activated
Fixup click handling
parent 2c08de36
...@@ -28,21 +28,14 @@ ...@@ -28,21 +28,14 @@
<script id="relation-listview-template" type="text/x-handlebars-template"> <script id="relation-listview-template" type="text/x-handlebars-template">
{{#if list.length}} {{#if list.length}}
<!--li class="ui-autocomplete ui-li ui-li-divider ui-bar-inherit ui-first-child" role="heading">Select from the {{list.length}} Search Results</li-->
{{#each list}} {{#each list}}
<li class="ui-li-static ui-body-inherit ui-icon-sign-in ui-btn-icon-right" data-relative-url="{{id}}" data-uid="{{uid}}">{{value}}</li> <li class="ui-li-static ui-body-inherit ui-icon-sign-in ui-btn-icon-right" data-relative-url="{{id}}" data-uid="{{uid}}">{{value}}</li>
{{/each}} {{/each}}
{{/if}}
{{#each type}} {{#each type}}
<li class="ui-li-static ui-body-inherit ui-bar-inherit ui-icon-plus ui-btn-icon-right" data-i18n="Create New" data-create-object="{{value}}" name="{{name}}">Create New <li class="ui-li-static ui-body-inherit ui-bar-inherit ui-icon-plus ui-btn-icon-right" data-i18n="Create New" data-create-object="{{value}}" name="{{name}}">Create New
<span data-create-object="{{value}}"> {{name}}: {{../value}}</span></li> <span> {{name}}: {{../value}}</span></li>
{{/each}}
{{else}}
<!--li class="ui-autocomplete ui-li ui-li-divider ui-bar-inherit ui-first-child" role="heading">No result</li-->
{{#each type}}
<li class="ui-li-static ui-body-inherit ui-bar-inherit ui-icon-plus ui-btn-icon-right" data-i18n="Create New" data-create-object="{{value}}" name="{{name}}">Create New
<span data-create-object="{{value}}"> {{name}}: {{../value}}</span></li>
{{/each}} {{/each}}
{{/if}}
<li class="ui-li-static ui-body-inherit ui-last-child ui-bar-inherit ui-icon-search ui-btn-icon-right" data-explore=true data-i18n="Explore the Search Result List" >Explore the Search Result List</li> <li class="ui-li-static ui-body-inherit ui-last-child ui-bar-inherit ui-icon-search ui-btn-icon-right" data-explore=true data-i18n="Explore the Search Result List" >Explore the Search Result List</li>
</script> </script>
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.26902.40110.53777</string> </value> <value> <string>966.58720.16411.15940</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1515764984.12</float> <float>1523881405.47</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -211,11 +211,11 @@ ...@@ -211,11 +211,11 @@
buildEditableInputHTML(gadget); buildEditableInputHTML(gadget);
} }
gadget.element.querySelector(".search_ul").innerHTML = "";
// Display the airplane link or the search button // Display the airplane link or the search button
if ((gadget.state.value_relative_url) || (gadget.state.value_text)) { if ((gadget.state.value_relative_url) || (gadget.state.value_text)) {
createEditableLink(gadget, JUMP_UNKNOWN_CLASS_STR); createEditableLink(gadget, JUMP_UNKNOWN_CLASS_STR);
} else { } else {
gadget.element.querySelector(".search_ul").innerHTML = "";
return createEditableButton(gadget, SEARCH_CLASS_STR); return createEditableButton(gadget, SEARCH_CLASS_STR);
} }
...@@ -225,7 +225,6 @@ ...@@ -225,7 +225,6 @@
var plane = gadget.element.querySelector("a"), var plane = gadget.element.querySelector("a"),
ul = gadget.element.querySelector(".search_ul"), ul = gadget.element.querySelector(".search_ul"),
input = gadget.element.querySelector("input"); input = gadget.element.querySelector("input");
ul.innerHTML = "";
plane.href = ''; plane.href = '';
if (input.value !== gadget.state.value_text) { if (input.value !== gadget.state.value_text) {
...@@ -378,15 +377,20 @@ ...@@ -378,15 +377,20 @@
data_uid, data_uid,
data_portal_type, data_portal_type,
data_explore, data_explore,
new_state = {}; new_state = {},
tag_name = evt.target.tagName.toLowerCase();
if (evt.target.tagName.toLowerCase() === 'button') { if (tag_name === 'button') {
// Go to the search listbox // Go to the search listbox
return redirectToTheSearchListbox(gadget); return redirectToTheSearchListbox(gadget);
} }
if (evt.target.tagName.toLowerCase() === 'li') { if (tag_name === 'li' || tag_name === 'span') {
if (tag_name === 'li') {
li = evt.target; li = evt.target;
} else {
li = evt.target.parentElement;
}
data_relative_url = li.getAttribute("data-relative-url"); data_relative_url = li.getAttribute("data-relative-url");
data_uid = li.getAttribute("data-uid"); data_uid = li.getAttribute("data-uid");
data_portal_type = li.getAttribute("data-create-object"); data_portal_type = li.getAttribute("data-create-object");
...@@ -395,6 +399,7 @@ ...@@ -395,6 +399,7 @@
// User want to create a new document // User want to create a new document
if (data_portal_type) { if (data_portal_type) {
new_state.value_portal_type = data_portal_type; new_state.value_portal_type = data_portal_type;
new_state.has_focus = false;
return gadget.changeState(new_state); return gadget.changeState(new_state);
} }
...@@ -403,6 +408,7 @@ ...@@ -403,6 +408,7 @@
new_state.value_text = li.textContent; new_state.value_text = li.textContent;
new_state.value_relative_url = data_relative_url; new_state.value_relative_url = data_relative_url;
new_state.value_uid = data_uid; new_state.value_uid = data_uid;
new_state.has_focus = false;
return gadget.changeState(new_state); return gadget.changeState(new_state);
} }
...@@ -414,10 +420,27 @@ ...@@ -414,10 +420,27 @@
}, false, false) }, false, false)
.onEvent('blur', function (evt) { .onEvent('blur', function (evt) {
if (evt.target === this.element.querySelector(".search_ul")) { var gadget = this;
return this.changeState({ if (evt.target.tagName.toLowerCase() === 'input') {
return new RSVP.Queue()
.push(function () {
// Wait a bit to handle click :/
return RSVP.delay(200);
})
.push(function () {
return gadget.changeState({
has_focus: false has_focus: false
}); });
});
}
}, true, false)
.onEvent('focus', function (evt) {
var gadget = this;
if (evt.target.tagName.toLowerCase() === 'input') {
return gadget.changeState({
has_focus: true
});
} }
}, true, false) }, true, false)
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.15380.34560.33723</string> </value> <value> <string>966.58749.49498.3481</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352011.0</float> <float>1523882792.37</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -51,26 +51,31 @@ ...@@ -51,26 +51,31 @@
<!-- Successful save does not mingle with editability --> <!-- Successful save does not mingle with editability -->
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//input[@name='field_my_foo_category_title']</td><td></td></tr> <td>//input[@name='field_my_foo_category_title']</td><td></td></tr>
<tr><td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>focus</td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_foo_category_title']//li</td><td></td></tr>
<tr><td>type</td> <tr><td>type</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_foo_category_title']</td>
<td></td></tr> <td></td></tr>
<tr><td>fireEvent</td> <tr><td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_foo_category_title']</td>
<td>input</td></tr> <td>input</td></tr>
<tr><td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>blur</td></tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Save'][contains(@class, 'ui-icon-warning')]</td>
<td></td>
</tr>
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//input[@name='field_my_title']</td><td></td></tr> <td>//input[@name='field_my_title']</td><td></td></tr>
<tr><td>type</td> <tr><td>type</td>
<td>field_my_title</td> <td>field_my_title</td>
<td>QWERTY</td></tr> <td>QWERTY</td></tr>
<tr><td>waitForElementPresent</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<td>//div[@data-gadget-scope='header']//button[text()='Save' and @type='submit']</td><td></td></tr>
<tr><td>click</td>
<td>//div[@data-gadget-scope='header']//button[text()='Save' and @type='submit']</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Data updated.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block>
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view_editable.html']</td><td></td></tr> <td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view_editable.html']</td><td></td></tr>
......
...@@ -154,6 +154,11 @@ ...@@ -154,6 +154,11 @@
<td>A New Foo</td> <td>A New Foo</td>
</tr> </tr>
<tr>
<td>fireEvent</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//input</td>
<td>focus</td>
</tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//input</td> <td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//input</td>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testRelationFieldNothingSelectedInList</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr>
<td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<!-- Initialize -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Add']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Document created.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_my_successor_title']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_successor_title']</td>
<td>A new foo</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@name='Foo']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>blur</td>
</tr>
<tr>
<td>pause</td>
<td>500</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//li[@name='Foo']</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name='field_my_successor_title']</td>
<td>A new foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Save']</td>
<td></td>
</tr>
<tal:block tal:define="notification_configuration python: {'class': 'error',
'text': 'Input data has errors.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block>
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//span[text()='No such document was found.']</td>
<td></td>
</tr>
<!-- Still no list displayed -->
<tr>
<td>assertElementNotPresent</td>
<td>//li[@name='Foo']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>focus</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@name='Foo']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@name='Foo']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//a[contains(@class, "ui-icon-plus")]</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment