Commit 2f622c5f authored by preetwinder's avatar preetwinder Committed by preetwinder

[erp5_officejs] Commit sort and search files.

parent 0dfe0a52
<!DOCTYPE html>
<html>
<!--
data-i18n=All criterions (AND)
data-i18n=At least one (OR)
data-i18n=Exact Match
data-i18n=keyword
data-i18n=Contain
data-i18n=Equals To
data-i18n=Greater Than
data-i18n=Less Than
data-i18n=Not Greater Than
data-i18n=Not Less Than
data-i18n=Searchable Text
-->
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Sort Editor</title>
<!-- renderjs -->
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<!-- custom script -->
<script src="gadget_erp5_search_editor.js"></script>
<script id="options-template" type="text/x-handlebars-template">
<select data-iconpos="left">
{{#each option}}
<option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
{{/each}}
</select>
</script>
<script id="filter-item-template" type="text/x-handlebars-template">
<button class="ui-icon ui-btn ui-btn-inline ui-icon-minus ui-icon-shadow"></button>
<div class="filter_item {{class_value}}" >
<select class="column" data-iconpos="left">
{{#each option}}
{{#equal value selected_option}}
<option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
{{else}}
<option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
{{/equal}}
{{/each}}
</select>
<select data-iconpos="left" >
{{#each operator_option}}
{{#equal value selected_option}}
<option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
{{else}}
<option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
{{/equal}}
{{/each}}
</select>
<div class="ui-controlgroup-controls">
<input type="{{input_type}}" value="{{input_value}}"></input>
</div>
</div>
</script>
<script id="filter-template" type="text/x-handlebars-template">
<div class="ui-panel-inner">
<div data-role="header" role="banner" class="ui-header ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<button data-i18n="submit" type="submit" class="submit responsive ui-last-child ui-btn ui-btn-icon-left ui-icon-check">Submit</button>
</div>
</div>
<h1 class="ui-title" role="heading" data-i18n="Filter Editor" aria-level="1">Filter Editor</h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
<button data-i18n="Close" class="close responsive ui-first-child ui-btn ui-btn-icon-left ui-icon-times">Close</button>
</div>
</div>
</div>
<section class="ui-body-c ui-content-section">
<fieldset class="ui-controlgroup ui-corner-all">
<select data-iconpos="left" name="heard_about">
<option data-i18n="All criterions (AND)" value="AND">All criterions (AND)</option>
<option data-i18n="At least one (OR)" value="OR">At least one (OR)</option>
</select>
</fieldset>
<div class="filter_item_container">
</div>
<button class="plus ui-btn-c ui-override-theme ui-btn ui-icon-plus ui-btn-icon-left ui-corner-all">Add Criteria</button>
</section>
</div>
</script>
</head>
<body>
<form class="filter_editor">
<div class="container"></div>
</form>
</body>
</html>
\ No newline at end of file
/*jslint indent: 2, maxerr: 3, maxlen: 100, nomen: true */
/*global window, document, rJS, RSVP, Handlebars,
QueryFactory, SimpleQuery, ComplexQuery, Query, console*/
(function (window, document, rJS, RSVP, Handlebars,
QueryFactory, SimpleQuery, ComplexQuery, Query, console) {
"use strict";
var gadget_klass = rJS(window),
template_element = gadget_klass.__template_element,
filter_item_template = Handlebars.compile(template_element
.getElementById("filter-item-template")
.innerHTML),
filter_template = Handlebars.compile(template_element
.getElementById("filter-template")
.innerHTML),
options_template = Handlebars.compile(template_element
.getElementById("options-template")
.innerHTML),
NUMERIC = [
["Equals To", "="], ["Greater Than", ">"],
["Less Than", "<"], ["Not Greater Than", "<="],
["Not Less Than", ">="]
],
OTHER = [
["Exact Match", "exacte_match"],
["keyword", "keyword"]
],
DEFAULT = [["Contain", "Contain"]];
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);
});
// XXX
// define input's type according to column's value
// the way to determiner is not generic
function isNumericComparison(value) {
return value.indexOf('date') !== -1 ||
value.indexOf('quantity') !== -1 ||
value.indexOf('price') !== -1;
}
function createOptionsTemplate(gadget, value) {
var option = [],
tmp,
i;
if (value !== "searchable_text") {
if (isNumericComparison(value)) {
tmp = NUMERIC;
} else {
tmp = OTHER;
}
} else {
tmp = DEFAULT;
}
for (i = 0; i < tmp.length; i += 1) {
option.push({
text: tmp[i][0],
value: tmp[i][1]
});
}
return gadget.translateHtml(options_template({option: option}));
}
function createFilterItemTemplate(gadget, class_value, filter_item) {
var column_list = gadget.state.search_column_list,
option = [],
tmp,
operator_option = [],
input_type = "search",
i;
if (filter_item) {
if (isNumericComparison(filter_item.key)) {
tmp = NUMERIC;
if (filter_item.key.indexOf("date") !== -1) {
input_type = "date";
} else {
input_type = "number";
}
} else {
tmp = OTHER;
}
} else {
tmp = DEFAULT;
filter_item = {};
}
for (i = 0; i < tmp.length; i += 1) {
operator_option.push({
text: tmp[i][0],
value: tmp[i][1],
selected_option: filter_item.operator
});
}
for (i = 0; i < column_list.length; i += 1) {
option.push({
text: column_list[i][1],
value: column_list[i][0],
selected_option: filter_item.key || "searchable_text"
});
}
return gadget.translateHtml(filter_item_template({
option: option,
operator_option: operator_option,
class_value: class_value,
input_value: filter_item.value,
input_type: input_type
}));
}
gadget_klass
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("trigger", "trigger")
//////////////////////////////////////////////
// initialize the gadget content
//////////////////////////////////////////////
.onStateChange(function () {
var gadget = this,
container = gadget.element.querySelector(".container"),
div = document.createElement("div"),
operator_select,
filter_item_container,
query_list = [],
promise_list = [],
i;
return gadget.translateHtml(filter_template())
.push(function (translated_html) {
div.innerHTML = translated_html;
operator_select = div.querySelector("select");
filter_item_container = div.querySelector(".filter_item_container");
if (gadget.state.extended_search) {
// string to query
try {
query_list = QueryFactory.create(gadget.state.extended_search);
} catch (error) {
// XXX hack to not crash interface
// it catch all error, not only search criteria invalid error
console.warn(error);
return [];
}
if (query_list.operator === "OR") {
operator_select.querySelectorAll("option")[1].selected = "selected";
}
query_list = query_list.query_list || [query_list];
for (i = 0; i < query_list.length; i += 1) {
promise_list.push(createFilterItemTemplate(gadget, "auto", query_list[i]));
}
}
return RSVP.all(promise_list);
})
.push(function (result_list) {
var subdiv;
for (i = 0; i < result_list.length; i += 1) {
subdiv = document.createElement("div");
subdiv.innerHTML = result_list[i];
filter_item_container.appendChild(subdiv);
}
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(div);
});
})
.declareMethod('render', function (options) {
return this.changeState({
search_column_list: options.search_column_list,
begin_from: options.begin_from,
extended_search: options.extended_search
});
})
.onEvent('submit', function () {
var i,
gadget = this,
simple_operator,
query,
key,
select_list,
simple_query_list = [],
complex_query,
select,
value,
options = {},
filter_item_list = gadget.element.querySelectorAll(".filter_item"),
operator_select = gadget.element.querySelector("select"),
operator = operator_select[operator_select.selectedIndex].value;
for (i = 0; i < filter_item_list.length; i += 1) {
select_list = filter_item_list[i].querySelectorAll("select");
value = filter_item_list[i].querySelector("input").value;
simple_operator = "";
select = select_list[1][select_list[1].selectedIndex].value;
if (select === "keyword") {
value = "%" + value + "%";
} else if (["", ">", "<", "<=", ">="].indexOf(select) !== -1) {
simple_operator = select;
}
if (select_list[0][select_list[0].selectedIndex].value === "searchable_text") {
key = "";
} else {
key = select_list[0][select_list[0].selectedIndex].value;
}
simple_query_list.push(new SimpleQuery(
{
key: key,
operator: simple_operator,
type: "simple",
value: value
}
));
}
if (simple_query_list.length > 0) {
complex_query = new ComplexQuery({
operator: operator,
query_list: simple_query_list,
type: "complex"
});
//query to string
query = Query.objectToSearchText(complex_query);
} else {
query = "";
}
options.extended_search = query;
options[gadget.state.begin_from] = undefined;
return gadget.redirect({
command: 'store_and_change',
options : options
});
})
.onEvent('click', function (evt) {
var gadget = this;
if (evt.target.classList.contains('close')) {
evt.preventDefault();
return this.trigger();
}
if (evt.target.classList.contains('plus')) {
evt.preventDefault();
return createFilterItemTemplate(gadget, 'auto')
.push(function (template) {
var tmp = document.createElement("div"),
container = gadget.element.querySelector(".filter_item_container");
tmp.innerHTML = template;
container.appendChild(tmp);
});
}
if (evt.target.classList.contains('ui-icon-minus')) {
evt.preventDefault();
evt.target.parentElement.parentElement.removeChild(evt.target.parentElement);
}
}, false, false)
.onEvent('change', function (evt) {
var gadget = this;
if (evt.target.classList.contains('column')) {
evt.preventDefault();
return createOptionsTemplate(gadget, evt.target.value)
.push(function (innerHTML) {
evt.target.parentElement.querySelectorAll('select')[1].innerHTML = innerHTML;
if (isNumericComparison(evt.target.value)) {
if (evt.target.value.indexOf("date") !== -1) {
evt.target.parentElement.querySelector('input').setAttribute("type", "date");
} else {
evt.target.parentElement.querySelector('input').setAttribute("type", "number");
}
} else {
evt.target.parentElement.querySelector('input').setAttribute("type", "text");
}
});
}
}, false, false);
}(window, document, rJS, RSVP, Handlebars,
QueryFactory, SimpleQuery, ComplexQuery, Query, console));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Sort Editor</title>
<!-- renderjs -->
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<!-- custom script -->
<script src="gadget_erp5_sort_editor.js"></script>
<script id="sort-item-template" type="text/x-handlebars-template">
<button type="submit" class="ui-icon ui-btn ui-btn-inline ui-icon-minus ui-icon-shadow"></button>
<div class="sort_item ui-controlgroup-controls" >
<select data-iconpos="left">
{{#each option}}
{{#equal value selected_option}}
<option selected="selected" data-i18n="{{text}}" value="{{value}}">{{text}}</option>
{{else}}
<option value="{{value}}" data-i18n="{{text}}">{{text}}</option>
{{/equal}}
{{/each}}
</select>
<select data-wrapper-class="ui-input-has-clear" data-iconpos="left">
<option {{#equal operator "ascending"}}selected="selected"{{/equal}} data-i18n="ascending" value="ascending">ascending</option>
<option {{#equal operator "descending"}}selected="selected"{{/equal}} data-i18n="descending" value="descending">descending</option>
</select>
</div>
</script>
<script id="sort-template" type="text/x-handlebars-template">
<div class="ui-panel-inner">
<div data-role="header" role="banner" class="ui-header ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<button data-rel="save" data-i18n="Submit" type="submit" class="submit responsive ui-last-child ui-btn ui-btn-icon-left ui-icon-check">Submit</button>
</div>
</div>
<h1 class="ui-title" role="heading" data-i18n="Sort Editor" aria-level="1">Sort Editor</h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
<button data-i18n="Close" data-rel="close" type="submit" class="close responsive ui-first-child ui-btn ui-btn-icon-left ui-icon-times">Close</button>
</div>
</div>
</div>
<section class="ui-body-c ui-content-section">
<div class="sort_item_container ui-controlgroup ui-corner_all"></div>
<button type="submit" class="plus ui-btn-c ui-override-theme ui-btn ui-icon-plus ui-btn-icon-left ui-corner-all">Add Criteria</button>
</section>
</div>
</script>
</head>
<body>
<form class="sort_editor">
<div class="container"></div>
</form>
</body>
</html>
\ No newline at end of file
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, document, rJS, RSVP, Handlebars*/
(function (window, document, rJS, RSVP, Handlebars) {
"use strict";
var gadget_klass = rJS(window),
template_element = gadget_klass.__template_element,
sort_item_template = Handlebars.compile(template_element
.getElementById("sort-item-template")
.innerHTML),
sort_template = Handlebars.compile(template_element
.getElementById("sort-template")
.innerHTML);
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);
});
function createSortItemTemplate(gadget, sort_value) {
var sort_column_list = gadget.state.sort_column_list,
sort_value_list = sort_value || [],
option_list = [],
i;
for (i = 0; i < sort_column_list.length; i += 1) {
option_list.push({
text: sort_column_list[i][1],
value: sort_column_list[i][0],
selected_option: sort_value_list[0]
});
}
return gadget.translateHtml(sort_item_template({
option: option_list,
operator: sort_value_list[1]
}));
}
/* Valid sort item is a tuple of (column-name, ordering) */
function isValidSortItem(sort_item) {
return sort_item.length === 2 &&
(sort_item[1] === 'ascending' || sort_item[1] === 'descending');
}
gadget_klass
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("trigger", "trigger")
.onStateChange(function () {
var gadget = this,
div = document.createElement("div"),
container = gadget.element.querySelector(".container");
return gadget.translateHtml(sort_template())
.push(function (translated_html) {
div.innerHTML = translated_html;
return RSVP.all(gadget.state.sort_list
.filter(isValidSortItem)
.map(function (sort_item) {
return createSortItemTemplate(gadget, sort_item);
})
);
})
.push(function (result_list) {
var i,
subdiv,
filter_item_container = div.querySelector('.sort_item_container');
for (i = 0; i < result_list.length; i += 1) {
subdiv = document.createElement("div");
subdiv.innerHTML = result_list[i];
filter_item_container.appendChild(subdiv);
}
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(div);
});
})
.declareMethod('render', function (options) {
return this.changeState({
sort_column_list: options.sort_column_list || [],
key: options.key,
sort_list: options.sort_list
});
})
.onEvent('click', function (evt) {
var gadget = this;
if (evt.target.classList.contains('close')) {
evt.preventDefault();
return this.trigger();
}
if (evt.target.classList.contains('plus')) {
evt.preventDefault();
return createSortItemTemplate(gadget)
.push(function (template) {
var tmp = document.createElement("div"),
container = gadget.element.querySelector(".sort_item_container");
tmp.innerHTML = template;
container.appendChild(tmp);
});
}
if (evt.target.classList.contains('ui-icon-minus')) {
evt.preventDefault();
evt.target.parentElement.parentElement.removeChild(evt.target.parentElement);
}
}, false, false)
.onEvent('submit', function () {
var gadget = this,
sort_list = gadget.element.querySelectorAll(".sort_item"),
sort_query = [],
select_list,
sort_item,
options = {},
i;
for (i = 0; i < sort_list.length; i += 1) {
sort_item = sort_list[i];
select_list = sort_item.querySelectorAll("select");
sort_query[i] = [select_list[0][select_list[0].selectedIndex].value,
select_list[1][select_list[1].selectedIndex].value];
}
if (i === 0) {
options[gadget.state.key] = undefined;
} else {
options[gadget.state.key] = sort_query;
}
return gadget.redirect({
command: 'store_and_change',
options: options
});
});
}(window, document, rJS, RSVP, Handlebars));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment