Add the formsaver module tied into nice UI for data saving (#52)

This commit is contained in:
2018-04-12 17:00:02 +10:00
parent 08bb577e37
commit 1dd2e4f316
3 changed files with 402 additions and 4 deletions

View File

@ -0,0 +1,269 @@
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var FormSaverSerialisers = {
"input:submit": function inputSubmit() {
return null;
},
"input:button": function inputButton() {
return null;
},
"input:image": function inputImage() {
return null;
},
"input:reset": function inputReset() {
return null;
},
"input:file": function inputFile() {
return null;
},
"input:radio": function inputRadio(group) {
return group.filter(function (input) {
return input.checked;
}).map(function (input) {
return input.value;
});
},
"input:checkbox": "input:radio",
"select": function select(group) {
return group.length == 1 ? Array.from(group[0].selectedOptions).map(function (elem) {
return elem.value;
}) : new Error('More than one select wth the same name');
},
"textarea": function textarea(group) {
return group.length == 1 ? group[0].value : new Error('More than one textarea with the same name');
},
"*": function _(group) {
return group.length == 1 ? group[0].value : new Error('More than one input with the same name');
}
};
var FormSaver = function () {
function FormSaver(_ref) {
var formId = _ref.formId,
except = _ref.except;
_classCallCheck(this, FormSaver);
this.formId = formId;
this.skipList = except || [];
}
_createClass(FormSaver, [{
key: "getExtendedTagName",
value: function getExtendedTagName(element) {
var tag = element.tagName.toLowerCase();
if (tag == 'input') {
return 'input:' + element.type;
} else {
return tag;
}
}
}, {
key: "deserialise",
value: function deserialise(data) {
var form = document.getElementById(this.formId);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = data[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var field = _step.value;
var element = form.elements[field.name];
// Skip some fields
if (this.skipList.includes(field.name)) {
continue;
}
// Deal with the case where we have a single tag first,
// ie. input type=text, selects, textareas
if (element.tagName) {
var tagName = this.getExtendedTagName(element);
if (tagName == 'select') {
// Go over all the <option>s and select the right ones
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = element.options[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var option = _step2.value;
option.selected = field.value.includes(option.value);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
} else {
element.value = field.value;
}
} else {
// We've got a list. This means we're radio or checkbox.
// Go over all the elements and select the right ones
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = element[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var input = _step3.value;
input.checked = field.value.includes(input.value);
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: "serialise",
value: function serialise() {
var output = [];
var errors = [];
var form = document.getElementById(this.formId);
var allControls = Array.from(form.elements);
// All inputs
var controlsByName = {};
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = allControls[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var control = _step4.value;
// Skip controls without names
if (control.name) {
// Make sure this entry exists
controlsByName[control.name] = controlsByName[control.name] || [];
controlsByName[control.name].push(control);
}
}
// Iterate over all the name groups
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = Object.keys(controlsByName)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var name = _step5.value;
// Skip some fields
if (this.skipList.includes(name)) {
continue;
}
// Get the current group
var group = controlsByName[name];
// Get a type like `input:file` or `textarea`
var type = this.getExtendedTagName(group[0]);
var fn = FormSaverSerialisers[type] || FormSaverSerialisers["*"];
if (typeof fn == "string") {
fn = FormSaverSerialisers[fn];
}
var value = fn(group);
if (value === null) {
// The less said the better
} else if ((typeof value === "undefined" ? "undefined" : _typeof(value)) == 'object' && value.name == 'Error') {
errors.push({ name: name, error: value });
} else {
output.push({ name: name, value: value });
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
return {
errors: errors,
form: output
};
}
}]);
return FormSaver;
}();

File diff suppressed because one or more lines are too long