Commit ea3b93fb authored by Romain Courteaud's avatar Romain Courteaud

[erp5_web_renderjs_ui] Rewrite relation field

Support calling render method multiple times.
parent 7b480c8f
/*jslint indent: 2, maxerr: 3, nomen: true */ /*jslint indent: 2, maxerr: 3, nomen: true, unparam: true, maxlen: 80 */
/*global window, rJS, RSVP, document */ /*global window, rJS, RSVP, document */
(function (window, rJS, RSVP, document) { (function (window, rJS, RSVP, document) {
"use strict"; "use strict";
rJS(window) function addRelationInput(gadget, value_relative_url, value_text,
value_uid, value_portal_type, index) {
///////////////////////////////////////////////////////////////// var input_gadget;
// ready return gadget.declareGadget('gadget_erp5_relation_input.html', {
///////////////////////////////////////////////////////////////// element: document.createElement("fieldset")
// Init local properties
.ready(function (gadget) {
gadget.props = {};
return gadget.getElement()
.push(function (element) {
gadget.props.element = element;
});
}) })
.allowPublicAcquisition("addRelationInput", function () { .push(function (result) {
var fieldset = document.createElement("fieldset"), input_gadget = result;
gadget = this, return input_gadget.render({
container = gadget.props.element.querySelector('.container'); editable: gadget.state.editable,
return gadget.declareGadget('gadget_erp5_relation_input.html', { query: gadget.state.query,
element: fieldset catalog_index: gadget.state.catalog_index,
}) allow_jump: gadget.state.allow_jump,
.push(function (relation_input) { // required: field_json.required,
var field_json = gadget.props.field_json, title: gadget.state.title,
index; key: gadget.state.key,
if (field_json.default.value) { view: gadget.state.view,
index = field_json.default.relation_item_relative_url.length; url: gadget.state.url,
field_json.default.relation_item_relative_url.push(''); allow_creation: gadget.state.allow_creation,
field_json.default.value.push(''); portal_types: gadget.state.portal_types,
} else { value_relative_url: value_relative_url,
index = field_json.relation_item_relative_url.length; value_text: value_text,
field_json.relation_item_relative_url.push(''); value_uid: value_uid,
field_json.default.push(''); value_portal_type: value_portal_type,
} relation_index: index
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);
}); });
}) })
.push(function () {
gadget.element.appendChild(input_gadget.element);
});
}
rJS(window)
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var field_json = options.field_json || {},
state_dict = {
editable: field_json.editable,
query: field_json.query,
catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump,
required: field_json.required,
title: field_json.title,
key: field_json.key,
view: field_json.view,
url: field_json.url,
allow_creation: field_json.allow_creation,
portal_types: field_json.portal_types,
relation_field_id: field_json.relation_field_id
};
if (field_json.default.hasOwnProperty('value_text_list')) {
//load non saved value
state_dict.value_relative_url_list =
JSON.stringify(field_json.default.value_relative_url_list);
state_dict.value_text_list =
JSON.stringify(field_json.default.value_text_list);
state_dict.value_uid_list =
JSON.stringify(field_json.default.value_uid_list);
state_dict.value_portal_type_list =
JSON.stringify(field_json.default.value_portal_type_list);
} else {
state_dict.value_relative_url_list =
JSON.stringify(field_json.relation_item_relative_url);
state_dict.value_text_list =
JSON.stringify(field_json.default);
state_dict.value_uid_list = JSON.stringify([]);
state_dict.value_portal_type_list = JSON.stringify([]);
}
return this.changeState(state_dict);
})
.onStateChange(function () {
var gadget = this, var gadget = this,
i, i,
list = [], queue = new RSVP.Queue(),
fieldset, element = gadget.element,
container = gadget.props.element.querySelector('.container'), value_relative_url_list =
field_json = options.field_json || {}, JSON.parse(gadget.state.value_relative_url_list),
relation_item_relative_url; value_text_list =
gadget.props.field_json = field_json; JSON.parse(gadget.state.value_text_list),
if (field_json.default.value) { value_uid_list =
if (field_json.default.relation_item_relative_url[field_json.default.relation_item_relative_url.length - 1]) { JSON.parse(gadget.state.value_uid_list),
//return form listbox value_portal_type_list =
field_json.default.value.push(""); JSON.parse(gadget.state.value_portal_type_list);
field_json.default.relation_item_relative_url.push("");
}
relation_item_relative_url = field_json.default.relation_item_relative_url; // Always display an empty value at the end
} else { value_relative_url_list.push("");
field_json.relation_item_relative_url.push(''); value_text_list.push("");
field_json.default.push('');
relation_item_relative_url = field_json.relation_item_relative_url; // Clear first to DOM, append after to reduce flickering/manip
while (element.firstChild) {
element.removeChild(element.firstChild);
} }
for (i = 0; i < relation_item_relative_url.length; i += 1) {
fieldset = document.createElement("fieldset"); function enQueue() {
container.appendChild(fieldset); var argument_list = arguments;
list.push(gadget.declareGadget('gadget_erp5_relation_input.html', { queue
element: fieldset .push(function () {
})); return addRelationInput.apply(this, argument_list);
});
} }
return new RSVP.Queue()
.push(function () { for (i = 0; i < value_relative_url_list.length; i += 1) {
return RSVP.all(list); enQueue(gadget, value_relative_url_list[i], value_text_list[i],
value_uid_list[i], value_portal_type_list[i], i);
}
return queue;
})
.declareAcquiredMethod("notifyChange", "notifyChange")
.allowPublicAcquisition('notifyChange', function (argument_list, scope) {
// An empty relation should be created when the last one is modified
// An empty relation should be removed
var gadget = this,
sub_gadget;
return gadget.getDeclaredGadget(scope)
.push(function (result) {
sub_gadget = result;
return sub_gadget.getContent();
}) })
.push(function (gadget_list) { .push(function (result) {
list = []; var value = result.value_text;
gadget.props.gadget_list = gadget_list; if (sub_gadget.element === gadget.element.lastChild) {
for (i = 0; i < gadget_list.length; i += 1) { if (value) {
list.push(gadget_list[i].render(options, { return addRelationInput(gadget, '', '', undefined, undefined,
index: i, gadget.element.childNodes.length);
addRelationInput: (i === gadget_list.length - 1) }
})); /*
} else {
if (!value) {
gadget.element.removeChild(sub_gadget.element);
}
*/
} }
return RSVP.all(list); })
.push(function () {
return gadget.notifyChange();
}); });
}) })
.declareMethod('getContent', function (options) { .declareMethod('getContent', function (options) {
var list = [], var i,
i, element = this.element,
gadget = this, queue = new RSVP.Queue(),
length = gadget.props.gadget_list.length; final_result = {},
if (options.format === 'erp5') { result_list = [],
length -= 1; gadget = this;
}
for (i = 0; i < length; i += 1) { function calculateSubContent(node) {
list.push(gadget.props.gadget_list[i].getContent(options, {"type": "MultiRelationField"})); queue
.push(function () {
var scope = node.getAttribute('data-gadget-scope');
if (scope !== null) {
return gadget.getDeclaredGadget(
node.getAttribute('data-gadget-scope')
)
.push(function (result) {
return result.getContent();
})
.push(function (result) {
result_list.push(result);
});
}
});
} }
return new RSVP.Queue()
.push(function () { if (this.state.editable) {
return RSVP.all(list); for (i = 0; i < element.childNodes.length; i += 1) {
}) calculateSubContent(element.childNodes[i]);
.push(function (result) { }
var tmp = {}, return queue
key, .push(function () {
key1;
for (i = 0; i < result.length; i += 1) { var result = {},
for (key in result[i]) { j,
if (result[i].hasOwnProperty(key)) { k = 0,
if (options.format === 'erp5') { input_result;
if (tmp[key] === undefined) {
tmp[key] = []; if (options.format === "erp5") {
} result[gadget.state.key] = [];
tmp[key].push(result[i][key]); } else {
} else { result[gadget.state.key] = {
if (tmp[key] === undefined) { value_text_list: [],
tmp[key] = {}; value_relative_url_list: [],
} value_portal_type_list: [],
for (key1 in result[i][key]) { value_uid_list: []
if (result[i][key].hasOwnProperty(key1)) { };
if (tmp[key][key1] === undefined) { }
tmp[key][key1] = []; for (j = 0; j < result_list.length; j += 1) {
} input_result = result_list[j];
tmp[key][key1].push(result[i][key][key1][0]);
if (options.format === "erp5") {
if (input_result.hasOwnProperty('value_text')) {
if (input_result.value_text) {
if (input_result.value_portal_type) {
result[gadget.state.relation_field_id + '_' + k] =
"_newContent_" + input_result.value_portal_type;
} }
result[gadget.state.key].push(input_result.value_text);
} }
} }
k += 1;
} else {
result[gadget.state.key].value_text_list
.push(input_result.value_text);
result[gadget.state.key].value_relative_url_list
.push(input_result.value_relative_url);
result[gadget.state.key].value_portal_type_list
.push(input_result.value_portal_type);
result[gadget.state.key].value_uid_list.push(undefined);
} }
} }
} return result;
return tmp;
}); });
}
return final_result;
}); });
}(window, rJS, RSVP, document)); }(window, rJS, RSVP, document));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>952.33012.29157.25361</string> </value> <value> <string>954.57674.49472.38673</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1468331865.64</float> <float>1477584183.47</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" /> <meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Relationstringfield</title> <title>ERP5 Relation Input</title>
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script> <script src="renderjs.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script> <script src="jiodev.js" type="text/javascript"></script>
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
</script> </script>
<script id="relation-input-template" type="text/x-handlebars-template"> <script id="relation-input-template" type="text/x-handlebars-template">
<div class="relation-input ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon {{readonly}}"> <div class="relation-input ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset ui-input-has-clear ui-input-has-icon">
<div> <div>
<input type='search' title="{{title}}" name="{{name}}" autocomplete="off" {{{input_readonly}}} data-enhanced="true" value="{{value}}" > <input type='search' title="{{title}}" name="{{name}}" autocomplete="off" data-enhanced="true" value="{{value}}" >
<ul class="ui-listview ui-corner-all search_ul"></ul> <ul class="ui-listview ui-corner-all search_ul"></ul>
</div> </div>
<a href={{href}} tabindex="-1" class="{{class_name}}" >Jump to this document</a> <a href={{href}} tabindex="-1" class="{{class_name}}" >Jump to this document</a>
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>954.45675.44850.53452</string> </value> <value> <string>954.54399.20164.63317</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1476956228.04</float> <float>1477475951.1</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint indent: 2, maxerr: 3, nomen: true */ /*jslint indent: 2, maxerr: 3, nomen: true, maxlen: 80 */
/*global window, rJS, RSVP, URI, loopEventListener, Handlebars, /*global window, rJS, RSVP, URI, Handlebars,
SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener*/ SimpleQuery, ComplexQuery, Query, QueryFactory, promiseEventListener*/
(function (window, rJS, RSVP, URI, loopEventListener, promiseEventListener, (function (window, rJS, RSVP, URI, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars) { SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars) {
"use strict"; "use strict";
...@@ -21,37 +21,43 @@ ...@@ -21,37 +21,43 @@
relation_listview_source = gadget_klass.__template_element relation_listview_source = gadget_klass.__template_element
.getElementById("relation-listview-template") .getElementById("relation-listview-template")
.innerHTML, .innerHTML,
relation_listview_template = Handlebars.compile(relation_listview_source), relation_listview_template = Handlebars.compile(relation_listview_source);
searching = "ui-btn ui-corner-all ui-btn-icon-notext" + function displayNonEditableLink(gadget) {
" ui-input-clear ui-icon-spinner ui-icon-spin", return gadget.getUrlFor({
jump_on = "ui-btn ui-corner-all ui-btn-icon-notext " + command: 'index',
"ui-icon-plane ui-shadow-inset ui-btn-inline", options: {
jump_off = "ui-btn ui-corner-all ui-btn-icon-notext " + jio_key: gadget.state.value_relative_url
"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", .push(function (href) {
jump_unknown = "ui-btn ui-corner-all ui-btn-icon-notext " + // XXX Use html5 element gadget
"ui-icon-warning ui-shadow-inset ui-btn-inline ui-disabled"; gadget.element.innerHTML = relation_link_template({
value: gadget.state.value_text,
href: href
});
});
}
function displayNonEditableText(gadget) {
gadget.element.textContent = gadget.state.value_text;
}
rJS(window) function displayEditableLink(gadget, class_name) {
return gadget.translateHtml(relation_input_template({
///////////////////////////////////////////////////////////////// href: "#",
// ready value: gadget.state.value_text,
///////////////////////////////////////////////////////////////// title: gadget.state.title,
// Init local properties name: gadget.state.key,
.ready(function (my_gadget) { class_name: class_name
my_gadget.props = { }))
input_deferred: RSVP.defer() .push(function (html) {
}; gadget.element.innerHTML = html;
return my_gadget.getElement() });
.push(function (element) { }
my_gadget.props.element = element;
});
})
gadget_klass
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// acquired methods // acquired methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -62,375 +68,335 @@ ...@@ -62,375 +68,335 @@
.declareAcquiredMethod("redirect", "redirect") .declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getFormContent", "getFormContent") .declareAcquiredMethod("getFormContent", "getFormContent")
.declareAcquiredMethod("translateHtml", "translateHtml") .declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("addRelationInput", "addRelationInput") // .declareAcquiredMethod("addRelationInput", "addRelationInput")
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod('render', function (options, options2) { .declareMethod('render', function (options) {
var state_dict = {
editable: options.editable,
query: options.query,
catalog_index: options.catalog_index,
allow_jump: options.allow_jump,
// required: field_json.required,
title: options.title,
key: options.key,
view: options.view,
url: options.url,
allow_creation: options.allow_creation,
portal_types: options.portal_types,
has_focus: false,
relation_index: options.relation_index,
value_relative_url: options.value_relative_url,
value_uid: options.value_uid,
value_text: options.value_text,
value_portal_type: options.value_portal_type
};
return this.changeState(state_dict);
})
.onStateChange(function (modification_dict) {
var gadget = this, var gadget = this,
field_json = options.field_json || {},
target_url,
queue = new RSVP.Queue(), queue = new RSVP.Queue(),
create_object, value_text = gadget.state.value_text,
unknown, // target_url,
relation_item_relative_url, SEARCHING_CLASS_STR = "ui-btn ui-corner-all ui-btn-icon-notext" +
uid, " ui-input-clear ui-icon-spinner ui-icon-spin",
value = "", JUMP_ON_CLASS_STR = "ui-btn ui-corner-all ui-btn-icon-notext " +
not_selected = true, "ui-icon-plane ui-shadow-inset ui-btn-inline",
index = options2.index || 0; JUMP_OFF_CLASS_STR = "ui-btn ui-corner-all ui-btn-icon-notext " +
gadget.props.field_json = field_json; "ui-icon-plane ui-shadow-inset ui-btn-inline ui-disabled",
JUMP_ADD_CLASS_STR = "ui-btn ui-corner-all ui-btn-icon-notext " +
if (!field_json.editable) { "ui-icon-plus ui-shadow-inset ui-btn-inline ui-disabled",
if (field_json.relation_item_relative_url) { JUMP_UNKNOWN_CLASS_STR = "ui-btn ui-corner-all ui-btn-icon-notext " +
return gadget.getUrlFor({ "ui-icon-warning ui-shadow-inset ui-btn-inline ui-disabled";
command: 'index',
options: { // Non editable
jio_key: field_json.relation_item_relative_url[index] if (!gadget.state.editable) {
} if ((gadget.state.value_relative_url) && (gadget.state.allow_jump)) {
}) return displayNonEditableLink(gadget);
.push(function (href) {
gadget.props.element.innerHTML = relation_link_template({
value: field_json.default[index] || "",
href: href
});
});
} }
return; return displayNonEditableText(gadget);
} }
gadget.props.index = index; if (modification_dict.hasOwnProperty('editable')) {
gadget.props.addRelationInput = options2.addRelationInput; // First display of the input
if (field_json.default.value) { queue.push(function () {
//load non saved value return displayEditableLink(gadget, JUMP_UNKNOWN_CLASS_STR);
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.query = QueryFactory.create(new URI(field_json.query).query(true).query);
gadget.props.create_object_type = create_object; return queue
if (!value && target_url && uid) { .push(function () {
//return from listbox var plane = gadget.element.querySelector("a"),
not_selected = false; ul = gadget.element.querySelector(".search_ul"),
queue input = gadget.element.querySelector("input");
.push(function () { ul.innerHTML = "";
plane.href = '';
if (input.value !== gadget.state.value_text) {
input.value = gadget.state.value_text;
}
// uid is known
// User selected a document from a listbox
if (gadget.state.value_uid) {
plane.className = SEARCHING_CLASS_STR;
return gadget.jio_allDocs({ return gadget.jio_allDocs({
"query": Query.objectToSearchText(new SimpleQuery({ "query": Query.objectToSearchText(new SimpleQuery({
key: "catalog.uid", key: "catalog.uid",
value: uid, value: gadget.state.value_uid,
limit: [0, 1] limit: [0, 1]
})), })),
"select_list": [field_json.catalog_index] "select_list": [gadget.state.catalog_index]
}); })
}) .push(function (result) {
.push(function (result) { return gadget.changeState({
value = result.data.rows[0].value[field_json.catalog_index]; value_text: result.data.rows[0]
}); .value[gadget.state.catalog_index],
} value_uid: null
if (target_url) { });
queue });
.push(function () { }
return gadget.getUrlFor({
command: 'index',
options: { // Expected portal type has been selected.
jio_key: target_url // User want to create a new document
} if (gadget.state.value_portal_type) {
}); plane.className = JUMP_ADD_CLASS_STR;
}); return;
} }
queue
.push(function (href) { // Relative URL is known. Display plane icon
var class_name, if (gadget.state.value_relative_url) {
jump_href = '#'; if (gadget.state.allow_jump) {
if (create_object) { return gadget.getUrlFor({
class_name = jump_add; command: 'index',
} else { options: {
if ((field_json.error_text || unknown) && not_selected) { jio_key: gadget.state.value_relative_url
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; .push(function (url) {
} plane.href = url;
plane.className = JUMP_ON_CLASS_STR;
});
}
if (modification_dict.hasOwnProperty('value_text')) {
plane.className = JUMP_UNKNOWN_CLASS_STR;
} else {
plane.className = JUMP_OFF_CLASS_STR;
} }
return;
} }
return gadget.translateHtml(relation_input_template({
href: jump_href, // No text, user want to delete the content
create_object: create_object, if (!gadget.state.value_text) {
readonly: field_json.editable ? "" : "ui-state-readonly", plane.className = JUMP_OFF_CLASS_STR;
input_readonly: field_json.editable ? "" : 'readonly="readonly"', return;
required: field_json.required ? "required" : "", }
value: value,
title: field_json.title, // User entered text, but didn't select
name: field_json.key, // from the list
class_name: class_name if (!gadget.state.has_focus) {
})); plane.className = JUMP_UNKNOWN_CLASS_STR;
}) return;
.push(function (html) { }
gadget.props.element.innerHTML = html;
gadget.props.input = // User typed some text.
gadget.props.element.querySelector("input"); // Propose some documents in a list
gadget.props.new_tag_div = gadget.props.element.querySelector(".new_tag"); plane.className = SEARCHING_CLASS_STR;
gadget.props.spinner = gadget.props.element.querySelector("a");
gadget.props.plane = gadget.props.element.querySelector("a"); return new RSVP.Queue()
gadget.props.input_deferred.resolve(); .push(function () {
// Wait a bit before launching the catalog query
// as user may still type new characters
return RSVP.delay(200);
})
.push(function () {
return gadget.jio_allDocs({
query: Query.objectToSearchText(new ComplexQuery({
operator: "AND",
query_list: [
QueryFactory.create(
new URI(gadget.state.query).query(true).query
),
new SimpleQuery({
key: gadget.state.catalog_index,
value: value_text
})
]
})),
limit: [0, 10],
select_list: [gadget.state.catalog_index]
});
})
.push(function (result) {
var list = [],
i,
type;
if (gadget.state.allow_creation) {
type = gadget.state.portal_types;
} else {
type = [];
}
for (i = 0; i < result.data.rows.length; i += 1) {
list.push({
id: result.data.rows[i].id,
value: result.data.rows[i].value[gadget.state.catalog_index]
});
}
plane.className = JUMP_UNKNOWN_CLASS_STR;
ul.innerHTML = relation_listview_template({
list: list,
type: type,
value: value_text
});
});
}); });
return queue;
}) })
.declareMethod('getContent', function (options, options2) {
var element = this.props.element.querySelector('input'), .declareMethod('getContent', function () {
result = {}, var gadget = this,
tmp = {}, result = {};
field_json = this.props.field_json;
if (!field_json.editable) { if (gadget.state.editable) {
return {}; result = {
} value_relative_url: gadget.state.value_relative_url,
if (options.format === "erp5") { value_text: gadget.state.value_text,
if (this.props.plane.className === jump_add) { value_portal_type: gadget.state.value_portal_type
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; return result;
}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared services // declared services
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareService(function () { .onEvent('blur', function () {
var gadget = this, var gadget = this,
props = gadget.props, ul,
input, new_state = {
search_query, has_focus: false
simple_query, };
field_json = props.field_json,
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 = jump_off;
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 = jump_off;
html = relation_listview_template({
list: list,
type: type,
value: my_value
});
ul.innerHTML = html;
});
}
function setSelectedElement(event) { if (!gadget.state.editable) {
var element = event.target, return;
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;
} }
ul = gadget.element.querySelector(".search_ul");
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return gadget.props.input_deferred.promise; return RSVP.any([
})
.push(function () {
input = gadget.props.element.querySelector('input');
ul = gadget.props.element.querySelector(".search_ul");
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 () { new RSVP.Queue()
var gadget = this; .push(function () {
return RSVP.delay(200);
})
.push(function () {
return gadget.changeState(new_state);
}),
function notifyInvalid(evt) { new RSVP.Queue()
return gadget.notifyInvalid(evt.target.validationMessage); .push(function () {
} return promiseEventListener(ul, "click", true);
return new RSVP.Queue() })
.push(function () { .push(function (event) {
return gadget.props.input_deferred.promise; // Check which 'li' element was clicked
var li = event.target,
data_relative_url = li.getAttribute("data-relative-url"),
data_portal_type = li.getAttribute("data-create-object"),
data_explore = li.getAttribute("data-explore");
// User want to create a new document
if (data_portal_type) {
new_state.value_portal_type = data_portal_type;
return gadget.changeState(new_state);
}
// User selected an existing document
if (data_relative_url) {
new_state.value_text = li.textContent;
new_state.value_relative_url = data_relative_url;
return gadget.changeState(new_state);
}
// Go to the search listbox
if (data_explore) {
return gadget.getFormContent({
format: "json"
})
.push(function (content) {
var input = gadget.element.querySelector('input');
return gadget.redirect({
command: 'index',
options: {
page: "relation_search",
url: gadget.state.url,
extended_search: Query.objectToSearchText(
new SimpleQuery({
key: gadget.state.catalog_index,
value: input.value
})
),
view: gadget.state.view,
back_field: gadget.state.key,
relation_index: gadget.state.relation_index
},
form_content: content
});
});
}
// No idea what has been clicked...
return gadget.changeState({
has_focus: false
});
})
]);
}) })
.push(function () { .push(function () {
// Listen to input change return gadget.notifyChange();
return loopEventListener(
gadget.props.element.querySelector('input'),
'invalid',
false,
notifyInvalid
);
}); });
}, true, false)
.declareMethod('checkValidity', function () {
return true;
}) })
.declareService(function () { // XXX Use html5 input
//////////////////////////////////// .onEvent('invalid', function (evt) {
// Check field validity when the value changes // invalid event does not bubble
//////////////////////////////////// return this.notifyInvalid(evt.target.validationMessage);
var gadget = this; }, true, false)
.onEvent('change', function () {
return RSVP.all([
this.checkValidity(),
this.notifyChange()
]);
}, false, false)
function notifyChange() { .onEvent('input', function (event) {
return gadget.notifyChange(); if (!this.state.editable) {
return;
} }
return new RSVP.Queue()
.push(function () {
return gadget.props.input_deferred.promise;
})
.push(function () {
return loopEventListener(
gadget.props.element.querySelector('input'),
'change',
false,
notifyChange
);
});
});
}(window, rJS, RSVP, URI, loopEventListener, promiseEventListener, return this.changeState({
value_text: event.target.value,
value_relative_url: null,
value_uid: null,
value_portal_type: null,
has_focus: true
});
}, true, false);
}(window, rJS, RSVP, URI, promiseEventListener,
SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars)); SimpleQuery, ComplexQuery, Query, QueryFactory, Handlebars));
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>953.41070.65129.47718</string> </value> <value> <string>954.57692.7289.25070</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1472800801.64</float> <float>1477583820.22</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint indent: 2, maxerr: 3, nomen: true */ /*jslint indent: 2, maxerr: 3, nomen: true, maxlen: 80 */
/*global window, rJS */ /*global window, rJS */
(function (window, rJS) { (function (window, rJS) {
"use strict"; "use strict";
rJS(window) rJS(window)
.allowPublicAcquisition("addRelationInput", function () {
return;
})
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var gadget = this,
field_json = options.field_json || {};
return this.getDeclaredGadget("relation_input") return this.getDeclaredGadget("relation_input")
.push(function (gadget) { .push(function (gadget) {
return gadget.render(options, {index: 0}); var render_options = {
editable: field_json.editable,
query: field_json.query,
catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump,
// required: field_json.required,
title: field_json.title,
key: field_json.key,
view: field_json.view,
url: field_json.url,
allow_creation: field_json.allow_creation,
portal_types: field_json.portal_types,
value_relative_url: field_json.relation_item_relative_url[0],
relation_index: 0
};
if (field_json.default.hasOwnProperty('value_text_list')) {
//load non saved value
render_options.value_relative_url =
field_json.default.value_relative_url_list[0];
render_options.value_uid =
field_json.default.value_uid_list[0];
render_options.value_text =
field_json.default.value_text_list[0];
render_options.value_portal_type =
field_json.default.value_portal_type_list[0];
} else {
render_options.value_text = field_json.default[0] || "";
}
return gadget.render(render_options);
})
.push(function () {
return gadget.changeState({
key: options.field_json.key,
relation_field_id: options.field_json.relation_field_id
});
}); });
}) })
.declareMethod('getContent', function (options) { .declareMethod('getContent', function (options) {
var gadget = this;
return this.getDeclaredGadget("relation_input") return this.getDeclaredGadget("relation_input")
.push(function (gadget) { .push(function (input_gadget) {
return gadget.getContent(options); return input_gadget.getContent();
})
.push(function (input_result) {
var result = {};
if (!input_result.hasOwnProperty('value_text')) {
return result;
}
if (options.format === "erp5") {
if (input_result.value_portal_type) {
result[gadget.state.relation_field_id] =
"_newContent_" + input_result.value_portal_type;
}
result[gadget.state.key] = input_result.value_text;
} else {
result[gadget.state.key] = {
value_text_list: [input_result.value_text],
value_relative_url_list: [input_result.value_relative_url],
value_portal_type_list: [input_result.value_portal_type],
value_uid_list: [undefined]
};
}
return result;
}); });
}); });
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>954.45675.44850.53452</string> </value> <value> <string>954.57675.64427.52462</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1477037965.54</float> <float>1477582815.99</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -446,7 +446,7 @@ ...@@ -446,7 +446,7 @@
function execHistoryPreviousCommand(gadget, previous_options, load_options) { function execHistoryPreviousCommand(gadget, previous_options, load_options) {
var history = previous_options.history, var history = previous_options.history,
jio_key = previous_options.jio_key, jio_key = previous_options.jio_key,
target_index = previous_options.target_index, relation_index = previous_options.relation_index,
field = previous_options.back_field, field = previous_options.back_field,
queue = new RSVP.Queue(), queue = new RSVP.Queue(),
previous_id; previous_id;
...@@ -473,9 +473,9 @@ ...@@ -473,9 +473,9 @@
if (results) { if (results) {
results = JSON.parse(results.target.result); results = JSON.parse(results.target.result);
if (load_options.uid) { if (load_options.uid) {
results[field].value[target_index] = ""; results[field].value_text_list[relation_index] = "";
results[field].relation_item_relative_url[target_index] = load_options.jio_key; results[field].value_relative_url_list[relation_index] = load_options.jio_key;
results[field].uid = load_options.uid; results[field].value_uid_list[relation_index] = load_options.uid;
} }
gadget.props.form_content = results; gadget.props.form_content = results;
} }
...@@ -491,8 +491,8 @@ ...@@ -491,8 +491,8 @@
return gadget.props.jio_gadget.get(history.options_id); return gadget.props.jio_gadget.get(history.options_id);
}) })
.push(function (result) { .push(function (result) {
var result_list = [result, previous_id]; var result_list = [result, previous_id],
var options = result_list[0].data, options = result_list[0].data,
next_jio_key = options.jio_key; next_jio_key = options.jio_key;
delete options.jio_key; delete options.jio_key;
return addNavigationHistoryAndDisplay(gadget, next_jio_key, options); return addNavigationHistoryAndDisplay(gadget, next_jio_key, options);
......
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>954.47260.43395.7014</string> </value> <value> <string>954.57620.63396.46779</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -250,7 +250,7 @@ ...@@ -250,7 +250,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1476957907.92</float> <float>1477580291.06</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </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