300 lines
8.0 KiB
JavaScript
300 lines
8.0 KiB
JavaScript
/*
|
|
* Confection App
|
|
*/
|
|
|
|
function loadFields(callback) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', '/fields.json', true);
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4) {
|
|
if (xhr.status === 200) {
|
|
var fields = JSON.parse(xhr.responseText);
|
|
callback(fields);
|
|
}
|
|
}
|
|
};
|
|
xhr.send(null);
|
|
}
|
|
|
|
function saveFields(payload, callback) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', '/save', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
|
|
xhr.onreadystatechange = function() {
|
|
if (xhr.readyState === 4) {
|
|
if (xhr.status === 200) {
|
|
var response = JSON.parse(xhr.responseText);
|
|
callback(response);
|
|
}
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify(payload));
|
|
}
|
|
|
|
function drawForm(fields) {
|
|
var container = document.getElementById('fields'),
|
|
fieldsets = {};
|
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
var field = fields[i];
|
|
|
|
if (field.value !== null) {
|
|
var fieldNode = makeFieldNode(field),
|
|
fieldSetName = field.path.match('(.*\/).*')[1];
|
|
|
|
if (!fieldsets[fieldSetName]) {
|
|
fieldsets[fieldSetName] = [];
|
|
}
|
|
fieldsets[fieldSetName].push(fieldNode);
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
var field = fields[i],
|
|
node;
|
|
|
|
if (field.value === null) {
|
|
node = makeFieldSetNode(field.title, fieldsets[field.path + '/']);
|
|
} else if (!field.path.match(/^\/[^\/]+\//)) {
|
|
node = makeFieldNode(field);
|
|
}
|
|
|
|
container.appendChild(node);
|
|
}
|
|
|
|
}
|
|
|
|
function makeFieldNode(field) {
|
|
var formGroup = makeDivNode('form-group'),
|
|
label = makeLabelNode(field.path, field.title),
|
|
input;
|
|
|
|
if (field.options !== null) {
|
|
input = makeSelectNode(field.options, !field.is_required)
|
|
} else {
|
|
input = document.createElement('input');
|
|
}
|
|
input.setAttribute('id', field.path);
|
|
|
|
if (field.type !== 'bool') {
|
|
input.value = field.value;
|
|
input.setAttribute('class', 'form-control');
|
|
} else {
|
|
if (field.value) {
|
|
input.setAttribute('checked', 'checked');
|
|
}
|
|
}
|
|
|
|
if (field.is_readonly) {
|
|
input.setAttribute('readonly', 'readonly');
|
|
}
|
|
|
|
input.setAttribute('data-type', field.type);
|
|
if (field.is_ignored) {
|
|
input.setAttribute('type', 'hidden');
|
|
return input;
|
|
}
|
|
|
|
switch (field.type) {
|
|
case 'string':
|
|
input.setAttribute('type', 'text');
|
|
formGroup.appendChild(label);
|
|
formGroup.appendChild(input);
|
|
break;
|
|
case 'bool':
|
|
input.setAttribute('type', 'checkbox');
|
|
label.innerHTML = '';
|
|
label.appendChild(input);
|
|
label.appendChild(document.createTextNode(field.title));
|
|
formGroup.setAttribute('class', 'checkbox');
|
|
formGroup.appendChild(label);
|
|
break;
|
|
case 'int':
|
|
case 'int8':
|
|
case 'int16':
|
|
case 'int32':
|
|
case 'int64':
|
|
case 'uint':
|
|
case 'uint8':
|
|
case 'uint16':
|
|
case 'uint32':
|
|
case 'uint64':
|
|
case 'float32':
|
|
case 'float64':
|
|
input.setAttribute('type', 'number');
|
|
switch (field.type) {
|
|
case 'int8':
|
|
input.setAttribute('min', '-128');
|
|
input.setAttribute('max', '127');
|
|
break;
|
|
case 'int16':
|
|
input.setAttribute('min', '-32768');
|
|
input.setAttribute('max', '32767');
|
|
break;
|
|
case 'int32':
|
|
input.setAttribute('min', '-2147483648');
|
|
input.setAttribute('max', '2147483647');
|
|
break;
|
|
case 'int': // Assuming x86-64 architecture
|
|
case 'int64':
|
|
input.setAttribute('min', '-9223372036854775808');
|
|
input.setAttribute('max', '9223372036854775807');
|
|
break;
|
|
case 'uint8':
|
|
input.setAttribute('min', '0');
|
|
input.setAttribute('max', '255');
|
|
break;
|
|
case 'uint16':
|
|
input.setAttribute('min', '0');
|
|
input.setAttribute('max', '65535');
|
|
break;
|
|
case 'uint32':
|
|
input.setAttribute('min', '0');
|
|
input.setAttribute('max', '4294967295');
|
|
break;
|
|
case 'uint': // Assuming x86-64 architecture
|
|
case 'uint64':
|
|
input.setAttribute('min', '0');
|
|
input.setAttribute('max', '18446744073709551615');
|
|
break;
|
|
case 'float32':
|
|
case 'float64':
|
|
input.setAttribute('step', 'any');
|
|
break;
|
|
}
|
|
formGroup.appendChild(label);
|
|
formGroup.appendChild(input);
|
|
break;
|
|
default:
|
|
console.log('Invalid field type: '+ field.type, field)
|
|
}
|
|
|
|
return formGroup;
|
|
}
|
|
|
|
function makeFieldSetNode(title, fields) {
|
|
var fieldsetNode = document.createElement('fieldset'),
|
|
legendNode = document.createElement('legend');
|
|
|
|
legendNode.appendChild(document.createTextNode(title));
|
|
fieldsetNode.appendChild(legendNode);
|
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
fieldsetNode.appendChild(fields[i]);
|
|
}
|
|
|
|
return fieldsetNode;
|
|
}
|
|
|
|
function makeDivNode(classes) {
|
|
var div = document.createElement('div');
|
|
div.setAttribute('class', classes);
|
|
return div;
|
|
}
|
|
|
|
function makeLabelNode(forId, text) {
|
|
var label = document.createElement('label'),
|
|
contents = document.createTextNode(text);
|
|
label.setAttribute('for', forId);
|
|
label.appendChild(contents);
|
|
return label;
|
|
}
|
|
|
|
function makeSelectNode(options, hasEmptyOption) {
|
|
var select = document.createElement('select');
|
|
|
|
if (hasEmptyOption === true) {
|
|
var option = document.createElement('option');
|
|
|
|
option.setAttribute('value', '');
|
|
option.appendChild(document.createTextNode('Not selected'));
|
|
select.appendChild(option);
|
|
}
|
|
|
|
for (var i = 0; i < options.length; i++) {
|
|
var value = options[i],
|
|
option = document.createElement('option');
|
|
|
|
option.setAttribute('value', value);
|
|
option.appendChild(document.createTextNode(value));
|
|
select.appendChild(option);
|
|
}
|
|
|
|
return select;
|
|
}
|
|
|
|
loadFields(drawForm);
|
|
|
|
document.getElementById('config').addEventListener('submit', function(e){
|
|
e.preventDefault();
|
|
|
|
var elems = {},
|
|
inputs = document.getElementsByTagName('input'),
|
|
selects = document.getElementsByTagName('select');
|
|
|
|
for (var i = 0; i < selects.length; i++) {
|
|
var select = selects[i],
|
|
path = select.getAttribute('id'),
|
|
value = select.value;
|
|
elems[path] = value;
|
|
}
|
|
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
var input = inputs[i],
|
|
type = input.getAttribute('data-type'),
|
|
path = input.getAttribute('id'),
|
|
value = input.value;
|
|
|
|
switch (type) {
|
|
case 'string':
|
|
elems[path] = value;
|
|
break;
|
|
case 'bool':
|
|
elems[path] = input.checked;
|
|
break;
|
|
case 'int':
|
|
case 'int8':
|
|
case 'int16':
|
|
case 'int32':
|
|
case 'int64':
|
|
case 'uint':
|
|
case 'uint8':
|
|
case 'uint16':
|
|
case 'uint32':
|
|
case 'uint64':
|
|
elems[path] = parseInt(value, 10);
|
|
break;
|
|
case 'float32':
|
|
case 'float64':
|
|
elems[path] = parseFloat(value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
var payload = {};
|
|
for (path in elems) {
|
|
var value = elems[path],
|
|
tokens = path.slice(1).split('/'),
|
|
parents = tokens.slice(0, -1),
|
|
key = tokens.slice(-1)[0],
|
|
parent = payload;
|
|
|
|
for (var i = 0; i < parents.length; i++) {
|
|
var pkey = parents[i];
|
|
|
|
if (!parent[pkey]) {
|
|
parent[pkey] = {}
|
|
}
|
|
parent = parent[pkey];
|
|
}
|
|
|
|
parent[key] = value;
|
|
}
|
|
|
|
saveFields(payload, function(resp){
|
|
console.log(resp);
|
|
});
|
|
|
|
return false;
|
|
});
|