Commit 7c0f804d authored by Romain Courteaud's avatar Romain Courteaud

[erp5_web_renderjs_ui] Validate dialog before posting it to the server

parent d751567a
...@@ -233,7 +233,7 @@ ...@@ -233,7 +233,7 @@
</item> </item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <int>50</int> </value>
</item> </item>
<item> <item>
<key> <string>required</string> </key> <key> <string>required</string> </key>
......
...@@ -35,77 +35,84 @@ ...@@ -35,77 +35,84 @@
} }
} }
return getContent.apply(this) return checkValidity.apply(gadget)
.push(function (content_dict) { .push(function (is_valid) {
var data = {}, if (!is_valid) {
key; enableButton();
// create a copy of sub_data so we do not modify them in-place
for (key in content_dict) {
if (content_dict.hasOwnProperty(key)) {
data[key] = content_dict[key];
}
}
// ERP5 expects target Script name in dialog_method field
data.dialog_method = gadget.state.form_definition.action;
// For Update Action - override the default value from "action"
if (is_updating) {
data.dialog_method = gadget.state.form_definition.update_action;
data.update_method = gadget.state.form_definition.update_action;
}
return data;
})
.push(function (data) {
return gadget.submitContent(
gadget.state.jio_key,
gadget.state.erp5_document._embedded._view._actions.put.href, // most likely points to Base_callDialogMethod
data
);
})
.push(function (jio_key) { // success redirect handler
var splitted_jio_key_list,
splitted_current_jio_key_list,
command,
i;
if (is_updating || !jio_key) {
return; return;
} }
if (gadget.state.redirect_to_parent) { return getContent.apply(gadget)
return gadget.redirect({command: 'history_previous'}); .push(function (content_dict) {
} var data = {},
if (gadget.state.jio_key === jio_key) { key;
// don't update navigation history when not really redirecting
return gadget.redirect({command: 'cancel_dialog_with_history'}); // create a copy of sub_data so we do not modify them in-place
} for (key in content_dict) {
// Check if the redirection goes to a same parent's subdocument. if (content_dict.hasOwnProperty(key)) {
// In this case, do not add current document to the history data[key] = content_dict[key];
// example: when cloning, do not keep the original document in history }
splitted_jio_key_list = jio_key.split('/'); }
splitted_current_jio_key_list = gadget.state.jio_key.split('/'); // ERP5 expects target Script name in dialog_method field
command = 'display_with_history'; data.dialog_method = gadget.state.form_definition.action;
if (splitted_jio_key_list.length === splitted_current_jio_key_list.length) { // For Update Action - override the default value from "action"
for (i = 0; i < splitted_jio_key_list.length - 1; i += 1) { if (is_updating) {
if (splitted_jio_key_list[i] !== splitted_current_jio_key_list[i]) { data.dialog_method = gadget.state.form_definition.update_action;
data.update_method = gadget.state.form_definition.update_action;
}
return data;
})
.push(function (data) {
return gadget.submitContent(
gadget.state.jio_key,
gadget.state.erp5_document._embedded._view._actions.put.href, // most likely points to Base_callDialogMethod
data
);
})
.push(function (jio_key) { // success redirect handler
var splitted_jio_key_list,
splitted_current_jio_key_list,
command,
i;
if (is_updating || !jio_key) {
return;
}
if (gadget.state.redirect_to_parent) {
return gadget.redirect({command: 'history_previous'});
}
if (gadget.state.jio_key === jio_key) {
// don't update navigation history when not really redirecting
return gadget.redirect({command: 'cancel_dialog_with_history'});
}
// Check if the redirection goes to a same parent's subdocument.
// In this case, do not add current document to the history
// example: when cloning, do not keep the original document in history
splitted_jio_key_list = jio_key.split('/');
splitted_current_jio_key_list = gadget.state.jio_key.split('/');
command = 'display_with_history';
if (splitted_jio_key_list.length === splitted_current_jio_key_list.length) {
for (i = 0; i < splitted_jio_key_list.length - 1; i += 1) {
if (splitted_jio_key_list[i] !== splitted_current_jio_key_list[i]) {
command = 'push_history';
}
}
} else {
command = 'push_history'; command = 'push_history';
} }
}
} else {
command = 'push_history';
}
// forced document change thus we update history // forced document change thus we update history
return gadget.redirect({ return gadget.redirect({
command: command, command: command,
options: { options: {
"jio_key": jio_key "jio_key": jio_key
// do not mingle with editable because it isn't necessary // do not mingle with editable because it isn't necessary
} }
}); });
}) })
.push(function (result) { .push(function (result) {
enableButton(); enableButton();
return result; return result;
});
}, function (error) { }, function (error) {
enableButton(); enableButton();
throw error; throw error;
......
...@@ -222,7 +222,7 @@ ...@@ -222,7 +222,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>972.55890.2478.15121</string> </value> <value> <string>976.20956.15292.37495</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1547136935.14</float> <float>1560246152.37</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testFormDialogWorkflowError</string> </value> <value> <string>testFormDialogWorkflowValidationErrorBackend</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <key> <string>output_encoding</string> </key>
......
<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 Workflow Transition with Invalid Form</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Workflow Transition with Invalid Form</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module/1?editable=1</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()='Actions']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()='Actions']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Custom Required Dialog']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n='Custom Required Dialog']</td>
<td></td>
</tr>
<!-- Wait for gadget to be loaded -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr>
<td>assertElementPresent</td>
<td>//input[@name='field_your_custom_workflow_variable']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_your_custom_workflow_variable']</td>
<td>AZERTYUIOPQSDFGHJKLMWXCVBNazertyuiopqsdfghjklmwxcvbn</td>
</tr>
<!-- Fill long string to provoke form validation failure -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<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>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td><td></td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td>
<td>Too much input was given.</td></tr>
<tr><td>type</td>
<td>//textarea[@name='field_your_comment']</td>
<td>QWERTY</td></tr>
<tr><td>type</td>
<td>//input[@name='field_your_custom_workflow_variable']</td>
<td>YTREWQ</td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<!-- Wait for the notification to appear. We cannot use verifyText because the button
is there all the time. It gets text assigned and is shown asynchronously later. -->
<tal:block tal:define="notification_configuration python: {'class': 'success', 'text': 'Status changed.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?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>testFormDialogWorkflowValidationErrorFrontend</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>
...@@ -36,21 +36,19 @@ ...@@ -36,21 +36,19 @@
<td></td> <td></td>
</tr> </tr>
<!-- Wait for gadget to be loaded --> <!-- Wait for gadget to be loaded -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr> <tr>
<td>waitForElementPresent</td> <td>assertElementPresent</td>
<td>//input[@name='field_your_custom_workflow_variable']</td> <td>//input[@name='field_your_custom_workflow_variable']</td>
<td></td> <td></td>
</tr> </tr>
<!-- Do not fill anything to provoke form validation failure --> <!-- Do not fill anything to provoke form validation failure -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<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>waitForElementPresent</td> <tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td><td></td></tr> <td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td><td></td></tr>
<tr><td>assertText</td> <tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td> <td>//div[@data-gadget-scope="field_your_custom_workflow_variable"]/div/span</td>
<td>Input is required but no input given.</td></tr> <td>Please fill out this field.</td></tr>
<tr><td>type</td> <tr><td>type</td>
<td>//textarea[@name='field_your_comment']</td> <td>//textarea[@name='field_your_comment']</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