mirror of
https://github.com/Karaka-Management/jsOMS.git
synced 2026-01-12 10:18:40 +00:00
Implement CRUD for forms instead of tables
This commit is contained in:
parent
d3312d760f
commit
02cd497954
|
|
@ -34,9 +34,9 @@ export class Request {
|
|||
|
||||
this.requestHeader['Content-Type'] = this.setContentTypeBasedOnType(this.type);
|
||||
|
||||
this.result[0] = function()
|
||||
this.result[0] = function(xhr)
|
||||
{
|
||||
Logger.instance.info('Unhandled response');
|
||||
Logger.getInstance().info('Unhandled response from "' + xhr.responseURL + '" with response data "' + xhr.response + '"');
|
||||
};
|
||||
|
||||
/** global: XMLHttpRequest */
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export class Form {
|
|||
if (typeof id !== 'undefined' && typeof this.ignore[id] === 'undefined') {
|
||||
this.bindForm(id);
|
||||
} else {
|
||||
const forms = document.getElementsByTagName('form'),
|
||||
const forms = document.querySelectorAll('form, [data-tag=form]'),
|
||||
length = !forms ? 0 : forms.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
|
|
@ -119,13 +119,18 @@ export class Form {
|
|||
return;
|
||||
}
|
||||
|
||||
// don't overwrite bind
|
||||
if (this.forms.hasOwnProperty(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const self = this;
|
||||
this.forms[id] = new FormView(id);
|
||||
|
||||
this.unbind(id);
|
||||
|
||||
const submits = this.forms[id].getSubmit(),
|
||||
length = submits.length;
|
||||
const submits = this.forms[id].getSubmit()
|
||||
let length = submits.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
submits[i].addEventListener('click', function (event)
|
||||
|
|
@ -134,6 +139,28 @@ export class Form {
|
|||
self.submit(self.forms[id]);
|
||||
});
|
||||
}
|
||||
|
||||
const removable = this.forms[id].getRemove();
|
||||
length = removable === null ? 0 : removable.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
this.bindRemovable(removable[i], id);
|
||||
}
|
||||
|
||||
const addable = this.forms[id].getAdd();
|
||||
length = addable === null ? 0 : addable.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
this.bindAddInline(addable[i], id);
|
||||
}
|
||||
|
||||
if (document.getElementById(id).getAttribute('data-ui-form') !== null) {
|
||||
this.bindAddExternal(id);
|
||||
}
|
||||
|
||||
const update = this.forms[id].getUpdate();
|
||||
length = update === null ? 0 : update.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
this.bindUpdatable(update[i], id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -220,7 +247,11 @@ export class Form {
|
|||
{
|
||||
if (!form.isValid()) {
|
||||
this.app.notifyManager.send(
|
||||
new NotificationMessage(NotificationLevel.INFO, jsOMS.lang.Info, jsOMS.lang.invalid_form), NotificationType.APP_NOTIFICATION
|
||||
new NotificationMessage(
|
||||
NotificationLevel.INFO,
|
||||
jsOMS.lang.Info,
|
||||
jsOMS.lang.invalid_form
|
||||
), NotificationType.APP_NOTIFICATION
|
||||
);
|
||||
|
||||
Logger.instance.debug('Form "' + form.getId() + '" has invalid values.');
|
||||
|
|
@ -305,4 +336,259 @@ export class Form {
|
|||
{
|
||||
return this.forms.length;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the ui element
|
||||
*
|
||||
* @param {string} createForm Create form
|
||||
* @param {Object} id Form id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindAddExternal(id)
|
||||
{
|
||||
const createForm = document.getElementById(id).getAttribute('data-ui-form');
|
||||
// todo: maybe allow multiple add buttons!!!! In order to do that do createForm.getAttribute('data-ui-form') and add this attribute to the add button instead of the pseudo form
|
||||
|
||||
this.app.uiManager.getFormManager().get(createForm).injectSubmit(function () {
|
||||
const subMain = document.getElementById(id).querySelector(document.getElementById(id).getAttribute('data-ui-content'));
|
||||
const newEle = subMain.getElementsByTagName('template')[0].content.cloneNode(true);
|
||||
|
||||
// set internal value
|
||||
let fields = newEle.querySelectorAll('[data-tpl-value]');
|
||||
let fieldLength = fields.length;
|
||||
let uuid = '';
|
||||
let value = '';
|
||||
|
||||
for (let j = 0; j < fieldLength; ++j) {
|
||||
value = document.querySelectorAll(
|
||||
'#' + createForm + ' [data-tpl-value="' + fields[j].getAttribute('data-tpl-value') + '"], [data-form="' + createForm + '"][data-tpl-value="' + fields[j].getAttribute('data-tpl-value') + '"]')[0]
|
||||
.getAttribute('data-value');
|
||||
|
||||
// todo: we need to check what kind of tag the selector above returns in order to get the correct value. currently this only makes sense for input elements but for selection, checkboxes etc. this doesn't make sense there we need .innerHtml or [data-text=]
|
||||
|
||||
fields[j].setAttribute('data-value', value);
|
||||
|
||||
uuid += value;
|
||||
}
|
||||
|
||||
// don't allow duplicate
|
||||
if (subMain.querySelectorAll('[data-tpl-uuid="' + uuid + '"').length !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
newEle.firstElementChild.setAttribute('data-tpl-uuid', uuid);
|
||||
|
||||
// set readable text
|
||||
fields = newEle.querySelectorAll('[data-tpl-text]');
|
||||
fieldLength = fields.length;
|
||||
|
||||
for (let j = 0; j < fieldLength; ++j) {
|
||||
fields[j].appendChild(
|
||||
document.createTextNode(
|
||||
document.querySelectorAll('#' + createForm + ' [data-tpl-text="' + fields[j].getAttribute('data-tpl-text') + '"], [data-form="' + createForm + '"][data-tpl-text="' + fields[j].getAttribute('data-tpl-text') + '"]')[0].value
|
||||
)
|
||||
);
|
||||
|
||||
// todo: we need to check what kind of tag the selector above returns in order to get the correct value. currently this only makes sense for input elements but for selection, checkboxes etc. this doesn't make sense there we need .innerHtml or [data-text=]
|
||||
}
|
||||
|
||||
subMain.appendChild(newEle);
|
||||
// todo: consider to do ui action as success inject to the backend request... maybe optional because sometimes there will be no backend call?
|
||||
// todo: if a column has a form in the template the id of the form needs to be set unique somehow (e.g. remove button in form)
|
||||
|
||||
// todo: bind removable
|
||||
// todo: bind edit
|
||||
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the table row
|
||||
*
|
||||
* @param {string} createForm Create form
|
||||
* @param {Object} id Table id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindAddInline(createForm, id)
|
||||
{
|
||||
const self = this;
|
||||
|
||||
createForm.addEventListener('click', function () {
|
||||
const subMain = document.getElementById(id).querySelector(document.getElementById(id).getAttribute('data-ui-content'));
|
||||
const newEle = subMain.getElementsByTagName('template')[1].content.cloneNode(true);
|
||||
const eleId = 'f' + Math.random().toString(36).substring(7);
|
||||
// todo: check if random id doesn't already exist
|
||||
|
||||
newEle.firstElementChild.id = eleId;
|
||||
newEle.firstElementChild.getElementsByTagName('form')[0].id = eleId + '-form';
|
||||
|
||||
const fields = newEle.firstElementChild.querySelectorAll('[data-form="' + id + '"]');
|
||||
const length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', eleId + '-form');
|
||||
}
|
||||
|
||||
subMain.appendChild(newEle.firstElementChild);
|
||||
|
||||
self.app.uiManager.getFormManager().get(eleId + '-form').injectSubmit(function () {
|
||||
document.getElementById(id).getElementsByTagName('tbody')[0].removeChild(
|
||||
document.getElementById(eleId)
|
||||
);
|
||||
});
|
||||
|
||||
// todo: bind removable
|
||||
// todo: bind edit
|
||||
});
|
||||
|
||||
// todo: this is polluting the form manager because it should be emptied afterwards (form is deleted but not from form manager)
|
||||
// todo: consider to do ui action as success inject to the backend request... maybe optional because sometimes there will be no backend call?
|
||||
// todo: if a column has a form in the template the id of the form needs to be set unique somehow (e.g. remove button in form)
|
||||
};
|
||||
|
||||
bindUpdatable(update, id)
|
||||
{
|
||||
if (document.getElementById(id).getAttribute('data-ui-form') === null) {
|
||||
this.bindUpdatableInline(update, id);
|
||||
} else {
|
||||
this.bindUpdatableExternal(update, id);
|
||||
}
|
||||
};
|
||||
|
||||
bindUpdatableInline(update, id) {
|
||||
const self = this;
|
||||
|
||||
update.addEventListener('click', function () {
|
||||
const parent = this.closest(document.getElementById(id).getAttribute('data-ui-element'));
|
||||
const values = parent.querySelectorAll('[data-tpl-value]');
|
||||
const text = parent.querySelectorAll('[data-tpl-text]');
|
||||
const subMain = parent.parentNode;
|
||||
|
||||
parent.style = "display: none"; // todo: replace with class instead of inline style
|
||||
|
||||
const newEle = subMain.getElementsByTagName('template')[1].content.cloneNode(true);
|
||||
const eleId = 'f' + Math.random().toString(36).substring(7);
|
||||
// todo: don't use random id use actual row id for data which needs to be updated
|
||||
|
||||
// root element is form even if it has a different tag than <form> also <tr> can be a form!
|
||||
newEle.firstElementChild.id = eleId;
|
||||
|
||||
const fields = newEle.firstElementChild.querySelectorAll('[data-form="' + id + '"]');
|
||||
let length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', eleId);
|
||||
}
|
||||
|
||||
// insert row values data into form
|
||||
length = values.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
// todo: handle multiple matches
|
||||
newEle.firstElementChild.querySelectorAll('[data-tpl-value="' + values[i].getAttribute('data-tpl-value') + '"')[0].value = values[i].value;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// insert row text data into form
|
||||
length = text.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
// todo: handle multiple matches
|
||||
newEle.firstElementChild.querySelectorAll('[data-tpl-text="' + text[i].getAttribute('data-tpl-text') + '"')[0].value = text[i].innerText;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
subMain.insertBefore(newEle.firstElementChild, parent);
|
||||
|
||||
//self.bindCreateForm(eleId, id); // todo: why this bind???
|
||||
self.app.uiManager.getFormManager().get(eleId).injectSubmit(function () {
|
||||
// todo: simplify this?
|
||||
self.closest(self.getAttribute('data-ui-element')).parentNode.removeChild(
|
||||
document.getElementById(eleId)
|
||||
);
|
||||
});
|
||||
|
||||
// todo: replace add button with save button and add cancel button
|
||||
// todo: on save button click insert data into hidden row and show hidden row again, delete form row
|
||||
});
|
||||
};
|
||||
|
||||
bindUpdatableExternal(update, id)
|
||||
{
|
||||
update.addEventListener('click', function () {
|
||||
const parent = this.closest(document.getElementById(id).getAttribute('data-ui-element'));
|
||||
const formId = document.getElementById(id).getAttribute('data-ui-form');
|
||||
const values = parent.querySelectorAll('[data-tpl-value]');
|
||||
const text = parent.querySelectorAll('[data-tpl-text]');
|
||||
|
||||
const fields = document.getElementById(formId).querySelectorAll('[data-form="' + id + '"]');
|
||||
let length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', eleId);
|
||||
}
|
||||
|
||||
// insert row values data into form
|
||||
length = values.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
// todo: handle multiple matches
|
||||
document.getElementById(formId).querySelectorAll('[data-tpl-value="' + values[i].getAttribute('data-tpl-value') + '"')[0].value = values[i].value;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// insert row text data into form
|
||||
length = text.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
// todo: handle multiple matches
|
||||
document.getElementById(formId).querySelectorAll('[data-tpl-text="' + text[i].getAttribute('data-tpl-text') + '"')[0].value = text[i].innerText;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// todo: replace add button with save button and add cancel button
|
||||
// todo: on save button click insert data into hidden row and show hidden row again, delete form row
|
||||
// todo: consider to highlight column during edit
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the closest row on click.
|
||||
*
|
||||
* @param {Element} remove Remove button
|
||||
* @param {Object} id Element id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindRemovable(remove, id)
|
||||
{
|
||||
remove.addEventListener('click', function () {
|
||||
const callback = function() {
|
||||
const parent = remove.closest(document.getElementById(id).getAttribute('data-ui-element'));
|
||||
parent.parentNode.removeChild(parent);
|
||||
};
|
||||
|
||||
const container = document.getElementById(id);
|
||||
|
||||
// container can be the table tr, form or just a div
|
||||
if (container !== null
|
||||
&& ((container.tagName.toLowerCase() !== 'form' && container.getAttribute('data-method') !== null)
|
||||
|| (container.tagName.toLowerCase() === 'form' && container.getAttribute('method') !== 'NONE'))
|
||||
) {
|
||||
const deleteRequest = new Request(
|
||||
container.tagName.toLowerCase() !== 'form' ? container.getAttribute('data-method') : container.getAttribute('method'),
|
||||
RequestMethod.DELETE
|
||||
);
|
||||
deleteRequest.setSuccess(callback);
|
||||
deleteRequest.send();
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
@ -20,6 +20,8 @@ export class Table {
|
|||
constructor(app)
|
||||
{
|
||||
this.app = app;
|
||||
|
||||
/** @var {Object <string, TableView>} */
|
||||
this.tables = {};
|
||||
this.ignore = {};
|
||||
};
|
||||
|
|
@ -108,27 +110,6 @@ export class Table {
|
|||
for (let i = 0; i < length; ++i) {
|
||||
this.bindFiltering(filters[i], id);
|
||||
}
|
||||
|
||||
const removable = this.tables[id].getRemovable();
|
||||
length = removable.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
this.bindRemovable(removable[i], id);
|
||||
}
|
||||
|
||||
const createForm = this.tables[id].getForm();
|
||||
const createButton = document.getElementById(id).getAttribute('data-table-add');
|
||||
|
||||
if (createButton !== null) {
|
||||
this.bindCreateInline(createButton, id);
|
||||
} else if (createForm !== null) {
|
||||
this.bindCreateForm(createForm, id);
|
||||
}
|
||||
|
||||
const update = this.tables[id].getUpdatable();
|
||||
length = update.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
this.bindUpdatable(update[i], id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -151,35 +132,12 @@ export class Table {
|
|||
button.addEventListener('click', function (event)
|
||||
{
|
||||
console.log(exports.serialize());
|
||||
// todo: either create download in javascript from this data or make roundtrip to server who then sends the data
|
||||
// todo: either create download in javascript from this data or make round trip to server who then sends the data
|
||||
// - think about allowing different export formats (json, csv, excel)
|
||||
// - maybe this should never be done from the ui, maybe a endpoint uri should be specified which then calls the api get function for this data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the closest row on click.
|
||||
*
|
||||
* @param {Element} remove Remove button
|
||||
* @param {Object} id Element id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindRemovable(remove, id)
|
||||
{
|
||||
if (remove.closest('form').getAttribute('method') !== 'NONE') {
|
||||
this.app.uiManager.getFormManager().get(remove.closest('form').id).setSuccess(function () {
|
||||
document.getElementById(id).deleteRow(remove.closest('tr').rowIndex);
|
||||
});
|
||||
} else {
|
||||
this.app.uiManager.getFormManager().get(remove.closest('form').id).setFinally(function () {
|
||||
document.getElementById(id).deleteRow(remove.closest('tr').rowIndex);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Swaps the row on click.
|
||||
*
|
||||
|
|
@ -309,8 +267,8 @@ export class Table {
|
|||
|
||||
const output = document.importNode(tpl.content, true);
|
||||
output.firstElementChild.setAttribute('style', 'position: absolute; top: ' + posY + 'px; left: ' + posX + 'px;')
|
||||
output.firstElementChild.setAttribute('data-table', this.closest('table').id);
|
||||
output.firstElementChild.setAttribute('data-table-column', this.closest('td').cellIndex);
|
||||
output.firstElementChild.setAttribute('data-ui', this.closest('table').id);
|
||||
output.firstElementChild.setAttribute('data-ui-column', this.closest('td').cellIndex);
|
||||
|
||||
// todo: set existing filtering option in ui here
|
||||
|
||||
|
|
@ -327,10 +285,10 @@ export class Table {
|
|||
filter.push(input[i].value);
|
||||
}
|
||||
|
||||
const table = document.getElementById(document.getElementById('table-filter').getAttribute('data-table'));
|
||||
const table = document.getElementById(document.getElementById('table-filter').getAttribute('data-ui'));
|
||||
|
||||
table.querySelectorAll('thead td')[
|
||||
document.getElementById('table-filter').getAttribute('data-table-column')
|
||||
document.getElementById('table-filter').getAttribute('data-ui-column')
|
||||
].setAttribute('data-filter', JSON.stringify(filter));
|
||||
|
||||
// todo: if not empty highlight filter button for user indication that filter is active
|
||||
|
|
@ -354,120 +312,6 @@ export class Table {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the table row
|
||||
*
|
||||
* @param {string} createForm Create form
|
||||
* @param {Object} id Table id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindCreateForm(createForm, id)
|
||||
{
|
||||
this.app.uiManager.getFormManager().get(createForm).injectSubmit(function () {
|
||||
const table = document.getElementById(id).getElementsByTagName('tbody')[0];
|
||||
const newRow = table.getElementsByTagName('template')[0].content.cloneNode(true);
|
||||
|
||||
// set internal value
|
||||
let fields = newRow.querySelectorAll('[data-tpl-value]');
|
||||
let fieldLength = fields.length;
|
||||
let uuid = '';
|
||||
let value = '';
|
||||
|
||||
for (let j = 0; j < fieldLength; ++j) {
|
||||
value = document.querySelectorAll(
|
||||
'#' + createForm + ' [data-tpl-value="' + fields[j].getAttribute('data-tpl-value') + '"], [data-form="' + createForm + '"][data-tpl-value="' + fields[j].getAttribute('data-tpl-value') + '"]')[0]
|
||||
.getAttribute('data-value');
|
||||
|
||||
// todo: we need to check what kind of tag the selector above returns in order to get the correct value. currently this only makes sense for input elements but for selection, checkboxes etc. this doesn't make sense there we need .innerHtml or [data-text=]
|
||||
|
||||
fields[j].setAttribute('data-value', value);
|
||||
|
||||
uuid += value;
|
||||
}
|
||||
|
||||
// don't allow duplicate
|
||||
if (table.querySelectorAll('[data-tpl-uuid="' + uuid + '"').length !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
newRow.firstElementChild.setAttribute('data-tpl-uuid', uuid);
|
||||
|
||||
// set readable text
|
||||
fields = newRow.querySelectorAll('[data-tpl-text]');
|
||||
fieldLength = fields.length;
|
||||
|
||||
for (let j = 0; j < fieldLength; ++j) {
|
||||
fields[j].appendChild(
|
||||
document.createTextNode(
|
||||
document.querySelectorAll('#' + createForm + ' [data-tpl-text="' + fields[j].getAttribute('data-tpl-text') + '"], [data-form="' + createForm + '"][data-tpl-text="' + fields[j].getAttribute('data-tpl-text') + '"]')[0].value
|
||||
)
|
||||
);
|
||||
|
||||
// todo: we need to check what kind of tag the selector above returns in order to get the correct value. currently this only makes sense for input elements but for selection, checkboxes etc. this doesn't make sense there we need .innerHtml or [data-text=]
|
||||
}
|
||||
|
||||
table.appendChild(newRow);
|
||||
// todo: consider to do ui action as success inject to the backend request... maybe optional because sometimes there will be no backend call?
|
||||
// todo: if a column has a form in the template the id of the form needs to be set unique somehow (e.g. remove button in form)
|
||||
|
||||
// todo: bind removable
|
||||
// todo: bind edit
|
||||
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the table row
|
||||
*
|
||||
* @param {string} createForm Create form
|
||||
* @param {Object} id Table id
|
||||
*
|
||||
* @return {void}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
bindCreateInline(createForm, id)
|
||||
{
|
||||
const self = this;
|
||||
|
||||
document.getElementById(createForm).addEventListener('click', function() {
|
||||
const table = document.getElementById(id).getElementsByTagName('tbody')[0];
|
||||
const newRow = table.getElementsByTagName('template')[1].content.cloneNode(true);
|
||||
const rowId = 'f' + Math.random().toString(36).substring(7);
|
||||
// todo: check if random id doesn't already exist
|
||||
|
||||
newRow.firstElementChild.id = rowId;
|
||||
newRow.firstElementChild.getElementsByTagName('form')[0].id = rowId + '-form';
|
||||
|
||||
const fields = newRow.firstElementChild.querySelectorAll('[data-form="' + self.tables[id].getForm() + '"]');
|
||||
const length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', rowId + '-form');
|
||||
}
|
||||
|
||||
table.appendChild(newRow.firstElementChild);
|
||||
|
||||
self.bindCreateForm(rowId + '-form', id);
|
||||
self.app.uiManager.getFormManager().get(rowId + '-form').injectSubmit(function () {
|
||||
document.getElementById(id).getElementsByTagName('tbody')[0].removeChild(
|
||||
document.getElementById(rowId)
|
||||
);
|
||||
});
|
||||
|
||||
// todo: bind removable
|
||||
// todo: bind edit
|
||||
});
|
||||
|
||||
// todo: this is polluting the form manager because it should be emptied afterwards (form is deleted but not from form manager)
|
||||
// todo: consider to do ui action as success inject to the backend request... maybe optional because sometimes there will be no backend call?
|
||||
// todo: if a column has a form in the template the id of the form needs to be set unique somehow (e.g. remove button in form)
|
||||
};
|
||||
|
||||
static getRemoteData (table)
|
||||
{
|
||||
const data = {
|
||||
|
|
@ -485,7 +329,7 @@ export class Table {
|
|||
request.setRequestHeader('Content-Type', 'application/json');
|
||||
request.setSuccess(function (xhr) {
|
||||
Table.emptyTable(table.getElementsByTagName('tbody')[0]);
|
||||
Table.addToTable(table.getElementsByTagName('tbody')[0], JSON.parse(xhr.response));
|
||||
Table.addToTable(table.getElementsByTagName('tbody')[0], JSON.parse(xhr.response)[0]);
|
||||
});
|
||||
|
||||
request.send();
|
||||
|
|
@ -537,89 +381,4 @@ export class Table {
|
|||
// todo: bind buttons if required (e.g. remove, edit button)
|
||||
}
|
||||
};
|
||||
|
||||
bindUpdatable (update, id)
|
||||
{
|
||||
const self = this;
|
||||
|
||||
update.addEventListener('click', function() {
|
||||
// handle external form
|
||||
// handle internal form
|
||||
const formId = document.getElementById(id).getAttribute('data-table-form');
|
||||
const values = this.closest('tr').querySelectorAll('[data-tpl-value]');
|
||||
const text = this.closest('tr').querySelectorAll('[data-tpl-text]');
|
||||
const table = document.getElementById(id).getElementsByTagName('tbody')[0];
|
||||
|
||||
if (document.getElementById(formId) === null) {
|
||||
this.closest('tr').style = "display: none"; // todo: replace with class instead of inline style
|
||||
|
||||
const newRow = table.getElementsByTagName('template')[1].content.cloneNode(true);
|
||||
const rowId = 'f' + Math.random().toString(36).substring(7);
|
||||
// todo: don't use random ide use actual row id for data which needs to be updated
|
||||
|
||||
newRow.firstElementChild.id = rowId;
|
||||
newRow.firstElementChild.getElementsByTagName('form')[0].id = rowId + '-form';
|
||||
|
||||
const fields = newRow.firstElementChild.querySelectorAll('[data-form="' + self.tables[id].getForm() + '"]');
|
||||
let length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', rowId + '-form');
|
||||
}
|
||||
|
||||
// insert row values data into form
|
||||
length = values.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
newRow.firstElementChild.querySelectorAll('[data-tpl-value="' + values[i].getAttribute('data-tpl-value') + '"')[0].value = values[i].value;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// insert row text data into form
|
||||
length = text.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
newRow.firstElementChild.querySelectorAll('[data-tpl-text="' + text[i].getAttribute('data-tpl-text') + '"')[0].value = text[i].innerText;
|
||||
console.log(text[i].innerText);
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
table.insertBefore(newRow.firstElementChild, this.closest('tr'));
|
||||
|
||||
self.bindCreateForm(rowId + '-form', id);
|
||||
self.app.uiManager.getFormManager().get(rowId + '-form').injectSubmit(function () {
|
||||
document.getElementById(id).getElementsByTagName('tbody')[0].removeChild(
|
||||
document.getElementById(rowId)
|
||||
);
|
||||
});
|
||||
|
||||
// todo: replace add button with save button and add cancel button
|
||||
// todo: on save button click insert data into hidden row and show hidden row again, delete form row
|
||||
} else {
|
||||
const fields = document.getElementById(formId).querySelectorAll('[data-form="' + self.tables[id].getForm() + '"]');
|
||||
let length = fields.length;
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
fields[i].setAttribute('data-form', rowId + '-form');
|
||||
}
|
||||
|
||||
// insert row values data into form
|
||||
length = values.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
document.getElementById(formId).querySelectorAll('[data-tpl-value="' + values[i].getAttribute('data-tpl-value') + '"')[0].value = values[i].value;
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// insert row text data into form
|
||||
length = text.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
document.getElementById(formId).querySelectorAll('[data-tpl-text="' + text[i].getAttribute('data-tpl-text') + '"')[0].value = text[i].innerText;
|
||||
console.log(text[i].innerText);
|
||||
// todo: handle different input types
|
||||
}
|
||||
|
||||
// todo: replace add button with save button and add cancel button
|
||||
// todo: on save button click insert data into hidden row and show hidden row again, delete form row
|
||||
// todo: consider to highlight column during edit
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Logger } from '../../../Log/Logger.js';
|
||||
|
||||
/**
|
||||
* Form manager class.
|
||||
*
|
||||
|
|
@ -71,12 +73,12 @@ export class VoiceManager {
|
|||
|
||||
this.recognition.onnomatch = function(event)
|
||||
{
|
||||
jsOMS.Log.Logger.instance.warning('Couldn\'t recognize speech');
|
||||
Logger.instance.warning('Couldn\'t recognize speech');
|
||||
};
|
||||
|
||||
this.recognition.onerror = function(event)
|
||||
{
|
||||
jsOMS.Log.Logger.instance.warning('Error during speech recognition: ' + event.error);
|
||||
Logger.instance.warning('Error during speech recognition: ' + event.error);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ import { Input } from '../UI/Component/Input.js';
|
|||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @todo expand this so any element can become a "form" e.g. table, div etc.
|
||||
* Simply add data-method, data-action
|
||||
* Expand the getData() and some other function to consider this
|
||||
*/
|
||||
export class FormView {
|
||||
/**
|
||||
|
|
@ -105,14 +109,62 @@ export class FormView {
|
|||
*/
|
||||
getSubmit ()
|
||||
{
|
||||
// todo: question, exclude save/remove button? maybe not because they also submit data right?
|
||||
return document.querySelectorAll(
|
||||
'#' + this.id + ' input[type=submit], '
|
||||
+ 'button[form=' + this.id + '][type=submit], '
|
||||
+ '#' + this.id + ' button[type=submit], '
|
||||
+ '.submit[data-form=' + this.id + '], '
|
||||
+ '#' + this.id + ' .submit'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get edit elements
|
||||
*
|
||||
* @return {Object}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
getUpdate() {
|
||||
return document.querySelectorAll(
|
||||
'button[form=' + this.id + '].update, '
|
||||
+ '.update[data-form=' + this.id + '], '
|
||||
+ '#' + this.id + ' .update'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get remove buttons
|
||||
*
|
||||
* @return {NodeListOf<any>}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
getRemove() {
|
||||
return document.querySelectorAll(
|
||||
'button[form=' + this.id + '].remove, '
|
||||
+ '.remove[data-form=' + this.id + '], '
|
||||
+ '#' + this.id + ' .remove'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get remove buttons
|
||||
*
|
||||
* @return {NodeListOf<any>}
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @todo isn't this the same as submit in some cases? form below table?
|
||||
*/
|
||||
getAdd() {
|
||||
return document.querySelectorAll(
|
||||
'button[form=' + this.id + '].add, '
|
||||
+ '.add[data-form=' + this.id + '], '
|
||||
+ '#' + this.id + ' .add'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get success callback
|
||||
*
|
||||
|
|
|
|||
|
|
@ -127,30 +127,4 @@ export class TableView {
|
|||
+ ' #' + this.id + ' tbody .order-down'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get row elements which allow to remove a row element
|
||||
*
|
||||
* @return {array}
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
getRemovable()
|
||||
{
|
||||
return document.querySelectorAll(
|
||||
'#' + this.id + ' tbody .remove'
|
||||
);
|
||||
};
|
||||
|
||||
getForm()
|
||||
{
|
||||
return document.getElementById(this.id).getAttribute('data-table-form');
|
||||
};
|
||||
|
||||
getUpdatable()
|
||||
{
|
||||
return document.querySelectorAll(
|
||||
'#' + this.id + ' tbody .update'
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user