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