Commit 3eb87be0 authored by Xiaowu Zhang's avatar Xiaowu Zhang

erp5_web_renderjs_ui: reimplement relation field

parent d99e1c41
...@@ -226,7 +226,44 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t ...@@ -226,7 +226,44 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
{"portal_type": portal_type_list} {"portal_type": portal_type_list}
).asSearchTextExpression(sql_catalog)}) ).asSearchTextExpression(sql_catalog)})
} }
title = field.get_value("title"),
column_list = field.get_value("columns")
proxy_listbox_ids = field.get_value("proxy_listbox_ids")
if len(proxy_listbox_ids):
listbox_ids = proxy_listbox_ids
else:
listbox_ids = [('Base_viewRelatedObjectListBase/listbox','default')]
listbox = {}
for grain in listbox_ids:
tmp = grain[0].split('/')
form = getattr(context, tmp[0])
for listbox_field in form.get_fields():
if listbox_field.getId() == tmp[1]:
#get original definition
result = renderField(context, listbox_field, getFormRelativeUrl(form))
#overwrite, like Base_getRelatedObjectParameter does
if result["portal_type"] == []:
result["portal_type"] = field.get_value('portal_type')
result["query"] = url_template_dict["jio_search_template"] % {
"query": make_query({"query": sql_catalog.buildQuery(
dict(portal_type = [x[1] for x in result["portal_type"]],
**result["default_params"]), ignore_unknown_columns=True
).asSearchTextExpression(sql_catalog)})
}
result.pop("list_method_template", None)
result["list_method"] = "portal_catalog"
result["title"] = title
#set default listbox's column list to relation's column list
if tmp[0] == 'Base_viewRelatedObjectListBase' and len(column_list) > 0:
result["column_list"] = column_list
listbox[grain[1]] = result
break
result = { result = {
"url": relative_url,
"portal_types": portal_type_list, "portal_types": portal_type_list,
"query": query, "query": query,
"catalog_index": field.get_value('catalog_index'), "catalog_index": field.get_value('catalog_index'),
...@@ -238,10 +275,17 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t ...@@ -238,10 +275,17 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
"css_class": field.get_value("css_class"), "css_class": field.get_value("css_class"),
"hidden": field.get_value("hidden"), "hidden": field.get_value("hidden"),
"description": field.get_value("description"), "description": field.get_value("description"),
"title": field.get_value("title"), "title": title,
"required": field.get_value("required") "required": field.get_value("required"),
"proxy_listbox_ids_len": len(proxy_listbox_ids),
"listbox": listbox
} }
result["default"] = getFieldDefault(traversed_document, field, result["key"], value) tmp = getFieldDefault(traversed_document, field, result["key"], value)
if isinstance(tmp, list):
result["default"] = tmp
else:
result["default"] = [tmp]
result["relation_field_id"] = traversed_document.Field_getSubFieldKeyDict( result["relation_field_id"] = traversed_document.Field_getSubFieldKeyDict(
field, field,
"relation", "relation",
...@@ -251,12 +295,7 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t ...@@ -251,12 +295,7 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
field, field,
"item", key=result["key"] "item", key=result["key"]
) )
result["relation_item_relative_url"] = [jump_reference.getRelativeUrl() for jump_reference in jump_reference_list]
if jump_reference_list:
url = [jump_reference.getRelativeUrl() for jump_reference in jump_reference_list]
uid = [jump_reference.getUid() for jump_reference in jump_reference_list]
result["relation_item_relative_url"] = url
result["relation_item_uid"] = uid
elif meta_type == "CheckBoxField": elif meta_type == "CheckBoxField":
result = { result = {
......
...@@ -182,6 +182,8 @@ gadget_erp5_page_logout.html\n ...@@ -182,6 +182,8 @@ gadget_erp5_page_logout.html\n
gadget_erp5_page_logout.js\n gadget_erp5_page_logout.js\n
gadget_erp5_page_preference.html\n gadget_erp5_page_preference.html\n
gadget_erp5_page_preference.js\n gadget_erp5_page_preference.js\n
gadget_erp5_page_relation_search.html\n
gadget_erp5_page_relation_search.js\n
gadget_erp5_page_search.html\n gadget_erp5_page_search.html\n
gadget_erp5_page_search.js\n gadget_erp5_page_search.js\n
gadget_erp5_page_tab.html\n gadget_erp5_page_tab.html\n
...@@ -311,8 +313,8 @@ NETWORK:\n ...@@ -311,8 +313,8 @@ NETWORK:\n
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1421252934.14</float> <float>1465381395.69</float>
<string>GMT</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
</object> </object>
...@@ -356,7 +358,7 @@ NETWORK:\n ...@@ -356,7 +358,7 @@ NETWORK:\n
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>952.5891.21040.4130</string> </value> <value> <string>952.10297.7504.12014</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -374,7 +376,7 @@ NETWORK:\n ...@@ -374,7 +376,7 @@ NETWORK:\n
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1466784262.24</float> <float>1467109017.1</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -2087,6 +2087,12 @@ html .ui-listview li:nth-child(even) > .ui-btn { ...@@ -2087,6 +2087,12 @@ html .ui-listview li:nth-child(even) > .ui-btn {
background-color: #fff; background-color: #fff;
background-color: rgba(0,0,0,0); background-color: rgba(0,0,0,0);
} }
/* fix relation string field background transparent error */
html .ui-listview li.ui-autocomplete ~ li {
background-color: white;
}
/* /*
------------------------------------------------------------------------- -------------------------------------------------------------------------
----------------------------- Controlgroup ------------------------------ ----------------------------- Controlgroup ------------------------------
...@@ -2123,7 +2129,6 @@ html body .ui-tag-list-inset { ...@@ -2123,7 +2129,6 @@ html body .ui-tag-list-inset {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
left: 3em;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
......
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
input.setAttribute('disabled', 'disabled'); input.setAttribute('disabled', 'disabled');
} }
}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function (options) {
var input = this.element.querySelector('input'), var input = this.element.querySelector('input'),
result = {}, result = {},
select, select,
...@@ -135,7 +135,21 @@ ...@@ -135,7 +135,21 @@
date, date,
hour, hour,
minute, minute,
timezone,
zone_list = {"GMT-12": "-1200", "GMT-11": "-1100",
"GMT-9": "-0900", "GMT-8": "-0800",
"GMT-7": "-0700", "GMT-6": "-0600",
"GMT-5": "-0500", "GMT-4": "-0400",
"GMT-3": "-0300", "GMT-2": "-0200",
"GMT-1": "-0100", "GMT": "+0000",
"GMT+1": "+0100", "GMT+2": "+0200",
"GMT+3": "+0300", "GMT+4": "+0400",
"GMT+5": "+0500", "GMT+6": "+0600",
"GMT+7": "+0700", "GMT+8": "+0800",
"GMT+9": "+0900", "GMT+10": "+1000",
"GMT+11": "+1100", "GMT+12": "+1200"},
value = input.value; value = input.value;
if (options === undefined || options.format === "erp5") {
if (value !== "") { if (value !== "") {
if (field_json.date_only === 0) { if (field_json.date_only === 0) {
value += "+0000"; value += "+0000";
...@@ -195,6 +209,19 @@ ...@@ -195,6 +209,19 @@
result[field_json.subfield_day_key] = ""; result[field_json.subfield_day_key] = "";
} }
return result; return result;
}
if (field_json.date_only) {
value += "T00:00";
}
if (field_json.timezone_style) {
//set timezone
select = this.element.querySelector("select");
timezone = select.options[select.selectedIndex].value;
} else {
timezone = "GMT";
}
result[field_json.key] = value + zone_list[timezone];
return result;
}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
var gadget = this, var gadget = this,
......
...@@ -98,6 +98,9 @@ ...@@ -98,6 +98,9 @@
.allowPublicAcquisition("getFieldTypeGadgetUrl", function (param_list) { .allowPublicAcquisition("getFieldTypeGadgetUrl", function (param_list) {
return getFieldTypeGadgetUrl(param_list[0]); return getFieldTypeGadgetUrl(param_list[0]);
}) })
.allowPublicAcquisition("getFormContent", function (param_list) {
return this.getContent(param_list[0]);
})
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
...@@ -196,6 +199,7 @@ ...@@ -196,6 +199,7 @@
form_gadget.props.gadget_list.push(field_gadget); form_gadget.props.gadget_list.push(field_gadget);
var suboptions = options[renderered_field.key] || suboption_dict; var suboptions = options[renderered_field.key] || suboption_dict;
suboptions.field_json = renderered_field; suboptions.field_json = renderered_field;
suboptions.field_json.view = options.view;
return field_gadget.render(suboptions); return field_gadget.render(suboptions);
}); });
} }
...@@ -237,14 +241,13 @@ ...@@ -237,14 +241,13 @@
} }
return {}; return {};
}) })
.declareMethod("getContent", function () { .declareMethod("getContent", function (options) {
var form_gadget = this, var form_gadget = this,
k, k,
field_gadget, field_gadget,
count = form_gadget.props.gadget_list.length, count = form_gadget.props.gadget_list.length,
data = {}, data = {},
queue = new RSVP.Queue(); queue = new RSVP.Queue();
function extendData(field_data) { function extendData(field_data) {
var key; var key;
for (key in field_data) { for (key in field_data) {
...@@ -253,13 +256,17 @@ ...@@ -253,13 +256,17 @@
} }
} }
} }
if (options === undefined) {
options = {
"format": "erp5"
};
}
for (k = 0; k < count; k += 1) { for (k = 0; k < count; k += 1) {
field_gadget = form_gadget.props.gadget_list[k]; field_gadget = form_gadget.props.gadget_list[k];
// XXX Hack until better defined // XXX Hack until better defined
if (field_gadget.getContent !== undefined) { if (field_gadget.getContent !== undefined) {
queue queue
.push(field_gadget.getContent.bind(field_gadget)) .push(field_gadget.getContent.bind(field_gadget, options))
.push(extendData); .push(extendData);
} }
} }
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
{{#each head_value}} {{#each head_value}}
<th data-i18n="{{data-i18n}}" class="{{class_value}}">{{text}}</th> <th data-i18n="{{data-i18n}}" class="{{class_value}}">{{text}}</th>
{{/each}} {{/each}}
{{#if line_icon}}
<th></th>
{{/if}}
</tr> </tr>
</thead> </thead>
</table> </table>
...@@ -42,6 +45,9 @@ ...@@ -42,6 +45,9 @@
{{#each head_value}} {{#each head_value}}
<th data-i18n="{{data-i18n}}" class="{{class_value}}">{{text}}</th> <th data-i18n="{{data-i18n}}" class="{{class_value}}">{{text}}</th>
{{/each}} {{/each}}
{{#if line_icon}}
<th></th>
{{/if}}
</tr> </tr>
</thead> </thead>
</table> </table>
...@@ -72,6 +78,11 @@ ...@@ -72,6 +78,11 @@
{{/if}} {{/if}}
</th> </th>
{{/each}} {{/each}}
{{#if line_icon}}
<th>
<a href ="{{jump}}" class="ui-body-inherit ui-btn-icon-right ui-link ui-btn ui-corner-all ui-icon-mail-forward"></a>
</th>
{{/if}}
</tr> </tr>
{{/each}} {{/each}}
</tbody> </tbody>
...@@ -107,6 +118,11 @@ ...@@ -107,6 +118,11 @@
{{/if}} {{/if}}
</th> </th>
{{/each}} {{/each}}
{{#if line_icon}}
<th>
<a href ="{{jump}}" class="ui-body-inherit ui-btn-icon-right ui-link ui-btn ui-corner-all ui-icon-mail-forward"></a>
</th>
{{/if}}
</tr> </tr>
{{/each}} {{/each}}
</tbody> </tbody>
......
...@@ -46,7 +46,8 @@ ...@@ -46,7 +46,8 @@
return gadget.translateHtml(template( return gadget.translateHtml(template(
{ {
"head_value": gadget.props.head_value, "head_value": gadget.props.head_value,
"show_anchor": gadget.props.field_json.show_anchor "show_anchor": gadget.props.field_json.show_anchor,
"line_icon": gadget.props.field_json.line_icon
} }
)); ));
} }
...@@ -236,9 +237,11 @@ ...@@ -236,9 +237,11 @@
j; j;
gadget.props.field_json = field_json; gadget.props.field_json = field_json;
gadget.props.field_id = options.field_id;
gadget.props.extended_search = options.extended_search; gadget.props.extended_search = options.extended_search;
gadget.props.hide_class = options.hide_enabled ? "" : "ui-disabled"; gadget.props.hide_class = options.hide_enabled ? "" : "ui-disabled";
gadget.props.sort_list = []; gadget.props.sort_list = [];
gadget.props.command = field_json.command || 'index';
//only display which is in listbox's column list //only display which is in listbox's column list
if (field_json.sort_column_list.length) { if (field_json.sort_column_list.length) {
...@@ -392,9 +395,10 @@ ...@@ -392,9 +395,10 @@
for (i = 0; i < counter; i += 1) { for (i = 0; i < counter; i += 1) {
promise_list.push( promise_list.push(
gadget.getUrlFor({ gadget.getUrlFor({
command: 'index', command: gadget.props.command,
options: { options: {
jio_key: result.data.rows[i].id, jio_key: result.data.rows[i].id,
uid: result.data.rows[i].value.uid,
selection_index: begin_from + i, selection_index: begin_from + i,
query: query_string, query: query_string,
list_method_template: field_json.list_method_template, list_method_template: field_json.list_method_template,
...@@ -430,7 +434,8 @@ ...@@ -430,7 +434,8 @@
body_value.push({ body_value.push({
"value": result.data.rows[i].value.uid, "value": result.data.rows[i].value.uid,
"jump": tmp_url, "jump": tmp_url,
"tr_value": tr_value "tr_value": tr_value,
"line_icon": field_json.line_icon
}); });
} }
gadget.props.body_value = body_value; gadget.props.body_value = body_value;
...@@ -458,7 +463,8 @@ ...@@ -458,7 +463,8 @@
}).push(function (url_list) { }).push(function (url_list) {
var foot = {}; var foot = {};
foot.colspan = field_json.column_list.length + gadget.props.field_json.show_anchor; foot.colspan = field_json.column_list.length + field_json.show_anchor +
(field_json.line_icon ? 1 : 0);
foot.default_colspan = foot.colspan; foot.default_colspan = foot.colspan;
foot.previous_classname = "ui-btn ui-icon-carat-l ui-btn-icon-left responsive ui-first-child"; foot.previous_classname = "ui-btn ui-icon-carat-l ui-btn-icon-left responsive ui-first-child";
foot.previous_url = url_list[0]; foot.previous_url = url_list[0];
...@@ -487,7 +493,7 @@ ...@@ -487,7 +493,7 @@
}) })
.declareMethod("getContent", function () { .declareMethod("getContent", function (options) {
var form_gadget = this, var form_gadget = this,
k, k,
field_gadget, field_gadget,
...@@ -509,7 +515,7 @@ ...@@ -509,7 +515,7 @@
// XXX Hack until better defined // XXX Hack until better defined
if (field_gadget.getContent !== undefined) { if (field_gadget.getContent !== undefined) {
queue queue
.push(field_gadget.getContent.bind(field_gadget)) .push(field_gadget.getContent.bind(field_gadget, options))
.push(extendData); .push(extendData);
} }
} }
......
<!DOCTYPE html>
<html>
<head>
<base href="https://softinst62810.node.vifib.com/erp5/web_site_module/renderjs_runner/gadget_erp5_page_relation_search.html/" />
Please register or sign in to reply
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Page Search</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_page_relation_search.js" type="text/javascript"></script>
<script id="search-template" type="text/x-handlebars-template">
<div class="ui-field-contain">
<label data-i18n="Select Template">Select Template<span></span></label>
<select>
{{#each options}}
{{#equal this ../select_template}}
<option selected="selected" data-i18n="{{this}}" value="{{this}}">{{this}}</option>
{{else}}
<option data-i18n="{{this}}" value="{{this}}">{{this}}</option>
{{/equal}}
{{/each}}
</select>
</div>
</script>
</head>
<body>
<div class="left">
</div>
<div data-gadget-url="gadget_erp5_pt_form_list.html"
data-gadget-scope="form_list"
data-gadget-sandbox="public">
</div>
</body>
</html>
\ No newline at end of file
<?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_erp5_page_relation_search.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>rjs_gadget_erp5_page_relation_search_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 ERP5 Relation Search</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>1458575478.84</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>950.53250.43607.26129</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>1461848814.52</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>
<none/>
</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>empty</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>1458575406.89</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
/*global window, rJS */
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, RSVP, Handlebars, loopEventListener*/
(function (window, rJS, RSVP, Handlebars, loopEventListener) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
search_source = gadget_klass.__template_element
.getElementById("search-template")
.innerHTML,
search_template = Handlebars.compile(search_source);
Handlebars.registerHelper('equal', function (left_value,
right_value, options) {
if (arguments.length < 3) {
throw new Error("Handlebars Helper equal needs 2 parameters");
}
if (left_value !== right_value) {
return options.inverse(this);
}
return options.fn(this);
});
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.allowPublicAcquisition('updateHeader', function (param_list) {
return this.updateHeader({
page_title: param_list[0].page_title,
back_url: this.props.back_url,
filter_action: true
});
})
.allowPublicAcquisition('getUrlParameter', function (argument_list) {
return this.getUrlParameter(argument_list)
.push(function (result) {
if ((result === undefined) && (argument_list[0] === 'field_listbox_sort_list:json')) {
return [];
}
return result;
});
})
.declareMethod("render", function (options) {
var gadget = this,
select_template = options.select_template || "";
return gadget.getUrlFor({command: 'history_previous'})
.push(function (back_url) {
gadget.props.back_url = back_url;
return RSVP.all([
gadget.jio_getAttachment(options.url, options.view),
gadget.getDeclaredGadget('form_list')
]);
})
.push(function (results) {
var form_gadget = results[1],
listbox_render,
field = results[0]._embedded._view[options.back_field.slice("field_".length)],
html;
gadget.props.listbox = field.listbox;
gadget.props.listbox_key = Object.keys(field.listbox);
gadget.props.field_title = field.title;
if (field.proxy_listbox_ids_len) {
if (select_template === "") {
select_template = gadget.props.listbox_key[0];
}
listbox_render = gadget.props.listbox[select_template];
html = search_template({
options: gadget.props.listbox_key,
select_template: select_template
});
gadget.props.element.querySelector(".left").innerHTML = html;
} else {
listbox_render = gadget.props.listbox[gadget.props.listbox_key[0]];
}
listbox_render.command = "history_previous";
listbox_render.line_icon = true;
return form_gadget.render({
erp5_document: {"_embedded": {"_view": {
"listbox": listbox_render
}},
"title": results[0].title,
"_links": results[0]._links
},
form_definition: {
group_list: [[
"bottom",
[["listbox"]]
]]
}
});
});
})
.declareMethod("triggerSubmit", function () {
var argument_list = arguments;
return this.getDeclaredGadget('form_list')
.push(function (gadget) {
return gadget.triggerSubmit.apply(gadget, argument_list);
});
})
.declareService(function () {
var gadget = this,
select = gadget.props.element.querySelector("select");
if (select) {
return loopEventListener(
select,
'change',
false,
function (event) {
var target = event.target,
value = target.options[target.selectedIndex].value;
return gadget.redirect({
command: 'change',
options: {
select_template: value
}
});
}
);
}
});
}(window, rJS, RSVP, Handlebars, loopEventListener));
\ No newline at end of file
<?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>content_type</string> </key>
<value> <string>text/javascript</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_relation_search.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>rjs_gadget_erp5_page_relation_search_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 ERP5 Relation Search 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>1458575571.65</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>951.48046.6494.25736</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>1466092941.35</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>
<none/>
</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>empty</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>1458575540.07</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
for (key in rendered_form) { for (key in rendered_form) {
if (rendered_form.hasOwnProperty(key) && (key[0] !== "_")) { if (rendered_form.hasOwnProperty(key) && (key[0] !== "_")) {
rendered_field = rendered_form[key]; rendered_field = rendered_form[key];
if ((rendered_field.type !== "ListBox") && ((!rendered_field.default) || (rendered_field.hidden === 1) || (rendered_field.default.length === 0))) { if ((rendered_field.type !== "ListBox") && ((!rendered_field.default) || (rendered_field.hidden === 1) || (rendered_field.default.length === 0)
|| (rendered_field.default.length === 1 && (!rendered_field.default[0])))) {
delete rendered_form[key]; delete rendered_form[key];
} else { } else {
rendered_field.editable = 0; rendered_field.editable = 0;
......
...@@ -6,6 +6,20 @@ ...@@ -6,6 +6,20 @@
var gadget_klass = rJS(window); var gadget_klass = rJS(window);
// DEFAULT_VIEW_REFERENCE = "view"; // DEFAULT_VIEW_REFERENCE = "view";
function loadFormContent(gadget, result) {
var key;
if (gadget.props.options.form_content) {
for (key in result) {
if (result.hasOwnProperty(key)) {
if (gadget.props.options.form_content[result[key].key]) {
result[key].default = gadget.props.options.form_content[result[key].key];
}
}
}
}
}
gadget_klass gadget_klass
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// ready // ready
...@@ -27,12 +41,25 @@ ...@@ -27,12 +41,25 @@
// Acquired methods // Acquired methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment") .declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("redirect", "redirect") .declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.allowPublicAcquisition("jio_allDocs", function (param_list) {
var gadget = this;
return gadget.jio_allDocs(param_list[0])
.push(function (result) {
var i;
if (result.data.rows.length) {
for (i = 0; i < result.data.rows.length; i += 1) {
loadFormContent(gadget, result.data.rows[i].value);
}
}
return result;
});
})
.declareMethod('triggerSubmit', function () { .declareMethod('triggerSubmit', function () {
return this.getDeclaredGadget('fg') return this.getDeclaredGadget('fg')
.push(function (g) { .push(function (g) {
...@@ -75,7 +102,7 @@ ...@@ -75,7 +102,7 @@
}) })
.push(function (result) { .push(function (result) {
erp5_form = result; erp5_form = result;
loadFormContent(gadget, erp5_document._embedded._view);
var url = "gadget_erp5_pt_" + erp5_form.pt; var url = "gadget_erp5_pt_" + erp5_form.pt;
// XXX Hardcoded specific behaviour for form_view // XXX Hardcoded specific behaviour for form_view
if ((options.editable !== undefined) && (erp5_form.pt === "form_view")) { if ((options.editable !== undefined) && (erp5_form.pt === "form_view")) {
......
...@@ -5,21 +5,84 @@ ...@@ -5,21 +5,84 @@
<meta name="viewport" content="width=device-width, user-scalable=no" /> <meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Relationstringfield</title> <title>ERP5 Relationstringfield</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script> <script src="renderjs.js" type="text/javascript"></script>
<script src="URI.js" type="text/javascript"></script> <script src="URI.js" type="text/javascript"></script>
<!-- custom script --> <script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_erp5_field_relationstring.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script> <script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_field_relationstring.js" type="text/javascript"></script>
</head>
<body> <script id="create-template" type="text/x-handlebars-template">
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon"> <div class="ui-controlgroup ui-controlgroup-horizontal ui-corner-all">
<input type='text' autocomplete="off" data-enhanced="true" /> <div class="ui-controlgroup-controls">
<li class="ui-first-child ui-last-child ui-input-text">Create:{{text}}
</li>
</div>
</script>
<script id="relation-input-template" type="text/x-handlebars-template">
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon {{readonly}}">
<input type='text' title={{title}} name={{name}} autocomplete="off" data-enhanced="true" {{required}} value="{{value}}" >
<a href="#" tabindex="-1" class="ui-hidden-accessible">&nbsp;</a> <a href="#" tabindex="-1" class="ui-hidden-accessible">&nbsp;</a>
<div class="ui-tag-list ui-tag-list-inset">
{{#if create_object}}
<div class="ui-controlgroup ui-controlgroup-horizontal ui-corner-all">
<div class="ui-controlgroup-controls">
<li class="ui-first-child ui-last-child ui-input-text">Create:{{create_object}}
</li>
</div>
</div> </div>
<a href="#" tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plane ui-shadow-inset ui-btn-inline ui-disabled">Jump to this document</a> {{/if}}
</div>
<ul class="ui-listview ui-corner-all search_ul"></ul>
</div>
{{#if create_object}}
<a href='#' tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plus ui-shadow-inset ui-btn-inline ui-disabled" >Jump to this document</a>
{{else}}
{{#if error_text}}
<a href='#' tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-warning ui-shadow-inset ui-btn-inline ui-disabled">Jump to this document</a>
{{else}}
{{#if jump_unknown}}
<a href='#' tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-warning ui-shadow-inset ui-btn-inline ui-disabled">Jump to this document</a>
{{else}}
{{#if href}}
{{#if allow_jump}}
<a href={{href}} tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plane ui-shadow-inset ui-btn-inline" >Jump to this document</a>
{{else}}
<a href='#' tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plane ui-shadow-inset ui-btn-inline ui-disabled">Jump to this document</a>
{{/if}}
{{else}}
<a href='#' tabindex="-1" class="ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plane ui-shadow-inset ui-btn-inline ui-disabled">Jump to this document</a>
{{/if}}
{{/if}}
{{/if}}
{{/if}}
</script>
<script id="relation-listview-template" type="text/x-handlebars-template">
{{#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}}
<li class="ui-li-static ui-body-inherit ui-icon-mail-forward ui-btn-icon-right" data-relative-url={{id}} >{{value}}</li>
{{/each}}
{{#each type}}
<li class="ui-li-static ui-body-inherit ui-bar-inherit ui-icon-plus ui-btn-icon-right" data-create-object="{{this}}" name="{{this}}">Create New {{this}}: {{../value}}</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-create-object="{{this}}" name="{{this}}">Create New {{this}}: {{../value}}</li>
{{/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 >Explore the Search Result List</li>
</script>
</head>
<body>
</body> </body>
</html> </html>
\ No newline at end of file
/*global window, document, rJS, RSVP, URI, loopEventListener, /*jslint indent: 2, maxerr: 3, nomen: true */
promiseEventListener */ /*global window, rJS, RSVP, URI, loopEventListener, Handlebars,
/*jslint indent: 2, maxerr: 3 */ SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener, $*/
(function (window, document, rJS, RSVP, URI, loopEventListener, (function (window, rJS, RSVP, URI, loopEventListener, promiseEventListener,
promiseEventListener) { SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, $) {
"use strict"; "use strict";
////////////////////////////////////
// Some methods
////////////////////////////////////
// XXX: re-factor.
// clear the autocomplete options, reset the plane tag and remove the create
// new tag. Since plane and new tag sometimes need to stay, "override_tag"
// can be set to something arbitrary to prevent removal of the respective
// element.
function clearResults(my_gadget, my_override_tag) {
var props = my_gadget.property_dict;
function dump(my_parent, my_tag_name) { var gadget_klass = rJS(window),
var child_list = my_parent.children, relation_input_source = gadget_klass.__template_element
i, .getElementById("relation-input-template")
i_len, .innerHTML,
child; relation_input_template = Handlebars.compile(relation_input_source),
// XXX: now that link ("A") stays, rewrite the whole element clearing!
for (i = 0, i_len = child_list.length; i < i_len; i += 1) {
child = child_list[i];
if (child && child.tagName === my_tag_name) {
if (my_tag_name === "A") {
props.plane.href = "#";
props.plane.className += " ui-disabled";
} else {
my_parent.removeChild(child);
}
}
}
}
// always clear autocomplete results (UL), the create new record input (DIV) relation_listview_source = gadget_klass.__template_element
// will only be removed on new searches, while the plane (A) is disabled .getElementById("relation-listview-template")
dump(props.wrapper, "UL"); .innerHTML,
dump(props.wrapper, my_override_tag || "DIV"); relation_listview_template = Handlebars.compile(relation_listview_source),
dump(my_gadget.element, my_override_tag || "A");
}
// creates a tag indicating the value entered will be added as new object create_source = gadget_klass.__template_element
// of displayed type when the form is submitted. Clicking the tag will .getElementById("create-template")
// reset the field, because otherwise accidentially typing something always .innerHTML,
// requires to reselect and manually backspace the value. Click to reset is create_template = Handlebars.compile(create_source),
// much easier/faster
function createNewTag(my_gadget) {
var props = my_gadget.property_dict,
field_json = props.field_json,
tag,
group,
controls,
subfield,
info,
link,
default_subfield;
// unique values only... changes ERP5 ["foo", "foo"] to ["foo"] to "foo" searching = "ui-btn ui-corner-all ui-btn-icon-notext" +
info = field_json.portal_types.filter(function (item, pos, self) { " ui-input-clear ui-icon-spinner ui-icon-spin",
return self.indexOf(item) === pos; searched = "ui-hidden-accessible",
}).join(""); jump_on = "ui-btn ui-corner-all ui-btn-icon-notext " +
"ui-icon-plane ui-shadow-inset ui-btn-inline",
jump_off = "ui-btn ui-corner-all ui-btn-icon-notext " +
"ui-icon-plane ui-shadow-inset ui-btn-inline ui-disabled",
jump_add = "ui-btn ui-corner-all ui-btn-icon-notext " +
"ui-icon-plus ui-shadow-inset ui-btn-inline ui-disabled",
jump_unknown = "ui-btn ui-corner-all ui-btn-icon-notext " +
"ui-icon-warning ui-shadow-inset ui-btn-inline ui-disabled";
link = document.createElement("a");
link.setAttribute("href", "#");
link.className = "ui-first-child ui-last-child ui-btn ui-corner-all " +
"ui-btn-inherit ui-btn-active ui-btn-icon-right ui-icon-delete";
link.textContent = "Create: " + info;
subfield = document.createElement("input");
subfield.setAttribute("type", "hidden");
subfield.setAttribute("name", field_json.relation_field_id);
subfield.setAttribute("value", "_newContent_" + info);
default_subfield = document.createElement("input");
default_subfield.setAttribute("type", "hidden");
default_subfield.setAttribute(
"name",
"default_subfield_" + field_json.key + "_relation:int"
);
default_subfield.setAttribute("value", 0);
controls = document.createElement("div");
controls.className = "ui-controlgroup-controls";
controls.appendChild(link);
controls.appendChild(subfield);
controls.appendChild(default_subfield);
group = document.createElement("div");
group.className = "ui-controlgroup ui-controlgroup-horizontal " +
"ui-corner-all";
group.appendChild(controls);
tag = document.createElement("div");
tag.className = "ui-tag-list ui-tag-list-inset";
tag.appendChild(group);
return tag;
}
// creates a set of autocomplete suggestings. Currently this is only a plain
// list of elements. The list will display the number of results (>10 or
// exact). Clicking on an option will set this option as field value
function createResults(my_result_list, index) {
var list = document.createElement("ul"),
head = document.createElement("li"),
str = "ui-li-static ui-body-inherit ui-icon-mail-forward " +
"ui-btn-icon-right",
len = my_result_list.length,
prefix = "",
item,
value_dict,
result,
i;
if (len === 11) {
prefix = ">";
len = 10;
}
head.className = "ui-autocomplete ui-li ui-li-divider ui-bar-inherit";
head.setAttribute("role", "heading");
head.textContent = prefix + " " + len + " Result(s)";
list.appendChild(head);
for (i = 0; i < len; i += 1) {
result = my_result_list[i];
value_dict = result.value;
item = document.createElement("li");
item.className = str;
// NOTE: gadget does not properties it gets here, so just concat
// NOTE: if doing more complex UI, beware the textContent value won't
// work, because currently it's used to retrieve the link from
// the last autocomplete query results!
item.textContent = value_dict[index];
item.setAttribute("data-relative-url", result.id);
item.setAttribute("name", value_dict.uid);
list.appendChild(item);
}
list.className = "ui-listview ui-corner-all";
list.firstChild.className += " ui-first-child";
list.lastChild.className += " ui-last-child";
return list;
}
////////////////////////////////////
// Promise methods
////////////////////////////////////
// notify change of field value, done here, since called from multiple sources
function notifyChange(my_gadget) {
return RSVP.all([
my_gadget.checkValidity(),
my_gadget.notifyChange()
]);
}
// set the link to jump to
function setRelationJump(my_gadget, my_initial_call, my_selected_value) {
var props = my_gadget.property_dict,
field_json = props.field_json,
target_url = false,
is_init = my_initial_call === true;
if (my_selected_value) {
target_url = my_selected_value;
} else {
if (field_json.relation_item_relative_url) {
target_url = field_json.relation_item_relative_url[0];
}
}
if (target_url && field_json.allow_jump) {
return new RSVP.Queue()
.push(function () {
return my_gadget.getUrlFor({
command: 'index',
options: {
jio_key: target_url,
query: 'relative_url:"' + target_url + '"'
}
});
})
.push(function (my_url) {
var plane = props.plane;
plane.href = my_url;
plane.className = "ui-btn ui-corner-all ui-btn-icon-notext " +
"ui-icon-plane ui-shadow-inset ui-btn-inline";
if (is_init === false) {
return notifyChange(my_gadget);
}
});
}
}
// trigger autocomplete for field value, on render() with value only sets link
function triggerAutocomplete(my_gadget, my_value) {
var props = my_gadget.property_dict,
field_json = props.field_json,
index = field_json.catalog_index,
begin_from = props.begin_from || 0,
lines = field_json.lines || 11,
select_list = [index, "uid"],
query_string = " AND (" + index + ':"' + my_value + '")',
result_dict,
no_results;
delete props.selected_uid;
return new RSVP.Queue()
.push(function () {
// new search, clear all, show spinner. set last_value to catch dups
clearResults(my_gadget);
props.last_value = my_value;
props.spinner.className = "ui-btn ui-corner-all ui-btn-icon-notext" +
" ui-input-clear ui-icon-spinner ui-icon-spin";
return my_gadget.jio_allDocs({
"query": new URI(field_json.query).query(true).query + query_string,
"limit": [begin_from, begin_from + lines],
"select_list": select_list
});
}).push(function (my_result) {
result_dict = my_result.data;
props.spinner.className = "ui-hidden-accessible";
no_results = result_dict.total_rows === 0;
// show "new" tag, clicking it will remove it and reset the field!
// XXX Not active - reset should be handled by a generic reset method!
if (no_results && field_json.allow_creation) {
return new RSVP.Queue()
.push(function () {
props.wrapper.appendChild(createNewTag(my_gadget));
my_gadget.property_dict.valid = true;
return notifyChange(my_gadget);
})
.push(function () {
var tag = props.wrapper.querySelector(".ui-tag-list .ui-btn");
return RSVP.any([
promiseEventListener(tag, "click", true),
promiseEventListener(tag, "tap", true)
]);
})
.push(function (my_event_to_clear) {
var wrapper,
tag_list,
original_value;
my_event_to_clear.preventDefault();
original_value = field_json.value || field_json.default || "";
wrapper = props.wrapper;
wrapper.querySelector("input").value = original_value;
tag_list = wrapper.querySelector(".ui-tag-list");
tag_list.parentNode.removeChild(tag_list);
return setRelationJump(my_gadget, undefined);
});
}
// default autocomplete
return new RSVP.Queue()
.push(function () {
var list;
if (no_results === false) {
props.wrapper.appendChild(createResults(result_dict.rows, index));
list = props.wrapper.querySelector("ul");
return RSVP.any([
promiseEventListener(list, "click", true),
promiseEventListener(list, "touchend", true)
]);
}
});
}).push(undefined, function (my_error) {
if (my_error instanceof RSVP.CancellationError) {
props.spinner.className = "ui-hidden-accessible";
clearResults(my_gadget, "skip");
}
throw my_error;
}).push(function (my_selection_event) {
var element,
jump_url;
// take entered text, set to input and clear list options
if (my_selection_event && my_selection_event.target) {
element = my_selection_event.target;
jump_url = element.getAttribute("data-relative-url");
props.selected_uid = element.getAttribute("name");
props.valid = true;
props.wrapper.querySelector("input").value = element.textContent;
clearResults(my_gadget, "skip");
return setRelationJump(my_gadget, undefined, jump_url);
}
});
}
rJS(window) rJS(window)
...@@ -309,96 +42,136 @@ promiseEventListener */ ...@@ -309,96 +42,136 @@ promiseEventListener */
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Init local properties // Init local properties
.ready(function (my_gadget) { .ready(function (my_gadget) {
my_gadget.property_dict = {}; my_gadget.props = {};
})
.ready(function (my_gadget) {
return my_gadget.getElement() return my_gadget.getElement()
.push(function (element) { .push(function (element) {
my_gadget.element = element; my_gadget.props.element = element;
my_gadget.property_dict.wrapper =
element.querySelector("div.ui-input-text");
my_gadget.property_dict.spinner = element.querySelector("a");
my_gadget.property_dict.plane = element.querySelectorAll("a")[1];
}); });
}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// acquired methods // acquired methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifyValid", "notifyValid")
.declareAcquiredMethod("notifyInvalid", "notifyInvalid") .declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.declareAcquiredMethod("notifyChange", "notifyChange") .declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs") .declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor") .declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getFormContent", "getFormContent")
.declareAcquiredMethod("translateHtml", "translateHtml")
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var field_gadget = this, var gadget = this,
input = field_gadget.element.querySelector('input'),
field_json = options.field_json || {}, field_json = options.field_json || {},
value; target_url,
queue = new RSVP.Queue(),
if (field_json.relation_item_relative_url) { create_object,
value = field_json.value || field_json.default; unknown,
} relation_item_relative_url,
// expose field_json and keep last value to prevent trigger on no-change uid,
field_gadget.property_dict.field_json = field_json; value = "";
field_gadget.property_dict.last_value = value || "";
field_gadget.property_dict.valid = true; if (field_json.default.format === "json") {
//load non saved value
input.setAttribute('value', value || ""); create_object = field_json.default.create_object;
input.setAttribute('name', field_json.key); unknown = field_json.default.jump_unknown;
input.setAttribute('title', field_json.title); relation_item_relative_url = field_json.default.relation_item_relative_url;
uid = field_json.default.uid;
if (field_json.required === 1) { value = field_json.default.value[0] || "";
input.setAttribute('required', 'required'); } else {
create_object = field_json.create_object;
unknown = field_json.jump_unknown;
relation_item_relative_url = field_json.relation_item_relative_url;
uid = field_json.uid;
value = field_json.default[0] || "";
}
gadget.props.jump_url = relation_item_relative_url;
if (relation_item_relative_url) {
target_url = relation_item_relative_url[0];
}
gadget.props.field_json = field_json;
gadget.props.query = QueryFactory.create(new URI(field_json.query).query(true).query);
if (!value && target_url && uid) {
//return from listbox
queue
.push(function () {
return gadget.jio_allDocs({
"query": Query.objectToSearchText(new SimpleQuery({
key: "catalog.uid",
value: uid,
limit: [0, 1]
})),
"select_list": [field_json.catalog_index]
});
})
.push(function (result) {
value = result.data.rows[0].value[field_json.catalog_index];
});
} }
if (field_json.editable !== 1) { if (target_url) {
input.setAttribute('readonly', 'readonly'); queue
field_gadget.property_dict.wrapper.className += ' ui-state-readonly ' .push(function () {
// input.setAttribute('data-wrapper-class', 'ui-state-readonly'); return gadget.getUrlFor({
// input.setAttribute('disabled', 'disabled'); command: 'index',
options: {
jio_key: target_url
} }
});
if (field_json.relation_item_relative_url) { });
return setRelationJump(field_gadget, true);
} }
queue
.push(function (href) {
return gadget.translateHtml(relation_input_template({
href: href,
readonly: field_json.editable ? "" : "ui-state-readonly",
required: field_json.required ? "required" : "",
value: value,
title: field_json.title,
name: field_json.key,
create_object: create_object,
allow_jump: field_json.allow_jump ? true : undefined,
error_text: field_json.error_text,
jump_unknown: unknown
}));
}) })
.push(function (html) {
// get content (needs hidden fields, too, when creating new records) gadget.props.element.innerHTML = html;
.declareMethod('getContent', function () { gadget.props.input =
var input_list = this.element.querySelectorAll('input'), gadget.props.element.querySelector("input");
gadget.props.new_tag_div = gadget.props.element.querySelector(".new_tag");
gadget.props.spinner = gadget.props.element.querySelector("a");
gadget.props.plane = gadget.props.element.querySelectorAll("a")[1];
});
return queue;
})
.declareMethod('getContent', function (options) {
var element = this.props.element.querySelector('input'),
result = {}, result = {},
i, tmp = {},
i_len, field_json = this.props.field_json;
input; if (options.format === "erp5") {
if (this.props.plane.className === jump_add) {
for (i = 0, i_len = input_list.length; i < i_len; i += 1) { result[field_json.relation_field_id] = "_newContent_" + this.props.create_object_type;
input = input_list[i];
result[input.getAttribute('name')] = input.value;
}
// Always return the document UID if value has been modified
if (this.property_dict.selected_uid !== undefined) {
result[this.property_dict.field_json.relation_field_id] =
this.property_dict.selected_uid;
} }
result[element.getAttribute('name')] = element.value;
return result; return result;
})
.declareMethod('checkValidity', function () {
var result;
result = (this.element.querySelector('input').checkValidity()) &&
(this.property_dict.valid);
if (result) {
return this.notifyValid()
.push(function () {
return result;
});
} }
tmp.format = "json";
tmp.value = [element.value];
if (this.props.plane.className === jump_add) {
tmp.create_object = this.props.create_object_type;
} else {
if (this.props.plane.className === jump_unknown) {
tmp.jump_unknown = true;
} else {
tmp.relation_item_relative_url = this.props.jump_url;
}
}
result[element.getAttribute('name')] = tmp;
return result; return result;
}) })
...@@ -406,126 +179,174 @@ promiseEventListener */ ...@@ -406,126 +179,174 @@ promiseEventListener */
// declared services // declared services
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareService(function () { .declareService(function () {
var field_gadget = this, var gadget = this,
props = field_gadget.property_dict, props = gadget.props,
element = field_gadget.element.querySelector('input'); input = gadget.props.element.querySelector('input'),
search_query,
simple_query,
field_json = props.field_json,
create_div = props.element.querySelector(".ui-tag-list"),
ul = gadget.props.element.querySelector(".search_ul");
// prevent unselecting on focus function generateList(event) {
function stop(e) { var index = field_json.catalog_index,
e.preventDefault(); begin_from = props.begin_from || 0,
return false; lines = field_json.lines || 10,
} my_value = event.target.value;
// trigger autocomplete ul.innerHTML = "";
function handler(my_event) { create_div.innerHTML = "";
var value = my_event.target.value, props.plane.className = jump_off;
pending_promise; props.jump_url = [];
// field value unchanged (tab-bing) if (my_value === "") {
if (props.last_value === value) { props.spinner.className = searched;
return; return;
} }
simple_query = new SimpleQuery({
// empty value, do nothing but notify key: index,
if (value === "") { value: my_value
field_gadget.property_dict.valid = true; });
return notifyChange(field_gadget); props.spinner.className = searching;
search_query = Query.objectToSearchText(new ComplexQuery({
operator: "AND",
query_list: [gadget.props.query, simple_query]
}));
return new RSVP.Queue()
.push(function () {
return gadget.jio_allDocs({
"query": search_query,
"limit": [begin_from, begin_from + lines],
"select_list": [index]
});
})
.push(function (result) {
var list = [],
i,
type = field_json.allow_creation ? field_json.portal_types : [],
html;
for (i = 0; i < result.data.rows.length; i += 1) {
list.push({
id: result.data.rows[i].id,
value: result.data.rows[i].value[index]
});
}
props.spinner.className = searched;
html = relation_listview_template({
list: list,
type: type,
value: my_value
});
$(ul).toggle();
ul.innerHTML = html;
$(ul).toggle();
});
} }
field_gadget.property_dict.valid = false;
// replace existing promise in case it has not triggered function setSelectedElement(event) {
pending_promise = props.pending_promise; var element = event.target,
if (pending_promise) { jump_url = element.getAttribute("data-relative-url"),
pending_promise.cancel(); create_object_type = element.getAttribute("data-create-object"),
explore = element.getAttribute("data-explore");
ul.innerHTML = "";
if (jump_url) {
props.input.value = element.textContent;
props.jump_url = [jump_url];
return gadget.getUrlFor({
command: 'index',
options: {
jio_key: jump_url
} }
}).push(function (url) {
// create a new queue, expose it to replace it with trailing events if (field_json.allow_jump) {
pending_promise = new RSVP.Queue() props.plane.href = url;
.push(function () { props.plane.className = jump_on;
return RSVP.delay(200); }
});
}
if (create_object_type) {
gadget.props.create_object_type = create_object_type;
props.plane.className = jump_add;
create_div.innerHTML = create_template({'text': create_object_type});
return;
}
if (explore) {
return gadget.getFormContent({
format: "json"
}) })
.push(function () { .push(function (content) {
return triggerAutocomplete(field_gadget, value); return gadget.redirect({
command: 'index',
options: {
page: "relation_search",
url: gadget.props.field_json.url,
extended_search: Query.objectToSearchText(simple_query),
view: gadget.props.field_json.view,
back_field: gadget.props.field_json.key,
target_index: 0
},
form_content: content
}); });
});
field_gadget.property_dict.pending_promise = pending_promise; }
return pending_promise; props.plane.className = jump_unknown;
} }
// Listen to all necessary events (blur not needed currently)
return RSVP.all([ return RSVP.all([
loopEventListener(element, 'onmouseout', false, stop), loopEventListener(input, 'input', false, generateList),
loopEventListener(element, 'keyup', false, handler), loopEventListener(input, 'blur', false, function () {
loopEventListener(element, 'input', false, handler) return new RSVP.Queue()
.push(function () {
return RSVP.any([
RSVP.delay(200),
promiseEventListener(ul, "click", true)
]); ]);
}) })
.push(function (event) {
if (event) {
return setSelectedElement(event);
}
if (ul.innerHTML) {
ul.innerHTML = "";
props.plane.className = jump_unknown;
}
});
})]
);
})
.declareService(function () { .declareService(function () {
var field_gadget = this; var gadget = this;
function notifyInvalid(evt) { function notifyInvalid(evt) {
return field_gadget.notifyInvalid(evt.target.validationMessage); return gadget.notifyInvalid(evt.target.validationMessage);
} }
// Listen to input change // Listen to input change
return loopEventListener( return loopEventListener(
field_gadget.element.querySelector('input'), gadget.props.element.querySelector('input'),
'invalid', 'invalid',
false, false,
notifyInvalid notifyInvalid
); );
}); })
.declareService(function () {
}(window, document, rJS, RSVP, URI, loopEventListener, promiseEventListener)); ////////////////////////////////////
// Check field validity when the value changes
////////////////////////////////////
/* var gadget = this;
Todos
- OK trigger with delay on input/keyup
- OK autocomplete makes portal catalog query instead of notifyloading
- OK too many events triggering
- OK 10 results shown,
- OK delete optionlist on focusout!
- OK use icon in optionlist
- OK user can pick one, whose value will be set to field
- OK existing selected entry should allow to plane if option is set
- OK loading with a preset value should query and activate plane if allowed
- OK no hardcoded "title" use anywhere, make generic
- OK remove plane on new search, don't make airport
- OK add results info
- OK non existing entry should allow to create new if option set
- OK selecting from options clears taglist, too
- OK update query
- OK fix broken links
- OK remove % from query syntax... ui downgrade, %% works, too
- OK don't trigger on tab-through of existing and new values
- OK don't autocomplete on empty string, clear values, too
- OK loader and planes tabindex =-1
- OK save custom entry
- OK should not work when not in editable mode, seems ok now
- OK fix CSS form spacing ---> not trivial
- OK implement deactivated plane icon until set, never hide icon!
- OK prevent multiple autocomplete elements when keyboard searching
- OK either add some functionality to "create element" or delete on click
- OK fix double trigger, multiple list
- OK fix value settings should notifychange!
- OK fix plane positioning in FF
- OK fix CSS element theming
- OK create button should rest when clicked in case user triggered to fast
- OK fix double list because not clearing what previous chain appended to DOM
- OK cleanup
- OK fix textinput css, not generic enough
- OK reimplement setting link without calling allDocs
- on small displays JQM will toggle headers, find way to prevent!
- fix broken promise chain
- ok test
- keyboard speed test
- add generic text and translations
- do multiRelationfield
- find way to digest response of erp5? submit should clean input
- add column_list parameter to pass more than title = "John Smith", render?
function notifyChange() {
return gadget.notifyChange();
}
return loopEventListener(
gadget.props.element.querySelector('input'),
'change',
false,
notifyChange
);
});
*/ }(window, rJS, RSVP, URI, loopEventListener, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, $));
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
</head> </head>
<body> <body>
<div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_form_content"></div>
<div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_selection"></div> <div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_selection"></div>
<div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_navigation_history"></div> <div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_navigation_history"></div>
<div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_document_state"></div> <div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_document_state"></div>
......
/*global window, rJS, RSVP, loopEventListener, document, jIO, URI, URL */ /*global window, rJS, RSVP, loopEventListener, document, jIO, URI, URL, Blob */
/*jslint nomen: true, indent: 2 */ /*jslint nomen: true, indent: 2 */
(function (window, rJS, RSVP, loopEventListener, document, jIO, URI, URL) { (function (window, rJS, RSVP, loopEventListener, document, jIO, URI, URL, Blob) {
"use strict"; "use strict";
// Keep reference of the latest allDocs params which reach to this view // Keep reference of the latest allDocs params which reach to this view
...@@ -330,7 +330,15 @@ ...@@ -330,7 +330,15 @@
return addHistory(gadget, previous_options); return addHistory(gadget, previous_options);
}) })
.push(function (id) { .push(function (id) {
var tmp;
next_options.history = id; next_options.history = id;
if (gadget.props.form_content) {
tmp = gadget.props.form_content;
delete gadget.props.form_content;
return gadget.props.jio_form_content.putAttachment('/', id, new Blob([JSON.stringify(tmp)], {type: "application/json"}));
}
})
.push(function () {
return addNavigationHistoryAndDisplay(gadget, jio_key, next_options); return addNavigationHistoryAndDisplay(gadget, jio_key, next_options);
}); });
} }
...@@ -454,17 +462,49 @@ ...@@ -454,17 +462,49 @@
}); });
} }
function execHistoryPreviousCommand(gadget, previous_options) { function execHistoryPreviousCommand(gadget, previous_options, load_options) {
var history = previous_options.history, var history = previous_options.history,
jio_key = previous_options.jio_key, jio_key = previous_options.jio_key,
target_index = previous_options.target_index,
field = previous_options.back_field,
queue = new RSVP.Queue(),
previous_id; previous_id;
if (history === undefined) { if (history === undefined) {
if (jio_key !== undefined) { if (jio_key !== undefined) {
return redirectToParent(gadget, jio_key); return redirectToParent(gadget, jio_key);
} }
} }
if (previous_options.back_field) {
queue
.push(function () {
return gadget.props.jio_form_content.getAttachment('/', history);
})
.push(function (results) {
return jIO.util.readBlobAsText(results);
}, function (error) {
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404)) {
return;
}
throw error;
})
.push(function (results) {
if (results) {
results = JSON.parse(results.target.result);
if (load_options.uid) {
results[field].value[target_index] = "";
results[field].relation_item_relative_url[target_index] = load_options.jio_key;
results[field].uid = load_options.uid;
}
gadget.props.form_content = results;
}
});
}
return gadget.props.jio_gadget.get(history) queue
.push(function () {
return gadget.props.jio_gadget.get(history);
})
.push(function (history) { .push(function (history) {
previous_id = history.previous_history_id; previous_id = history.previous_history_id;
return gadget.props.jio_gadget.get(history.options_id); return gadget.props.jio_gadget.get(history.options_id);
...@@ -486,6 +526,7 @@ ...@@ -486,6 +526,7 @@
delete options.jio_key; delete options.jio_key;
return addNavigationHistoryAndDisplay(gadget, next_jio_key, options); return addNavigationHistoryAndDisplay(gadget, next_jio_key, options);
}); });
return queue;
} }
...@@ -567,6 +608,10 @@ ...@@ -567,6 +608,10 @@
// Store current options to handle navigation // Store current options to handle navigation
gadget.props.options = JSON.parse(JSON.stringify(command_options.args)); gadget.props.options = JSON.parse(JSON.stringify(command_options.args));
if (gadget.props.form_content) {
command_options.args.form_content = gadget.props.form_content;
delete gadget.props.form_content;
}
return { return {
url: "gadget_erp5_page_" + command_options.args.page + ".html", url: "gadget_erp5_page_" + command_options.args.page + ".html",
// XXX Drop this options thing. // XXX Drop this options thing.
...@@ -631,7 +676,7 @@ ...@@ -631,7 +676,7 @@
return execSelectionPreviousCommand(gadget, previous_options); return execSelectionPreviousCommand(gadget, previous_options);
} }
if (command_options.path === COMMAND_HISTORY_PREVIOUS) { if (command_options.path === COMMAND_HISTORY_PREVIOUS) {
return execHistoryPreviousCommand(gadget, previous_options); return execHistoryPreviousCommand(gadget, previous_options, next_options);
} }
if (command_options.path === COMMAND_PUSH_HISTORY) { if (command_options.path === COMMAND_PUSH_HISTORY) {
return execPushHistoryCommand(gadget, previous_options, next_options); return execPushHistoryCommand(gadget, previous_options, next_options);
...@@ -746,6 +791,16 @@ ...@@ -746,6 +791,16 @@
}); });
}); });
}) })
.ready(function (g) {
return g.getDeclaredGadget("jio_form_content")
.push(function (jio_form_content) {
g.props.jio_form_content = jio_form_content;
return jio_form_content.createJio({
type: "local",
sessiononly: true
});
});
})
.declareMethod('getCommandUrlFor', function (options) { .declareMethod('getCommandUrlFor', function (options) {
var command = options.command, var command = options.command,
...@@ -776,6 +831,8 @@ ...@@ -776,6 +831,8 @@
}) })
.declareMethod('redirect', function (options) { .declareMethod('redirect', function (options) {
this.props.form_content = options.form_content;
delete options.form_content;
return this.getCommandUrlFor(options) return this.getCommandUrlFor(options)
.push(function (hash) { .push(function (hash) {
window.location.replace(hash); window.location.replace(hash);
...@@ -824,4 +881,4 @@ ...@@ -824,4 +881,4 @@
}); });
}); });
}(window, rJS, RSVP, loopEventListener, document, jIO, URI, URL)); }(window, rJS, RSVP, loopEventListener, document, jIO, URI, URL, Blob));
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
'gadget_erp5_page_logout.js', 'gadget_erp5_page_logout.js',
'gadget_erp5_page_preference.html', 'gadget_erp5_page_preference.html',
'gadget_erp5_page_preference.js', 'gadget_erp5_page_preference.js',
'gadget_erp5_page_relation_search.html',
'gadget_erp5_page_relation_search.js',
'gadget_erp5_page_search.html', 'gadget_erp5_page_search.html',
'gadget_erp5_page_search.js', 'gadget_erp5_page_search.js',
'gadget_erp5_page_tab.html', 'gadget_erp5_page_tab.html',
......
<?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>testBreadcrumbCanNotAccessRelationSearchPage</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>
<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>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo Line</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>storeLocation</td>
<td>url</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr>
<td>open</td>
<td>${url}</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//h1[@class="ui-title"]/a</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]/a</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Foo Category</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>search</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@class="search_button"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]//a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="field_my_title"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody//tr[1]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr>
<td>open</td>
<td>${url}</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Views"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Views"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="2"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="2"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Actions"]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//a[@data-i18n="Actions"]</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -64,51 +64,7 @@ ...@@ -64,51 +64,7 @@
<td>Quantity</td> <td>Quantity</td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>click</td>
<td>link=Foo: 2</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Foos</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Menu']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
......
...@@ -106,18 +106,29 @@ ...@@ -106,18 +106,29 @@
<td>input</td> <td>input</td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//input[@name='subfield_field_my_successor_title_relation']</td> <td>//li[@name='Foo']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_successor_title']</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@name='Foo']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>type</td> <td>type</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_foo_category_title']</td>
...@@ -136,6 +147,12 @@ ...@@ -136,6 +147,12 @@
<td></td> <td></td>
</tr> </tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>blur</td>
</tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</td> <td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</td>
...@@ -168,13 +185,7 @@ ...@@ -168,13 +185,7 @@
<td>//input[@name='field_my_successor_title']</td> <td>//input[@name='field_my_successor_title']</td>
<td></td> <td></td>
</tr> </tr>
<!--
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']/a[@class='ui-btn ui-corner-all ui-btn-icon-notext ui-icon-plane ui-shadow-inset ui-btn-inline']</td>
<td></td>
</tr>
-->
<tr> <tr>
<td>verifyValue</td> <td>verifyValue</td>
...@@ -188,25 +199,6 @@ ...@@ -188,25 +199,6 @@
<td>a1</td> <td>a1</td>
</tr> </tr>
<!--
<tr>
<td>click</td>
<td>//div[@data-gadget-scope='field_my_successor_title']/a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Jump']</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name='field_my_title']</td>
<td>A new foo</td>
</tr>
-->
</tbody></table> </tbody></table>
</body> </body>
</html> </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>testRelationFieldNotAllowCreation</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>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Views']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n='Views']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Relation Fields']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n='Relation Fields']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>notallowcreation</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore='true']</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//li[@name='Category']</td>
<td></td>
</tr>
</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>testRelationFieldSearchWithListbox</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>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Views"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Views"]</td>
<td></td>
</tr>
<tr>
<td>storeLocation</td>
<td>url</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr>
<td>open</td>
<td>${url}</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Relation Fields"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Relation Fields"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="field_my_successor_title"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>a1</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_title"]</td>
<td>TEST</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_successor_title"]</td>
<td>search</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_successor_title"]</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore="true"]</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[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@class="search_button"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody/tr[1]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//tbody/tr[1]//a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="field_my_successor_title"]</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name="field_my_successor_title"]</td>
<td>2</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name="field_my_title"]</td>
<td>TEST</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
</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>testRelationFieldUnknownIcon</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>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Views']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n='Views']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Relation Fields']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n='Relation Fields']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>unknowntext</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore='true']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>blur</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_foo_category_title"]//a[contains(@class, "ui-icon-warning")]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope="field_my_foo_category_title"]//a[contains(@class, "ui-icon-warning")]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_successor_title']</td>
<td>search</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore='true']</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[@data-explore='true']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='search']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]//a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_foo_category_title"]//a[contains(@class, "ui-icon-warning")]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope="field_my_foo_category_title"]//a[contains(@class, "ui-icon-warning")]</td>
<td></td>
</tr>
</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>testRelationFieldWithNonSavedPageContent</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>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo Line</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]/a</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Foo Category</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name='field_your_portal_type']</td>
<td>label=Foo Line</td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Proceed']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>storeLocation</td>
<td>url</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr>
<td>open</td>
<td>${url}</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//h1[@class="ui-title"]/a</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]/a</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Foo Category</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_short_title"]</td>
<td>TEST</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_foo_big_category_title"]</td>
<td>TEST1</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_big_category_title"]</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@name='Category']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_big_category_title"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@name='Category']</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@name="field_my_frozen"]</td>
<td></td>
</tr>
<tr>
<td>assertChecked</td>
<td>//input[@name="field_my_frozen"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//select[@name="field_my_local_title"]</td>
<td>index=1</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody//tr[1]</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//tbody//tr[1]//input[@title="listbox_start_date"]</td>
<td>2000-12-12</td>
</tr>
<tr>
<td>type</td>
<td>//tbody//tr[1]//input[@title="Quantity"]</td>
<td>2.3</td>
</tr>
<tr>
<td>type</td>
<td>//tbody//tr[1]//input[@title="Quantity"]</td>
<td>2.3</td>
</tr>
<tr>
<td>type</td>
<td>//tbody//tr[2]//input[@title="listbox_start_date"]</td>
<td>2012-12-12</td>
</tr>
<tr>
<td>type</td>
<td>//tbody//tr[2]//input[@title="Quantity"]</td>
<td>10.1</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>search</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//h1[@class="ui-title"]//a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="field_my_short_title"]</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name="field_my_short_title"]</td>
<td>TEST</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//input[@name="field_my_foo_big_category_title"]</td>
<td>TEST1</td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>assertChecked</td>
<td>//input[@name="field_my_frozen"]</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//select[@name="field_my_local_title"]</td>
<td>First title</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody//tr[1]//input[@title="listbox_start_date"]</td>
<td></td>
</tr>
<tr>
<td>verifyValue</td>
<td>//tbody//tr[1]//input[@title="listbox_start_date"]</td>
<td>2000-12-12</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//tbody//tr[1]//input[@title="Quantity"]</td>
<td>2.3</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//tbody//tr[2]//input[@title="listbox_start_date"]</td>
<td>2012-12-12</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//tbody//tr[2]//input[@title="Quantity"]</td>
<td>10.1</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_foo_category_title"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="search"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Modules"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Foos"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Foos"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody/tr[1]/th/a</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//tbody/tr[1]/th/a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Editable"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[@data-i18n="Editable"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name="field_my_short_title"]</td>
<td></td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//input[@name="field_my_short_title"]</td>
<td>TEST</td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//input[@name="field_my_foo_big_category_title"]</td>
<td>TEST1</td>
</tr>
<tr>
<td>verifyTextNotPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>assertNotChecked</td>
<td>//input[@name="field_my_frozen"]</td>
<td></td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//select[@name="field_my_local_title"]</td>
<td>First title</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//tbody//tr[1]//input[@title="listbox_start_date"]</td>
<td></td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//tbody//tr[1]//input[@title="listbox_start_date"]</td>
<td>2000-12-12</td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//tbody//tr[1]//input[@title="Quantity"]</td>
<td>2.3</td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//tbody//tr[2]//input[@title="listbox_start_date"]</td>
<td>2012-12-12</td>
</tr>
<tr>
<td>verifyNotValue</td>
<td>//tbody//tr[2]//input[@title="Quantity"]</td>
<td>10.1</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -108,13 +108,20 @@ ...@@ -108,13 +108,20 @@
<tr> <tr>
<td>waitForElementPresent</td> <td>waitForElementPresent</td>
<td>//input[@name='subfield_field_my_successor_title_relation']</td> <td>//li[@name='Foo']</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>waitForElementPresent</td> <td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td> <td>//input[@name='field_my_successor_title']</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@name='Foo']</td>
<td></td> <td></td>
</tr> </tr>
...@@ -136,6 +143,12 @@ ...@@ -136,6 +143,12 @@
<td></td> <td></td>
</tr> </tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_foo_category_title']</td>
<td>blur</td>
</tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</td> <td>//li[@data-relative-url='portal_categories/foo_category/a/a1']</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