Commit 1cca3113 authored by Boris Kocherov's avatar Boris Kocherov

support arbitrary data in object.additionalProperties and array.items

parent d4276e1b
...@@ -122,18 +122,17 @@ ...@@ -122,18 +122,17 @@
} }
function addSubForm(options) { function addSubForm(options) {
var element = options.element, var input_element = options.element,
g = options.gadget, g = options.gadget,
property_name, property_name,
parent_path = options.path || element.name, parent_path,
scope, scope;
input_element;
scope = parent_path + Math.random().toString(36).substr(2, 9); scope = Math.random().toString(36).substr(2, 9);
if (options.parent_type !== "array") { if (options.parent_type !== "array") {
parent_path = options.path;
property_name = options.property_name; property_name = options.property_name;
if (!property_name) { if (!property_name) {
input_element = element.parentNode.querySelector("input[type='text']");
property_name = input_element.value; property_name = input_element.value;
} }
if (!property_name) { if (!property_name) {
...@@ -153,11 +152,11 @@ ...@@ -153,11 +152,11 @@
return g.declareGadget('gadget_json_generated_form.html', {scope: scope}) return g.declareGadget('gadget_json_generated_form.html', {scope: scope})
.push(function (form_gadget) { .push(function (form_gadget) {
form_gadget.element.setAttribute("data-json-parent", parent_path);
form_gadget.element.setAttribute("data-gadget-parent-scope", form_gadget.element.setAttribute("data-gadget-parent-scope",
g.element.getAttribute("data-gadget-scope")); g.element.getAttribute("data-gadget-scope"));
if (options.parent_type !== "array") { if (options.parent_type !== "array") {
g.props.objects[parent_path][property_name] = scope; g.props.objects[parent_path][property_name] = scope;
form_gadget.element.setAttribute("data-json-parent", parent_path);
form_gadget.element.setAttribute("data-json-property-name", property_name); form_gadget.element.setAttribute("data-json-property-name", property_name);
} }
return form_gadget.renderForm({ return form_gadget.renderForm({
...@@ -170,6 +169,68 @@ ...@@ -170,6 +169,68 @@
}); });
} }
function render_select_type(gadget, title, type_arr, event) {
var scope = Math.random().toString(36).substr(2, 9);
if (!type_arr || type_arr === true) {
return gadget.declareGadget("gadget_html5_select.html", {scope: scope})
.push(function (g) {
var i,
item_list = [[title, title]],
render_options;
if (!type_arr || type_arr === true) {
type_arr = [
"string",
"number",
"boolean",
"array",
"object",
"null"
];
}
for (i = 0; i < type_arr.length; i += 1) {
item_list.push([type_arr[i], type_arr[i]]);
}
render_options = {
name: scope,
editable: true,
hidden: item_list.length <= 1,
value: item_list[0][1],
item_list: item_list
};
gadget.props.add_custom_data[scope] = {
element: g.element,
event: function () {
return g.getContent()
.push(function (value) {
return event(value[scope]);
})
.push(function () {
return g.render(render_options);
});
}
};
return g.render(render_options)
//not need if gadget_html5_select.render return element
.push(function () {
return g.element;
});
});
}
return RSVP.Queue()
.push(function () {
var input = document.createElement("button");
input.setAttribute("class",
"ui-shadow-inset ui-btn ui-btn-inline ui-corner-all" +
" ui-btn-icon-notext ui-icon-btn ui-icon-plus ui-input-btn");
input.type = "button";
gadget.props.add_buttons.push({
element: input,
event: event.bind(gadget, undefined)
});
return input;
});
}
function render_array(gadget, json_field, default_array, root, path, schema_path) { function render_array(gadget, json_field, default_array, root, path, schema_path) {
var queue = RSVP.Queue(), var queue = RSVP.Queue(),
div, div,
...@@ -191,35 +252,25 @@ ...@@ -191,35 +252,25 @@
} }
} }
if (maxItems === undefined || default_array.length < maxItems) { item_schema = json_field.items;
item_schema = json_field.items; queue
.push(render_select_type.bind(gadget, gadget, "add item to array", item_schema, function (value) {
input = document.createElement("button"); return addSubForm({
input.setAttribute("class", gadget: gadget,
"ui-shadow-inset ui-btn ui-btn-inline ui-corner-all" + parent_type: 'array',
" ui-btn-icon-notext ui-icon-btn ui-icon-plus ui-input-btn"); schema_path: schema_path + '/items',
input.type = "button"; schema_part: (value && {type: value}) || item_schema
input.name = path; })
gadget.props.add_buttons.push({ .push(element_append);
element: input, }))
event: function () { .push(function (element) {
return addSubForm({ input = element;
gadget: gadget, // XXX update on every add/delete item
parent_type: 'array', input.hidden = maxItems !== undefined && default_array.length >= maxItems;
element: input, div_input.appendChild(input);
schema_path: schema_path + '/items', div.appendChild(div_input);
schema_part: item_schema root.appendChild(div);
})
.push(element_append);
}
}); });
} else {
input = document.createElement("div");
input.setAttribute("class", "input");
}
div_input.appendChild(input);
div.appendChild(div_input);
if (default_array) { if (default_array) {
for (i = 0; i < default_array.length; i = i + 1) { for (i = 0; i < default_array.length; i = i + 1) {
...@@ -228,8 +279,6 @@ ...@@ -228,8 +279,6 @@
addSubForm.bind(gadget, { addSubForm.bind(gadget, {
gadget: gadget, gadget: gadget,
parent_type: 'array', parent_type: 'array',
path: path,
element: input,
schema_path: schema_path + '/items', schema_path: schema_path + '/items',
schema_part: item_schema, schema_part: item_schema,
default_dict: default_array[i] default_dict: default_array[i]
...@@ -238,7 +287,6 @@ ...@@ -238,7 +287,6 @@
.push(element_append); .push(element_append);
} }
} }
root.appendChild(div);
// XXX add failback rendering if default_array not array // XXX add failback rendering if default_array not array
// input = render_textarea(json_field, default_value, "array"); // input = render_textarea(json_field, default_value, "array");
return queue; return queue;
...@@ -297,7 +345,8 @@ ...@@ -297,7 +345,8 @@
span_error, span_error,
input, input,
first_path, first_path,
queue = RSVP.Queue(); queue = RSVP.Queue(),
type;
if (path && key) { if (path && key) {
first_path = path + encodeJsonPointer(key); first_path = path + encodeJsonPointer(key);
...@@ -323,18 +372,19 @@ ...@@ -323,18 +372,19 @@
}); });
} }
if (json_field.type === undefined && default_value) { type = json_field.type;
json_field.type = getDocumentType(default_value); if (type === undefined && default_value) {
type = getDocumentType(default_value);
} }
// XXX bad peace of code // XXX bad peace of code
// we can not change schema // i do not sure that type can be computed so
// but our schema in slapos bad // but our schema in slapos bad
if (!json_field.type) { if (!type) {
if (json_field.properties && if (json_field.properties &&
json_field.required && json_field.required &&
json_field.required.length > 0) { json_field.required.length > 0) {
json_field.type = "object"; type = "object";
} }
} }
...@@ -359,7 +409,7 @@ ...@@ -359,7 +409,7 @@
input = render_selection(json_field, default_value); input = render_selection(json_field, default_value);
} }
if (json_field.type === "boolean") { if (type === "boolean") {
if (default_value === "true") { if (default_value === "true") {
default_value = true; default_value = true;
} }
...@@ -372,7 +422,7 @@ ...@@ -372,7 +422,7 @@
}, default_value); }, default_value);
} }
if (!input && ["string", "integer", "number"].indexOf(json_field.type) >= 0) { if (!input && ["string", "integer", "number"].indexOf(type) >= 0) {
if (json_field.contentMediaType === "text/plain") { if (json_field.contentMediaType === "text/plain") {
input = render_textarea(json_field, default_value, "string"); input = render_textarea(json_field, default_value, "string");
} else { } else {
...@@ -381,7 +431,7 @@ ...@@ -381,7 +431,7 @@
input.value = default_value; input.value = default_value;
} }
if (json_field.type === "integer") { if (type === "integer") {
input.type = "number"; input.type = "number";
} else { } else {
input.type = "text"; input.type = "text";
...@@ -389,7 +439,7 @@ ...@@ -389,7 +439,7 @@
} }
} }
if (json_field.type === "array") { if (type === "array") {
queue = render_array( queue = render_array(
gadget, gadget,
json_field, json_field,
...@@ -400,10 +450,10 @@ ...@@ -400,10 +450,10 @@
); );
div.setAttribute("data-json-path", first_path + '/'); div.setAttribute("data-json-path", first_path + '/');
gadget.props.arrays[first_path + '/'] = div; gadget.props.arrays[first_path + '/'] = div;
div.setAttribute("data-json-type", json_field.type); div.setAttribute("data-json-type", type);
} }
if (json_field.type === "object") { if (type === "object") {
queue queue
.push(function () { .push(function () {
return render_object( return render_object(
...@@ -561,27 +611,22 @@ ...@@ -561,27 +611,22 @@
input.type = "text"; input.type = "text";
div_input.appendChild(input); div_input.appendChild(input);
input = document.createElement("button"); queue
input.setAttribute("class", .push(render_select_type.bind(g, g, "add custom property", schema, function (value) {
"ui-shadow-inset ui-btn ui-btn-inline ui-corner-all" +
" ui-btn-icon-notext ui-icon-btn ui-icon-plus ui-input-btn");
input.type = "button";
input.name = path;
g.props.add_buttons.push({
element: input,
event: function () {
return addSubForm({ return addSubForm({
gadget: g, gadget: g,
element: input, element: input,
path: path,
schema_path: schema_path + '/additionalProperties', schema_path: schema_path + '/additionalProperties',
schema_part: schema schema_part: (value && {type: value}) || schema
}) })
.push(element_append); .push(element_append);
} }))
}); .push(function (input) {
div_input.appendChild(input); // XXX update on every add/delete item
div.appendChild(div_input); div_input.appendChild(input);
div.appendChild(div_input);
});
for (property_name in default_dict) { for (property_name in default_dict) {
if (default_dict.hasOwnProperty(property_name) && !used_properties.hasOwnProperty(property_name)) { if (default_dict.hasOwnProperty(property_name) && !used_properties.hasOwnProperty(property_name)) {
...@@ -592,7 +637,6 @@ ...@@ -592,7 +637,6 @@
gadget: g, gadget: g,
property_name: property_name, property_name: property_name,
path: path, path: path,
element: input,
schema_path: schema_path + '/additionalProperties', schema_path: schema_path + '/additionalProperties',
schema_part: schema, schema_part: schema,
default_dict: default_dict[property_name] default_dict: default_dict[property_name]
...@@ -660,7 +704,7 @@ ...@@ -660,7 +704,7 @@
} else { } else {
additionalProperties = json_field.additionalProperties; additionalProperties = json_field.additionalProperties;
} }
if (getDocumentType(additionalProperties) === "object") { if (additionalProperties !== false) {
addAdditional(additionalProperties); addAdditional(additionalProperties);
} }
...@@ -751,8 +795,7 @@ ...@@ -751,8 +795,7 @@
for (path in options.arrays) { for (path in options.arrays) {
if (options.arrays.hasOwnProperty(path)) { if (options.arrays.hasOwnProperty(path)) {
array = options.arrays[path] array = options.arrays[path]
.querySelectorAll("div[data-json-parent='" + path + "']" + .querySelectorAll("div[data-gadget-parent-scope='" + g.element.getAttribute("data-gadget-scope") + "']");
"[data-gadget-parent-scope='" + g.element.getAttribute("data-gadget-scope") + "']");
len = array.length; len = array.length;
for (i = 0; i < len; i = i + 1) { for (i = 0; i < len; i = i + 1) {
getContentAndPushArray( getContentAndPushArray(
...@@ -959,11 +1002,12 @@ ...@@ -959,11 +1002,12 @@
}) })
.allowPublicAcquisition("notifyChange", function (arr, sub_scope) { .allowPublicAcquisition("notifyChange", function (arr, sub_scope) {
var g = this, var g = this,
opt = arr[0]; opt = arr[0],
if (opt.type === "change") { event_object;
return g.props event_object = g.props.add_property_selections[sub_scope];
.add_property_selections[sub_scope] event_object = event_object || g.props.add_custom_data[sub_scope];
.event(); if (opt.type === "change" && event_object) {
return event_object.event();
} }
}) })
.declareMethod('renderForm', function (options) { .declareMethod('renderForm', function (options) {
...@@ -974,6 +1018,7 @@ ...@@ -974,6 +1018,7 @@
root; root;
g.props.inputs = []; g.props.inputs = [];
g.props.add_buttons = []; g.props.add_buttons = [];
g.props.add_custom_data = {};
g.props.add_property_selections = {}; g.props.add_property_selections = {};
g.props.arrays = {}; g.props.arrays = {};
g.props.objects = {}; g.props.objects = {};
......
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