Commit 555356ce authored by Romain Courteaud's avatar Romain Courteaud

[erp5_web_renderjs_ui] RelationField: add checkValidity method

Prevent submitting the form if the relation field contains an unknown search string.
parent 43204aaf
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
url: field_json.url, url: field_json.url,
allow_creation: field_json.allow_creation, allow_creation: field_json.allow_creation,
portal_types: field_json.portal_types, portal_types: field_json.portal_types,
translated_portal_types: field_json.translated_portal_types, translated_portal_types: field_json.translated_portal_types,
relation_field_id: field_json.relation_field_id, relation_field_id: field_json.relation_field_id,
hidden: field_json.hidden, hidden: field_json.hidden,
// Force calling subfield render // Force calling subfield render
...@@ -234,7 +234,8 @@ ...@@ -234,7 +234,8 @@
} }
} }
//user remove all data //user remove all data
if (options.format === "erp5" && result[gadget.state.key].length === 0) { if (options.format === "erp5" &&
result[gadget.state.key].length === 0) {
result[gadget.state.key] = ""; result[gadget.state.key] = "";
} }
return result; return result;
...@@ -242,6 +243,47 @@ ...@@ -242,6 +243,47 @@
}); });
} }
return final_result; return final_result;
}, {mutex: 'changestate'})
.declareMethod('checkValidity', function () {
var context = this;
function checkSubContentValidity(node) {
var scope = node.getAttribute('data-gadget-scope');
if (scope !== null) {
return context.getDeclaredGadget(
node.getAttribute('data-gadget-scope')
)
.push(function (result) {
return result.checkValidity();
});
}
}
if (this.state.editable) {
return new RSVP.Queue()
.push(function () {
var promise_list = [],
i;
for (i = 0; i < context.element.childNodes.length; i += 1) {
promise_list.push(
checkSubContentValidity(context.element.childNodes[i])
);
}
return RSVP.all(promise_list);
})
.push(function (validity_list) {
var i;
for (i = 0; i < validity_list.length; i += 1) {
if (!validity_list[i]) {
return false;
}
}
return true;
});
}
return true;
}, {mutex: 'changestate'}); }, {mutex: 'changestate'});
}(window, rJS, RSVP, document)); }(window, rJS, RSVP, document));
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>970.11252.5060.21026</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321450.32</float> <float>1536588738.44</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -445,8 +445,18 @@ ...@@ -445,8 +445,18 @@
}, true, false) }, true, false)
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if ((this.state.value_text) && (
(this.state.value_relative_url === null) &&
(this.state.value_uid === null) &&
(this.state.value_portal_type === null)
)) {
return this.notifyInvalid("No such document was found")
.push(function () {
return false;
});
}
return true; return true;
}) }, {mutex: 'changestate'})
// XXX Use html5 input // XXX Use html5 input
.onEvent('invalid', function (evt) { .onEvent('invalid', function (evt) {
...@@ -455,10 +465,7 @@ ...@@ -455,10 +465,7 @@
}, true, false) }, true, false)
.onEvent('change', function () { .onEvent('change', function () {
return RSVP.all([ return this.notifyChange();
this.checkValidity(),
this.notifyChange()
]);
}, false, false) }, false, 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>966.58749.49498.3481</string> </value> <value> <string>970.16829.43481.45789</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>1523882792.37</float> <float>1536923390.01</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -85,6 +85,13 @@ ...@@ -85,6 +85,13 @@
} }
return result; return result;
}); });
}, {mutex: 'changestate'})
.declareMethod('checkValidity', function () {
return this.getDeclaredGadget("relation_input")
.push(function (input_gadget) {
return input_gadget.checkValidity();
});
}, {mutex: 'changestate'}); }, {mutex: 'changestate'});
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value> <value> <string>970.11323.28526.22766</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352110.99</float> <float>1536593071.17</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -17,60 +17,25 @@ ...@@ -17,60 +17,25 @@
<td></td> <td></td>
</tr> </tr>
<!-- Wait for gadget to be loaded --> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-url='${base_url}/web_site_module/renderjs_runner/gadget_erp5_pt_form_view_editable.html']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Title 1</td>
<td></td>
</tr>
<!-- Header has a save button --> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='header']//button[text()='Save' and @type='submit']</td>
<td></td>
</tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>field_my_foo_category_title</td> <td>field_my_title</td>
<td>QWERTY</td> <td>Foo Title 123</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>input</td>
</tr>
<tr>
<td>pause</td>
<td>1000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[@data-gadget-scope='header']//button[text()='Save' and @type='submit']</td>
<td></td>
</tr> </tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_save" />
<!--tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='header']//button[text()='Save' and @type='submit' and contains(@class, 'ui-icon-spinner')]</td>
<td></td>
</tr-->
<tr> <tr>
<td>waitForTextPresent</td> <td>waitForTextPresent</td>
<td>No such document was found</td> <td>Input is required but no input given.</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>verifyValue</td> <td>verifyValue</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_title']</td>
<td>QWERTY</td> <td>Foo Title 123</td>
</tr> </tr>
<tal:block tal:define="notification_configuration python: {'class': 'error', <tal:block tal:define="notification_configuration python: {'class': 'error',
......
...@@ -21,27 +21,24 @@ ...@@ -21,27 +21,24 @@
<td>renderjs_url</td></tr> <td>renderjs_url</td></tr>
<tr><td>open</td> <tr><td>open</td>
<td>${renderjs_url}/#/foo_module/1?editable=true</td><td></td></tr> <td>${renderjs_url}/#/foo_module/1?editable=true</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<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>
<tr><td>verifyElementNotPresent</td> <tr><td>verifyElementNotPresent</td>
<td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view.html']</td><td></td></tr> <td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view.html']</td><td></td></tr>
<!-- Unsuccessful save does not mingle with editability --> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr><td>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//input[@name='field_my_foo_category_title']</td><td></td></tr> <td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view_editable.html']</td><td></td></tr>
<tr><td>type</td> <tr><td>verifyElementNotPresent</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_view.html']</td><td></td></tr>
<td>QWERTY</td></tr>
<tr><td>fireEvent</td> <!-- Unsuccessful save does not mingle with editability -->
<td>//input[@name='field_my_foo_category_title']</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_save" />
<td>input</td></tr> <tal:block tal:define="notification_configuration python: {'class': 'error',
<tr><td>waitForElementPresent</td> 'text': 'Input data has errors.'}">
<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_notification" />
<tr><td>click</td> </tal:block>
<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" />
<tr><td>waitForTextPresent</td>
<td>Input data has errors.</td><td></td></tr>
<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>
...@@ -54,22 +51,23 @@ ...@@ -54,22 +51,23 @@
<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>focus</td></tr> <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>object_exchange</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> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//button[@data-i18n='Save'][contains(@class, 'ui-icon-warning')]</td> <td>//li[@data-relative-url='portal_categories/action_type/object_exchange']</td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>click</td>
<td>//li[@data-relative-url='portal_categories/action_type/object_exchange']</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>
...@@ -98,8 +96,8 @@ ...@@ -98,8 +96,8 @@
<tr><td>type</td> <tr><td>type</td>
<td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_dialog.html']//textarea</td> <td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_dialog.html']//textarea</td>
<td>QWERTY</td></tr> <td>QWERTY</td></tr>
<tr><td>click</td> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<td>//div[@data-gadget-url='${renderjs_url}/gadget_erp5_pt_form_dialog.html']//input[@type='submit']</td><td></td></tr>
<tal:block tal:define="notification_configuration python: {'class': 'success', <tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Status changed.'}"> 'text': 'Status changed.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
......
...@@ -29,8 +29,10 @@ ...@@ -29,8 +29,10 @@
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module</td> <td>${base_url}/web_site_module/renderjs_runner/#/foo_module</td>
<td></td> <td></td>
</tr> </tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<tr> <tr>
<td>waitForElementPresent</td> <td>assertElementPresent</td>
<td>//a[@data-i18n='Add']</td> <td>//a[@data-i18n='Add']</td>
<td></td> <td></td>
</tr> </tr>
...@@ -47,26 +49,8 @@ ...@@ -47,26 +49,8 @@
</tal:block> </tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <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" /> <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> <tr>
<td>type</td> <td>type</td>
<td>//input[@name='field_my_successor_title']</td> <td>//input[@name='field_my_successor_title']</td>
...@@ -108,19 +92,15 @@ ...@@ -108,19 +92,15 @@
<td>A new foo</td> <td>A new foo</td>
</tr> </tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_save" />
<tr> <!--tal:block tal:define="notification_configuration python: {'class': 'error',
<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.'}"> 'text': 'Input data has errors.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block> </tal:block-->
<tr> <tr>
<td>assertElementPresent</td> <td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//span[text()='No such document was found.']</td> <td>//div[@data-gadget-scope='field_my_successor_title']//span[text()='No such document was found']</td>
<td></td> <td></td>
</tr> </tr>
......
<tal:block xmlns:tal="http://xml.zope.org/namespaces/tal" <tal:block xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"> xmlns:metal="http://xml.zope.org/namespaces/metal">
<tal:block metal:define-macro="save"> <tal:block metal:define-macro="click_save">
<tr> <tr>
<td colspan="3"><b>Save</b></td> <td colspan="3"><b>Click on Save</b></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<td>//button[@data-i18n='Save']</td> <td>//button[@data-i18n='Save']</td>
<td></td> <td></td>
</tr> </tr>
</tal:block>
<tal:block metal:define-macro="save">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_save" />
<tr>
<td colspan="3"><b>Save</b></td>
</tr>
<!-- First loader while calling Base_edit --> <!-- First loader while calling Base_edit -->
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
......
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