Commit 50504c85 authored by Xiaowu Zhang's avatar Xiaowu Zhang

erp5_web_renderjs_ui: improve filter editor and add sort editor.

1. use QueryFactory to process query in filter editor and listbox
2. add draft support for sort editor
3. add layout for hide rows functionality in listbox
parent 1662cbe4
......@@ -73,13 +73,14 @@ return context.ERP5Document_getHateoas(\n
default_param_json=default_param_json,\n
form_relative_url=form_relative_url,\n
bulk_list=bulk_list,\n
sort_on=sort_on,\n
restricted=1\n
)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]"</string> </value>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -75,18 +75,18 @@ url_template_dict = {\n
"traverse_template": "%(root_url)s/%(script_id)s?mode=traverse" + \\\n
"{&relative_url,view}",\n
"search_template": "%(root_url)s/%(script_id)s?mode=search" + \\\n
"{&query,select_list*,limit*}",\n
"{&query,select_list*,limit*,sort_on*}",\n
"custom_search_template": "%(root_url)s/%(script_id)s?mode=search" + \\\n
"&relative_url=%(relative_url)s" \\\n
"&form_relative_url=%(form_relative_url)s" \\\n
"&list_method=%(list_method)s" \\\n
"&default_param_json=%(default_param_json)s" \\\n
"{&query,select_list*,limit*}",\n
"{&query,select_list*,limit*,sort_on*}",\n
"custom_search_template_no_editable": "%(root_url)s/%(script_id)s?mode=search" + \\\n
"&relative_url=%(relative_url)s" \\\n
"&list_method=%(list_method)s" \\\n
"&default_param_json=%(default_param_json)s" \\\n
"{&query,select_list*,limit*}",\n
"{&query,select_list*,limit*,sort_on*}",\n
"new_content_action": "%(root_url)s/%(script_id)s?mode=newContent",\n
"bulk_action": "%(root_url)s/%(script_id)s?mode=bulk",\n
# XXX View is set by default to empty\n
......@@ -103,9 +103,9 @@ def getAllSubCategoriesAsMap(root):\n
sub_categories_list = root.objectValues()\n
if len(sub_categories_list) != 0:\n
for grain in sub_categories_list:\n
result[grain.getTitle()] = {"sub_categories": getAllSubCategoriesAsMap(grain),\n
"id": grain.getId(),\n
"uid": grain.getUid()}\n
result[grain.getId()] = {"sub_categories": getAllSubCategoriesAsMap(grain),\n
"title": grain.getTitle(),\n
"uid": grain.getUid()}\n
\n
return result\n
\n
......@@ -392,8 +392,8 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
domain_tree = field.get_value("domain_root_list")\n
for tree in domain_tree:\n
if hasattr(portal_categories, tree[0]):\n
domain_tree_map[tree[1]] = {"sub_categories":getAllSubCategoriesAsMap(portal_categories[tree[0]]),\n
"id": tree[0],\n
domain_tree_map[tree[0]] = {"sub_categories":getAllSubCategoriesAsMap(portal_categories[tree[0]]),\n
"title": tree[1],\n
"uid": portal_categories[tree[0]].getUid()}\n
\n
result = {\n
......@@ -921,11 +921,18 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
callable_list_method = portal.portal_catalog\n
else:\n
callable_list_method = getattr(traversed_document, list_method)\n
\n
tmp_sort_on = ()\n
if sort_on is not None:\n
for grain in sort_on:\n
if grain != "":\n
tmp_sort_on += (tuple([x for x in grain.split(",")]),)\n
\n
if query:\n
sql_list = callable_list_method(full_text=query, limit=limit, **catalog_kw)\n
sql_list = callable_list_method(full_text=query, limit=limit, sort_on=tmp_sort_on, **catalog_kw)\n
else:\n
sql_list = callable_list_method(limit=limit, **catalog_kw)\n
\n
sql_list = callable_list_method(limit=limit, sort_on=tmp_sort_on, **catalog_kw)\n
\n
result_list = []\n
\n
# if (select_list is None):\n
......@@ -1081,7 +1088,7 @@ else:\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, restricted=0, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]"</string> </value>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, form=None, relative_url=None, restricted=0, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=()</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -137,6 +137,10 @@
<option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>\n
</script>\n
\n
\n
\n
\n
\n
<script id="filter-template" type="text/x-handlebars-template">\n
<div class="ui-panel-inner">\n
\n
......@@ -153,7 +157,7 @@
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">\n
<div class="ui-controlgroup-controls">\n
<form class="submit">\n
<button data-rel="save" type="submit" class="submit responsive ui-last-child ui-btn ui-btn-icon-right ui-icon-check">Save</button>\n
<button data-rel="save" type="submit" class="submit responsive ui-last-child ui-btn ui-btn-icon-left ui-icon-check">Save</button>\n
</form>\n
</div>\n
</div>\n
......@@ -345,7 +349,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.22508.10889.31197</string> </value>
<value> <string>945.37783.58290.59204</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -363,7 +367,7 @@
</tuple>
<state>
<tuple>
<float>1440760242.27</float>
<float>1442309257.72</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -221,6 +221,9 @@
if (form_definition.extended_search) {\n
suboption_dict.extended_search = form_definition.extended_search;\n
}\n
if (form_definition.extended_sort_list) {\n
suboption_dict.extended_sort_list = form_definition.extended_sort_list;\n
}\n
\n
form_gadget.props.gadget_list = [];\n
form_gadget.props.id = erp5_document._id;\n
......@@ -500,7 +503,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>xiaowu</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -514,7 +517,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>944.22467.53128.26641</string> </value>
<value> <string>945.49324.9572.9676</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -532,8 +535,8 @@
</tuple>
<state>
<tuple>
<float>1436753892.36</float>
<string>GMT+2</string>
<float>1442309628.83</float>
<string>UTC</string>
</tuple>
</state>
</object>
......
......@@ -163,6 +163,10 @@
<div data-gadget-url="gadget_erp5_filter_editor.html"\n
data-gadget-scope="filterEditor"\n
data-gadget-sandbox="public"></div>\n
\n
<div data-gadget-url="gadget_erp5_sort_editor.html"\n
data-gadget-scope="sortEditor"\n
data-gadget-sandbox="public"></div>\n
\n
<div role="main" class="ui-content gadget-content"></div>\n
......@@ -310,7 +314,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.18332.59164.9181</string> </value>
<value> <string>945.49198.46948.13260</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -328,7 +332,7 @@
</tuple>
<state>
<tuple>
<float>1440437597.42</float>
<float>1442309444.67</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -498,6 +498,9 @@
.allowPublicAcquisition(\'triggerFilterEditor\', function () {\n
return route(this, "filterEditor", "toggle");\n
})\n
.allowPublicAcquisition("triggleSortEditor", function () {\n
return route(this, "sortEditor", "toggle");\n
})\n
\n
.allowPublicAcquisition("jio_allDocs", function (param_list) {\n
return callJioGadget(this, "allDocs", param_list);\n
......
......@@ -120,22 +120,26 @@
\n
<!-- custom script -->\n
<script src="gadget_erp5_field_listbox.js" type="text/javascript"></script>\n
\n
\n
</head>\n
<body>\n
\n
<!-- XXX must set a theme here -->\n
<section class="document_table">\n
<div class="ui-table-header ui-header ui-bar-c ui-corner-all">\n
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">\n
<div class="ui-controlgroup-controls">\n
<a data-i18n="hide" class="ui-responsive ui-btn ui-btn-icon-left ui-icon-eye ui-first-child ui-override-theme ui-disabled" href="#">Hide Rows</a>\n
<form class="hide_form">\n
<button data-rel="hide" type="submit" class="submit responsive ui-last-child ui-btn ui-icon-eye ui-btn-icon-left">Hide Rows</button>\n
</form>\n
</div>\n
</div>\n
<h1 data-i18n="selected" class="ui-title ui-override-theme">0 items selected</h1>\n
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">\n
<div class="ui-controlgroup-controls">\n
<a data-i18n="sort" class="ui-responsive ui-btn ui-btn-icon-left ui-icon-sort-amount-desc ui-last-child ui-override-theme ui-disabled" href="#">Sort</a>\n
<form class="sort_form">\n
<button data-rel="Sort" type="submit" class="submit responsive ui-last-child ui-btn ui-icon-sort-amount-desc ui-btn-icon-left">Sort</button>\n
</form>\n
</div>\n
</div>\n
</div>\n
......@@ -269,7 +273,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>super_sven</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -283,7 +287,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>939.51034.42464.64273</string> </value>
<value> <string>945.49220.61498.30600</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -301,8 +305,8 @@
</tuple>
<state>
<tuple>
<float>1419418783.77</float>
<string>GMT</string>
<float>1442307840.51</float>
<string>UTC</string>
</tuple>
</state>
</object>
......
......@@ -108,9 +108,11 @@
<value> <string encoding="cdata"><![CDATA[
/*jslint indent: 2, maxerr: 3, nomen: true */\n
/*global window, document, rJS, URI, RSVP, UriTemplate */\n
/*global window, document, rJS, URI, RSVP, UriTemplate, QueryFactory, loopEventListener */\n
(function (window, document, rJS, URI, RSVP, UriTemplate) {\n
"use strict";\n
\n
\n
\n
rJS(window)\n
/////////////////////////////////////////////////////////////////\n
......@@ -131,6 +133,7 @@
g.props.element = element;\n
});\n
})\n
\n
\n
//////////////////////////////////////////////\n
// acquired method\n
......@@ -140,6 +143,7 @@
.declareAcquiredMethod("getUrlFor", "getUrlFor")\n
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")\n
.declareAcquiredMethod("getFieldTypeGadgetUrl", "getFieldTypeGadgetUrl")\n
.declareAcquiredMethod("triggleSortEditor", "triggleSortEditor")\n
//////////////////////////////////////////////\n
// initialize the gadget content\n
//////////////////////////////////////////////\n
......@@ -155,6 +159,9 @@
\n
gadget.props.field_json = field_json;\n
gadget.props.extended_search = options.extended_search;\n
if (options.extended_sort_list) {\n
gadget.props.extended_sort_list = Object.keys(options.extended_sort_list).map(function (key) {return options.extended_sort_list[key]; });\n
}\n
if (field_json.show_anchor) {\n
th = document.createElement("th");\n
th.textContent = "Jump";\n
......@@ -188,13 +195,14 @@
//////////////////////////////////////////////\n
// render the listbox in an asynchronous way\n
//////////////////////////////////////////////\n
.declareService(function () {\n
.declareMethod(\'createListboxItem\', function (options) {\n
var gadget = this,\n
props = gadget.props,\n
field_json = props.field_json,\n
begin_from = props.begin_from,\n
table = props.element.querySelector(\'table\'),\n
original_tfoot = props.element.querySelector(\'tfoot\'),\n
original_tbody = props.element.querySelector(\'tbody\'),\n
tbody = document.createElement("tbody"),\n
url_query = props.extended_search,\n
query_string = "",\n
......@@ -206,8 +214,10 @@
tmp_query,\n
domain_query,\n
domain_tree_map,\n
sort_list = options.sort_list || [],\n
operator,\n
i,\n
j,\n
list_method_promise = function () {\n
return gadget.jio_allDocs.apply(gadget, arguments);\n
};\n
......@@ -219,43 +229,42 @@
// return previous + next[0] + \':= "\' + url_query + \'" OR \';\n
// }\n
//rebuild query\n
//don\'t know a good idea\n
if (url_query) {\n
domain_tree_map = props.field_json.domain_tree_map;\n
tmp_query = url_query.split(" OR ");\n
operator = " OR ";\n
if (tmp_query.length === 1) {\n
tmp_query = url_query.split(" AND ");\n
operator = " AND ";\n
}\n
tmp_query = QueryFactory.create(url_query);\n
operator = tmp_query.operator ? " " + tmp_query.operator + " " : " AND ";\n
tmp_query = tmp_query.query_list || [tmp_query];\n
\n
url_query = "";\n
for (i = 0; i < tmp_query.length; i += 1) {\n
if (i !== 0) {\n
url_query += operator;\n
}\n
if (tmp_query[i].indexOf("Domain:") !== -1) {\n
domain_query = tmp_query[i].split(":")[1].split("/");\n
if (tmp_query[i].key === "Domain") {\n
domain_query = tmp_query[i].value.split("/");\n
if (domain_query[0] !== "--") {\n
url_query += "category.base_category_uid: " + domain_tree_map[domain_query[0]].uid;\n
domain_tree_map = domain_tree_map[domain_query[0]].sub_categories;\n
for (i = 1; i < domain_query.length - 1; i += 1) {\n
last_uid = domain_tree_map[domain_query[i]].uid;\n
domain_tree_map = domain_tree_map[domain_query[i]].sub_categories;\n
for (j = 1; j < domain_query.length - 1; j += 1) {\n
last_uid = domain_tree_map[domain_query[j]].uid;\n
domain_tree_map = domain_tree_map[domain_query[j]].sub_categories;\n
}\n
if (i < domain_query.length && domain_query[i] !== "--") {\n
if (j < domain_query.length && domain_query[j] !== "--") {\n
url_query += operator;\n
url_query += "category.category_uid: " + domain_tree_map[domain_query[i]].uid;\n
} else if (i !== 1) {\n
url_query += "category.category_uid: " + domain_tree_map[domain_query[j]].uid;\n
} else if (j !== 1) {\n
url_query += operator;\n
url_query += "category.category_uid: " + last_uid;\n
}\n
}\n
} else {\n
url_query += tmp_query[i];\n
if (tmp_query[i].operator) {\n
url_query += tmp_query[i].key + ":" + tmp_query[i].operator + tmp_query[i].value;\n
} else {\n
url_query += tmp_query[i].key + ":" + tmp_query[i].value;\n
}\n
}\n
}\n
\n
\n
//query_string = field_json.column_list.reduce(buildQueryString, \' AND (\').replace(new RegExp("OR " + \'$\'), \')\');\n
if (field_json.list_method_template === undefined) {\n
query_string = \' AND \' + url_query;\n
......@@ -268,12 +277,15 @@
select_list.push(field_json.column_list[i][0]);\n
}\n
\n
select_list.push("uid");\n
return gadget.jio_allDocs({\n
// XXX Not jIO compatible, but until a better api is found...\n
"list_method_template": field_json.list_method_template,\n
"query": new URI(field_json.query).query(true).query + query_string,\n
"limit": [begin_from, lines + 1],\n
"select_list": select_list\n
"select_list": select_list,\n
"sort_on": sort_list\n
}).push(function (result) {\n
var promise_list = [result];\n
counter = Math.min(result.data.total_rows, lines);\n
......@@ -293,8 +305,7 @@
return RSVP.all(promise_list);\n
\n
}).push(function (result_list) {\n
var j,\n
tr,\n
var tr,\n
th,\n
a,\n
result = result_list[0],\n
......@@ -322,6 +333,7 @@
dataset = result;\n
for (i = 0; i < counter; i += 1) {\n
tr = document.createElement("tr");\n
tr.setAttribute("value", result.data.rows[i].value.uid);\n
tmp_url = result_list[i + 1];\n
\n
if (field_json.show_anchor) {\n
......@@ -456,7 +468,7 @@
fragment.appendChild(tbody);\n
fragment.appendChild(tfoot);\n
\n
for (len = table.children.length; len > 0; len -= 1) {\n
for (len = table.children.length; len > 1; len -= 1) {\n
table.removeChild(table.lastChild);\n
}\n
// NOTE: for passing translations, temp must contain a table\n
......@@ -471,8 +483,58 @@
table.appendChild(temp);\n
});\n
})\n
.declareService(function () {\n
var gadget = this;\n
return gadget.createListboxItem({"sort_list": gadget.props.extended_sort_list});\n
})\n
.declareService(function () {\n
var gadget = this,\n
sort_form = gadget.props.element.querySelector(".sort_form");\n
loopEventListener(\n
sort_form,\n
"submit",\n
false,\n
function () {\n
gadget.triggleSortEditor();\n
}\n
);\n
})\n
.declareService(function () {\n
var gadget = this,\n
hide_form = gadget.props.element.querySelector(".hide_form");\n
/* hide form */\n
loopEventListener(\n
hide_form,\n
"submit",\n
false,\n
function () {\n
var tr_list = gadget.props.element.querySelector("tbody").querySelectorAll("tr"),\n
thead_tr = gadget.props.element.querySelector("thead").querySelector("tr"),\n
i,\n
th,\n
hide_form_elements,\n
checkbox;\n
\n
hide_form_elements = gadget.props.element.querySelectorAll(".hide_form_element");\n
if (hide_form_elements.length > 0) {\n
for (i = 0; i < hide_form_elements.length; i += 1) {\n
hide_form_elements[i].parentElement.removeChild(hide_form_elements[i]);\n
}\n
return;\n
}\n
th = document.createElement("th");\n
\n
th.setAttribute("class", "hide_form_element");\n
thead_tr.insertBefore(th, thead_tr.firstChild);\n
for (i = 0; i < tr_list.length; i += 1) {\n
checkbox = document.createElement("input");\n
checkbox.setAttribute("type", "checkbox");\n
checkbox.setAttribute("class", "hide_form_element");\n
tr_list[i].insertBefore(checkbox, tr_list[i].firstChild);\n
}\n
}\n
);\n
})\n
.declareMethod("getContent", function () {\n
var form_gadget = this,\n
k,\n
......@@ -651,7 +713,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.28372.10785.47223</string> </value>
<value> <string>945.49507.40992.33228</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -669,7 +731,7 @@
</tuple>
<state>
<tuple>
<float>1441041243.42</float>
<float>1442308372.06</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -139,6 +139,12 @@
\n
form_options.erp5_document = options.erp5_document;\n
form_options.form_definition = options.form_definition;\n
// XXX not generic, fix later\n
if (options.erp5_searchfield) {\n
form_options.form_definition.extended_search = options.erp5_searchfield.extended_search;\n
form_options.form_definition.extended_sort_list = options.erp5_searchfield.sort_list;\n
search_options.extended_search = options.erp5_searchfield.extended_search;\n
}\n
form_options.view = options.view;\n
\n
return new RSVP.Queue()\n
......@@ -342,7 +348,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>946.44927.40202.16725</string> </value>
<value> <string>945.49301.25010.20189</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -360,7 +366,7 @@
</tuple>
<state>
<tuple>
<float>1445939450.54</float>
<float>1442309537.27</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -174,8 +174,12 @@
var sub_options = options.fg;\n
if (sub_options === undefined) {\n
sub_options = {};\n
if(options.filterEditor) {\n
if (options.filterEditor) {\n
sub_options.erp5_searchfield = options.filterEditor;\n
} else {\n
if (options.sortEditor) {\n
sub_options.erp5_searchfield = options.sortEditor;\n
}\n
}\n
}\n
sub_options.erp5_document = erp5_document;\n
......@@ -337,7 +341,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.12418.34036.47547</string> </value>
<value> <string>945.49277.33497.32034</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -355,7 +359,7 @@
</tuple>
<state>
<tuple>
<float>1440083034.81</float>
<float>1442308423.62</float>
<string>UTC</string>
</tuple>
</state>
......
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