Commit dc796546 authored by Xiaowu Zhang's avatar Xiaowu Zhang

erp5_web_renderjs_ui: add a common gadget to render multi&relation field & no...

erp5_web_renderjs_ui: add a common gadget to render multi&relation field & no need to show "Create:X" string

/reviewed-on nexedi/erp5!140
parents 0aea5167 8bddeb7d
......@@ -205,6 +205,8 @@ gadget_erp5_pt_report_view.html\n
gadget_erp5_pt_report_view.js\n
gadget_erp5_router.html\n
gadget_erp5_router.js\n
gadget_erp5_relation_input.html\n
gadget_erp5_relation_input.js\n
gadget_erp5_search_editor.html\n
gadget_erp5_search_editor.js\n
gadget_erp5_searchfield.html\n
......@@ -358,7 +360,7 @@ NETWORK:\n
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.33119.51229.58811</string> </value>
<value> <string>952.33120.45206.6075</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -376,7 +378,7 @@ NETWORK:\n
</tuple>
<state>
<tuple>
<float>1468331561.38</float>
<float>1468331792.72</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -7,104 +7,10 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="URI.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_field_multirelationstring.js" type="text/javascript"></script>
<script id="create-template" type="text/x-handlebars-template">
<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:{{text}}
</li>
</div>
</script>
<script id="single-input-template" type="text/x-handlebars-template">
<fieldset class='single_input add_after'>
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon">
<input type='text' autocomplete="off" data-enhanced="true" >
<a href="#" tabindex="-1" class="ui-hidden-accessible">&nbsp;</a>
<div class="ui-tag-list ui-tag-list-inset"></div>
<ul class="ui-listview ui-corner-all search_ul"></ul>
</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>
</fieldset>
</script>
<script id="multi-input-template" type="text/x-handlebars-template">
<div class="container">
{{#each input}}
<fieldset class="single_input">
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon {{../readonly}}">
{{#if create_object}}
<input type='text' title="{{title}}" name="{{name}}" autocomplete="off" data-enhanced="true" value="{{value}}" data-create-object="{{create_object}}">
{{else}}
<input type='text' title="{{title}}" name="{{name}}" autocomplete="off" data-enhanced="true" value="{{value}}" >
{{/if}}
<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>
{{/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}}
</fieldset>
{{/each}}
</div>
</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>
<div class="container">
</div>
</body>
</html>
\ No newline at end of file
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.27575.44504.22766</string> </value>
<value> <string>952.27591.27746.29798</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1467999805.39</float>
<float>1468331869.06</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, rJS, RSVP, URI, loopEventListener, Handlebars, Event, document,
SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener, $*/
(function (window, rJS, RSVP, URI, loopEventListener, promiseEventListener, document,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, Event, $) {
/*global window, rJS, RSVP, document */
(function (window, rJS, RSVP, document) {
"use strict";
var gadget_klass = rJS(window),
single_input_source = gadget_klass.__template_element
.getElementById("single-input-template")
.innerHTML,
single_input_template = Handlebars.compile(single_input_source),
relation_listview_source = gadget_klass.__template_element
.getElementById("relation-listview-template")
.innerHTML,
relation_listview_template = Handlebars.compile(relation_listview_source),
multi_input_source = gadget_klass.__template_element
.getElementById("multi-input-template")
.innerHTML,
multi_input_template = Handlebars.compile(multi_input_source),
create_source = gadget_klass.__template_element
.getElementById("create-template")
.innerHTML,
create_template = Handlebars.compile(create_source),
searching = "ui-btn ui-corner-all ui-btn-icon-notext" +
" ui-input-clear ui-icon-spinner ui-icon-spin",
searched = "ui-hidden-accessible",
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";
function listenToInput(gadget, index) {
var props = gadget.props,
div = gadget.props.element.querySelectorAll('.single_input')[index],
input = div.querySelector('input'),
search_query,
simple_query,
plane = div.querySelector('.ui-btn'),
field_json = props.field_json,
spinner = div.querySelector('.ui-hidden-accessible'),
create_div = div.querySelector(".ui-tag-list"),
ul = div.querySelector(".search_ul");
function generateList(event) {
var catalog_index = field_json.catalog_index,
begin_from = props.begin_from || 0,
lines = field_json.lines || 10,
my_value = event.target.value;
ul.innerHTML = "";
create_div.innerHTML = "";
plane.className = jump_off;
props.jump_url[index] = "";
if (my_value === "") {
spinner.className = searched;
return;
}
simple_query = new SimpleQuery({
key: catalog_index,
value: my_value
});
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": [catalog_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[catalog_index]
});
}
spinner.className = searched;
html = relation_listview_template({
list: list,
type: type,
value: my_value
});
$(ul).toggle();
ul.innerHTML = html;
$(ul).toggle();
});
}
function setSelectedElement(event) {
var element = event.target,
jump_url = element.getAttribute("data-relative-url"),
create_object_type = element.getAttribute("data-create-object"),
explore = element.getAttribute("data-explore"),
tmp;
ul.innerHTML = "";
if (index === gadget.props.last_index - 1 && !explore) {
props.jump_url[gadget.props.last_index] = "";
tmp = document.createElement("fieldset");
tmp.innerHTML = single_input_template();
gadget.props.container.appendChild(tmp);
gadget.props.input_list.push({
"title": field_json.key,
"name": field_json.key,
"value": "",
"href": "",
"create_object": ""
});
gadget.props.last_index += 1;
gadget.props.element.dispatchEvent(new Event('add_relation_input'));
}
if (jump_url) {
props.jump_url[index] = jump_url;
input.value = element.textContent;
return gadget.getUrlFor({
command: 'index',
options: {
jio_key: jump_url
}
}).push(function (url) {
if (field_json.allow_jump) {
plane.href = url;
plane.className = jump_on;
}
});
}
if (create_object_type) {
input.setAttribute("data-create-object", create_object_type);
plane.className = jump_add;
create_div.innerHTML = create_template({'text': create_object_type});
return;
}
if (explore) {
return gadget.getFormContent({
format: "json"
})
.push(function (content) {
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: index
},
form_content: content
});
});
}
plane.className = jump_unknown;
}
return RSVP.all([
loopEventListener(input, 'input', false, generateList),
loopEventListener(input, 'blur', false, function () {
return new RSVP.Queue()
.push(function () {
return RSVP.any([
RSVP.delay(200),
promiseEventListener(ul, "click", true)
]);
})
.push(function (event) {
var tmp;
if (event) {
return setSelectedElement(event);
}
if (ul.innerHTML) {
ul.innerHTML = "";
plane.className = jump_unknown;
if (index === gadget.props.last_index - 1) {
props.jump_url[gadget.props.last_index] = "";
tmp = document.createElement("fieldset");
tmp.innerHTML = single_input_template();
gadget.props.container.appendChild(tmp);
gadget.props.input_list.push({
"title": field_json.key,
"name": field_json.key,
"value": "",
"href": "",
"create_object": ""
});
gadget.props.last_index += 1;
gadget.props.element.dispatchEvent(new Event('add_relation_input'));
}
}
});
})]
);
}
rJS(window)
/////////////////////////////////////////////////////////////////
......@@ -227,17 +16,35 @@
gadget.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getFormContent", "getFormContent")
.allowPublicAcquisition("addRelationInput", function () {
var fieldset = document.createElement("fieldset"),
gadget = this,
container = gadget.props.element.querySelector('.container');
return gadget.declareGadget('gadget_erp5_relation_input.html', {
element: fieldset
})
.push(function (relation_input) {
var field_json = gadget.props.field_json,
index;
if (field_json.default.value) {
index = field_json.default.relation_item_relative_url.length;
field_json.default.relation_item_relative_url.push('');
field_json.default.value.push('');
} else {
index = field_json.relation_item_relative_url.length;
field_json.relation_item_relative_url.push('');
field_json.default.push('');
}
gadget.props.gadget_list.push(relation_input);
return relation_input.render({field_json: gadget.props.field_json}, {
index: index,
addRelationInput: true
});
})
.push(function () {
container.appendChild(fieldset);
});
})
/////////////////////////////////////////////////////////////////
// declared methods
......@@ -245,172 +52,91 @@
.declareMethod('render', function (options) {
var gadget = this,
i,
field_json = options.field_json || {},
target_url_list = [],
list = [],
input = [],
create_object,
unknown,
uid,
relation_item_relative_url,
value_list;
if (field_json.default.format === "json") {
create_object = field_json.default.create_object || [];
unknown = field_json.default.jump_unknown || [];
uid = field_json.default.uid;
fieldset,
container = gadget.props.element.querySelector('.container'),
field_json = options.field_json || {},
relation_item_relative_url;
gadget.props.field_json = field_json;
if (field_json.default.value) {
if (field_json.default.relation_item_relative_url[field_json.default.relation_item_relative_url.length - 1]) {
//return form listbox
field_json.default.value.push("");
field_json.default.relation_item_relative_url.push("");
}
relation_item_relative_url = field_json.default.relation_item_relative_url;
value_list = field_json.default.value || [];
} else {
create_object = field_json.create_object || [];
unknown = field_json.jump_unknown || [];
uid = field_json.uid;
field_json.relation_item_relative_url.push('');
field_json.default.push('');
relation_item_relative_url = field_json.relation_item_relative_url;
value_list = field_json.default || [];
}
if (relation_item_relative_url) {
target_url_list = relation_item_relative_url;
for (i = 0; i < relation_item_relative_url.length; i += 1) {
fieldset = document.createElement("fieldset");
container.appendChild(fieldset);
list.push(gadget.declareGadget('gadget_erp5_relation_input.html', {
element: fieldset
}));
}
gadget.props.field_json = field_json;
gadget.props.jump_url = [];
gadget.props.query = QueryFactory.create(new URI(field_json.query).query(true).query);
return new RSVP.Queue()
.push(function () {
for (i = 0; i < value_list.length; i += 1) {
if (!value_list[i]) {
if (uid) {
return gadget.jio_allDocs({
query: Query.objectToSearchText(new SimpleQuery({
key: "catalog.uid",
value: uid
})),
limit: [0, 1],
select_list: [field_json.catalog_index]
});
}
}
}
return RSVP.all(list);
})
.push(function (result) {
var non_empty_input = true;
.push(function (gadget_list) {
list = [];
if (result) {
value_list[i] = result.data.rows[0].value[field_json.catalog_index];
}
for (i = 0; i < target_url_list.length; i += 1) {
if (target_url_list[i]) {
gadget.props.jump_url.push(target_url_list[i]);
list.push(gadget.getUrlFor({
command: 'index',
options: {
jio_key: target_url_list[i]
}
}));
} else {
if (!create_object[i]) {
//non jump url nor create onject
non_empty_input = false;
}
gadget.props.jump_url.push("");
list.push("");
}
}
if (non_empty_input) {
value_list.push("");
list.push("");
gadget.props.jump_url.push("");
gadget.props.gadget_list = gadget_list;
for (i = 0; i < gadget_list.length; i += 1) {
list.push(gadget_list[i].render(options, {
index: i,
addRelationInput: (i === gadget_list.length - 1)
}));
}
return RSVP.all(list);
})
.push(function (href_list) {
for (i = 0; i < value_list.length; i += 1) {
input.push({
"create_object": create_object[i],
"title": field_json.key,
"name": field_json.key,
"value": value_list[i],
"href": href_list[i],
"jump_unknown": unknown[i],
"error_text": field_json.error_text
});
}
gadget.props.input_list = input;
gadget.props.default_index = input.length;
gadget.props.last_index = input.length;
return gadget.translateHtml(multi_input_template({
input: input,
allow_jump: field_json.allow_jump,
readonly: field_json.editable ? "" : "ui-state-readonly"
}));
})
.push(function (html) {
gadget.props.element.innerHTML = html;
gadget.props.container = gadget.props.element.querySelector(".container");
});
})
.declareMethod('getContent', function (options) {
var list = this.props.element.querySelectorAll('.single_input'),
result = {},
var list = [],
i,
input,
value_list = [],
plane,
tmp = {},
field_json = this.props.field_json;
if (options.format === "erp5") {
for (i = 0; i < list.length - 1; i += 1) {
plane = list[i].querySelector('.ui-btn');
input = list[i].querySelector('input');
if (plane.className === jump_add) {
result[field_json.relation_field_id + "_" + i] = "_newContent_" + input.getAttribute("data-create-object");
}
value_list.push(input.value);
}
result[field_json.key] = value_list;
return result;
}
tmp.format = "json";
tmp.value = [];
tmp.create_object = [];
tmp.jump_unknown = [];
for (i = 0; i < list.length; i += 1) {
plane = list[i].querySelector('.ui-btn');
input = list[i].querySelector('input');
tmp.value[i] = input.value;
tmp.jump_unknown[i] = "";
tmp.create_object[i] = "";
if (plane.className === jump_add) {
tmp.create_object[i] = input.getAttribute("data-create-object");
} else {
if (plane.className === jump_unknown) {
tmp.jump_unknown[i] = true;
}
}
}
tmp.relation_item_relative_url = this.props.jump_url;
result[field_json.key] = tmp;
return result;
})
.declareService(function () {
var i,
gadget = this,
list = [];
for (i = 0; i < gadget.props.last_index; i += 1) {
list.push(listenToInput(gadget, i));
length = gadget.props.gadget_list.length;
if (options.format === 'erp5') {
length -= 1;
}
return RSVP.all(list);
})
.declareService(function () {
var gadget = this;
return loopEventListener(gadget.props.element, 'add_relation_input', false, function () {
var list = [],
i;
for (i = gadget.props.default_index; i < gadget.props.last_index; i += 1) {
list.push(listenToInput(gadget, i));
}
return RSVP.all(list);
});
for (i = 0; i < length; i += 1) {
list.push(gadget.props.gadget_list[i].getContent(options, {"type": "MultiRelationField"}));
}
return new RSVP.Queue()
.push(function () {
return RSVP.all(list);
})
.push(function (result) {
var tmp = {},
key,
key1;
for (i = 0; i < result.length; i += 1) {
for (key in result[i]) {
if (result[i].hasOwnProperty(key)) {
if (options.format === 'erp5') {
if (tmp[key] === undefined) {
tmp[key] = [];
}
tmp[key].push(result[i][key]);
} else {
if (tmp[key] === undefined) {
tmp[key] = {};
}
for (key1 in result[i][key]) {
if (result[i][key].hasOwnProperty(key1)) {
if (tmp[key][key1] === undefined) {
tmp[key][key1] = [];
}
tmp[key][key1].push(result[i][key][key1][0]);
}
}
}
}
}
}
return tmp;
});
});
}(window, rJS, RSVP, URI, loopEventListener, promiseEventListener, document,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, Event, $));
}(window, rJS, RSVP, document));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.33012.3834.15974</string> </value>
<value> <string>952.33012.29157.25361</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1468325066.65</float>
<float>1468331865.64</float>
<string>UTC</string>
</tuple>
</state>
......
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Relationstringfield</title>
<script src="jquery.js"></script>
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="URI.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_erp5_relation_input.js" type="text/javascript"></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" value="{{value}}" >
<a href="#" tabindex="-1" class="ui-hidden-accessible">&nbsp;</a>
<ul class="ui-listview ui-corner-all search_ul"></ul>
</div>
<a href={{href}} tabindex="-1" class="{{class_name}}" >Jump to this document</a>
</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>
</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_relation_input.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_relation_input_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 Input</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>1467997782.36</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>952.34465.51212.22528</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>1468420120.27</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>1467997763.22</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, rJS, RSVP, URI, loopEventListener, Handlebars,
SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener, $*/
(function (window, rJS, RSVP, URI, loopEventListener, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, $) {
"use strict";
var gadget_klass = rJS(window),
relation_input_source = gadget_klass.__template_element
.getElementById("relation-input-template")
.innerHTML,
relation_input_template = Handlebars.compile(relation_input_source),
relation_listview_source = gadget_klass.__template_element
.getElementById("relation-listview-template")
.innerHTML,
relation_listview_template = Handlebars.compile(relation_listview_source),
searching = "ui-btn ui-corner-all ui-btn-icon-notext" +
" ui-input-clear ui-icon-spinner ui-icon-spin",
searched = "ui-hidden-accessible",
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";
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (my_gadget) {
my_gadget.props = {};
return my_gadget.getElement()
.push(function (element) {
my_gadget.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getFormContent", "getFormContent")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("addRelationInput", "addRelationInput")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('render', function (options, options2) {
var gadget = this,
field_json = options.field_json || {},
target_url,
queue = new RSVP.Queue(),
create_object,
unknown,
relation_item_relative_url,
uid,
value = "",
not_selected = true,
index = options2.index || 0;
gadget.props.index = index;
gadget.props.addRelationInput = options2.addRelationInput;
if (field_json.default.value) {
//load non saved value
create_object = field_json.default.create_object ? field_json.default.create_object[index] : false;
unknown = field_json.default.jump_unknown ? field_json.default.jump_unknown[index] : false;
relation_item_relative_url = field_json.default.relation_item_relative_url || [];
uid = field_json.default.uid;
value = field_json.default.value[index] || "";
} else {
create_object = field_json.create_object ? field_json.create_object[index] : false;
unknown = field_json.jump_unknown ? field_json.jump_unknown[index] : false;
relation_item_relative_url = field_json.relation_item_relative_url;
uid = field_json.uid;
value = field_json.default[index] || "";
}
gadget.props.jump_url = [relation_item_relative_url[index]];
if (relation_item_relative_url) {
target_url = relation_item_relative_url[index];
}
gadget.props.field_json = field_json;
gadget.props.query = QueryFactory.create(new URI(field_json.query).query(true).query);
gadget.props.create_object_type = create_object;
if (!value && target_url && uid) {
//return from listbox
not_selected = false;
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 (target_url) {
queue
.push(function () {
return gadget.getUrlFor({
command: 'index',
options: {
jio_key: target_url
}
});
});
}
queue
.push(function (href) {
var class_name,
jump_href = '#';
if (create_object) {
class_name = jump_add;
} else {
if ((field_json.error_text || unknown) && not_selected) {
class_name = jump_unknown;
} else {
if (href) {
if (field_json.allow_jump) {
jump_href = href;
class_name = jump_on;
} else {
class_name = jump_off;
}
} else {
class_name = jump_off;
}
}
}
return gadget.translateHtml(relation_input_template({
href: jump_href,
create_object: create_object,
readonly: field_json.editable ? "" : "ui-state-readonly",
required: field_json.required ? "required" : "",
value: value,
title: field_json.title,
name: field_json.key,
class_name: class_name
}));
})
.push(function (html) {
gadget.props.element.innerHTML = html;
gadget.props.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, options2) {
var element = this.props.element.querySelector('input'),
result = {},
tmp = {},
field_json = this.props.field_json;
if (options.format === "erp5") {
if (this.props.plane.className === jump_add) {
if (options2 && options2.type === 'MultiRelationField') {
result[field_json.relation_field_id + '_' + this.props.index] = "_newContent_" + this.props.create_object_type;
} else {
result[field_json.relation_field_id] = "_newContent_" + this.props.create_object_type;
}
}
result[element.getAttribute('name')] = element.value;
return result;
}
tmp.value = [element.value];
tmp.create_object = [""];
tmp.jump_unknown = [""];
tmp.relation_item_relative_url = [""];
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;
})
/////////////////////////////////////////////////////////////////
// declared services
/////////////////////////////////////////////////////////////////
.declareService(function () {
var gadget = this,
props = gadget.props,
input = gadget.props.element.querySelector('input'),
search_query,
simple_query,
field_json = props.field_json,
ul = gadget.props.element.querySelector(".search_ul");
function generateList(event) {
var index = field_json.catalog_index,
begin_from = props.begin_from || 0,
lines = field_json.lines || 10,
my_value = event.target.value;
props.plane.className = jump_off;
props.jump_url = [];
ul.innerHTML = "";
if (my_value === "") {
props.spinner.className = searched;
return;
}
simple_query = new SimpleQuery({
key: index,
value: my_value
});
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();
});
}
function setSelectedElement(event) {
var element = event.target,
jump_url = element.getAttribute("data-relative-url"),
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) {
if (field_json.allow_jump) {
props.plane.href = url;
props.plane.className = jump_on;
}
});
}
if (create_object_type) {
gadget.props.create_object_type = create_object_type;
props.plane.className = jump_add;
return;
}
if (explore) {
return gadget.getFormContent({
format: "json"
})
.push(function (content) {
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: gadget.props.index
},
form_content: content
});
});
}
props.plane.className = jump_unknown;
}
return RSVP.all([
loopEventListener(input, 'input', false, generateList),
loopEventListener(input, 'blur', false, function () {
return new RSVP.Queue()
.push(function () {
return RSVP.any([
RSVP.delay(200),
promiseEventListener(ul, "click", true)
]);
})
.push(function (event) {
var queue = new RSVP.Queue();
if (event) {
queue
.push(function () {
return setSelectedElement(event);
});
}
if (ul.innerHTML) {
ul.innerHTML = "";
props.plane.className = jump_unknown;
if (gadget.props.addRelationInput) {
gadget.props.addRelationInput = false;
queue.push(function () {
return gadget.addRelationInput();
});
}
}
return queue;
});
})]
);
})
.declareService(function () {
var gadget = this;
function notifyInvalid(evt) {
return gadget.notifyInvalid(evt.target.validationMessage);
}
// Listen to input change
return loopEventListener(
gadget.props.element.querySelector('input'),
'invalid',
false,
notifyInvalid
);
})
.declareService(function () {
////////////////////////////////////
// Check field validity when the value changes
////////////////////////////////////
var gadget = this;
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, $));
<?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>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_relation_input.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_relation_input_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 Input 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>1467996017.5</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>952.34578.31726.63163</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>1468420163.31</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>1467993500.68</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
......@@ -7,82 +7,11 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="URI.js" type="text/javascript"></script>
<script src="handlebars.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>
<script id="create-template" type="text/x-handlebars-template">
<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:{{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>
<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>
{{/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>
<div data-gadget-url="gadget_erp5_relation_input.html"
data-gadget-scope="relation_input"
data-gadget-sandbox="public"></div>
</body>
</html>
\ No newline at end of file
......@@ -228,7 +228,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.27574.44571.31761</string> </value>
<value> <string>952.27574.48547.19899</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -246,7 +246,7 @@
</tuple>
<state>
<tuple>
<float>1467998804.4</float>
<float>1468331862.94</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, rJS, RSVP, URI, loopEventListener, Handlebars,
SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener, $*/
(function (window, rJS, RSVP, URI, loopEventListener, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, $) {
/*global window, rJS */
(function (window, rJS) {
"use strict";
var gadget_klass = rJS(window),
relation_input_source = gadget_klass.__template_element
.getElementById("relation-input-template")
.innerHTML,
relation_input_template = Handlebars.compile(relation_input_source),
relation_listview_source = gadget_klass.__template_element
.getElementById("relation-listview-template")
.innerHTML,
relation_listview_template = Handlebars.compile(relation_listview_source),
create_source = gadget_klass.__template_element
.getElementById("create-template")
.innerHTML,
create_template = Handlebars.compile(create_source),
searching = "ui-btn ui-corner-all ui-btn-icon-notext" +
" ui-input-clear ui-icon-spinner ui-icon-spin",
searched = "ui-hidden-accessible",
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";
rJS(window)
/////////////////////////////////////////////////////////////////
......@@ -46,307 +15,25 @@
return my_gadget.getElement()
.push(function (element) {
my_gadget.props.element = element;
return my_gadget.getDeclaredGadget("relation_input");
})
.push(function (relation_input_gadget) {
my_gadget.props.relation_input_gadget = relation_input_gadget;
});
})
/////////////////////////////////////////////////////////////////
// acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("notifyInvalid", "notifyInvalid")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getFormContent", "getFormContent")
.declareAcquiredMethod("translateHtml", "translateHtml")
.allowPublicAcquisition("addRelationInput", function () {
return;
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('render', function (options) {
var gadget = this,
field_json = options.field_json || {},
target_url,
queue = new RSVP.Queue(),
create_object,
unknown,
relation_item_relative_url,
uid,
value = "";
if (field_json.default.format === "json") {
//load non saved value
create_object = field_json.default.create_object;
unknown = field_json.default.jump_unknown;
relation_item_relative_url = field_json.default.relation_item_relative_url;
uid = field_json.default.uid;
value = field_json.default.value[0] || "";
} 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 (target_url) {
queue
.push(function () {
return gadget.getUrlFor({
command: 'index',
options: {
jio_key: target_url
}
});
});
}
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) {
gadget.props.element.innerHTML = html;
gadget.props.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;
return this.props.relation_input_gadget.render(options, {
index: 0
});
})
.declareMethod('getContent', function (options) {
var element = this.props.element.querySelector('input'),
result = {},
tmp = {},
field_json = this.props.field_json;
if (options.format === "erp5") {
if (this.props.plane.className === jump_add) {
result[field_json.relation_field_id] = "_newContent_" + this.props.create_object_type;
}
result[element.getAttribute('name')] = element.value;
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;
})
/////////////////////////////////////////////////////////////////
// declared services
/////////////////////////////////////////////////////////////////
.declareService(function () {
var gadget = this,
props = gadget.props,
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");
function generateList(event) {
var index = field_json.catalog_index,
begin_from = props.begin_from || 0,
lines = field_json.lines || 10,
my_value = event.target.value;
ul.innerHTML = "";
create_div.innerHTML = "";
props.plane.className = jump_off;
props.jump_url = [];
if (my_value === "") {
props.spinner.className = searched;
return;
}
simple_query = new SimpleQuery({
key: index,
value: my_value
});
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();
});
}
function setSelectedElement(event) {
var element = event.target,
jump_url = element.getAttribute("data-relative-url"),
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) {
if (field_json.allow_jump) {
props.plane.href = url;
props.plane.className = jump_on;
}
});
}
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 (content) {
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
});
});
}
props.plane.className = jump_unknown;
}
return RSVP.all([
loopEventListener(input, 'input', false, generateList),
loopEventListener(input, 'blur', false, function () {
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 () {
var gadget = this;
function notifyInvalid(evt) {
return gadget.notifyInvalid(evt.target.validationMessage);
}
// Listen to input change
return loopEventListener(
gadget.props.element.querySelector('input'),
'invalid',
false,
notifyInvalid
);
})
.declareService(function () {
////////////////////////////////////
// Check field validity when the value changes
////////////////////////////////////
var gadget = this;
function notifyChange() {
return gadget.notifyChange();
}
return loopEventListener(
gadget.props.element.querySelector('input'),
'change',
false,
notifyChange
);
return this.props.relation_input_gadget.getContent(options);
});
}(window, rJS, RSVP, URI, loopEventListener, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars, $));
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.33013.1794.1928</string> </value>
<value> <string>952.33013.17443.54510</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1468325115.92</float>
<float>1468331859.64</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -3,7 +3,7 @@
(function (self, caches, fetch) {
"use strict";
var CACHE_NAME = 'Tue, 24 Jun 2016 16:00:00 GMT',
var CACHE_NAME = 'Thu, 12 July 2016 12:00:00 GMT',
// Files required to make this app work offline
REQUIRED_FILES = [
'./',
......@@ -100,6 +100,8 @@
'gadget_erp5_pt_report_view.js',
'gadget_erp5_router.html',
'gadget_erp5_router.js',
'gadget_erp5_relation_input.html',
'gadget_erp5_relation_input.js',
'gadget_erp5_search_editor.html',
'gadget_erp5_search_editor.js',
'gadget_erp5_searchfield.html',
......@@ -189,4 +191,4 @@
}(self, caches, fetch));
}(self, caches, fetch));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>952.10297.29040.12014</string> </value>
<value> <string>952.33133.9116.24098</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1468327067.19</float>
<float>1468419919.07</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -160,12 +160,6 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
<tr>
......@@ -216,12 +210,6 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[2]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[2]//a[contains(@class, "ui-icon-plus")]</td>
......
......@@ -175,11 +175,7 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
......@@ -326,11 +322,6 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
......
......@@ -137,11 +137,7 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
......@@ -195,11 +191,6 @@
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>click</td>
......@@ -279,11 +270,7 @@
<td>//input[@name="field_my_foo_line_foo_category_title"]</td>
<td>TEST1</td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>assertChecked</td>
......@@ -305,11 +292,7 @@
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//fieldset[1]//div[@class="ui-tag-list ui-tag-list-inset"]//li</td>
<td>Create:Foo</td>
</tr>
......@@ -462,11 +445,7 @@
<td>//input[@name="field_my_foo_line_foo_category_title"]</td>
<td>TEST1</td>
</tr>
<tr>
<td>verifyTextNotPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>assertNotChecked</td>
......
......@@ -206,11 +206,7 @@
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Create:Category</td>
<td></td>
</tr>
<tr>
<td>click</td>
......@@ -334,11 +330,7 @@
<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>
......@@ -488,11 +480,7 @@
<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>
......
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