added ui state manager

This commit is contained in:
Dennis Eichhorn 2022-04-10 00:18:16 +02:00
parent 301f73fda5
commit 928bad0e41
10 changed files with 311 additions and 101 deletions

View File

@ -83,18 +83,20 @@ export class Form
{
if (id !== null && typeof this.ignore[id] === 'undefined') {
this.bindForm(id);
} else {
const forms = document.querySelectorAll('form, [data-tag=form]');
const length = !forms ? 0 : forms.length;
for (let i = 0; i < length; ++i) {
const formId = forms[i].getAttribute('id');
return;
}
if (typeof formId !== 'undefined' && formId !== null && typeof this.ignore[formId] === 'undefined') {
this.bindForm(formId);
} else {
Logger.instance.info('A form doesn\'t have an ID.');
}
const forms = document.querySelectorAll('form, [data-tag=form]');
const length = !forms ? 0 : forms.length;
for (let i = 0; i < length; ++i) {
const formId = forms[i].getAttribute('id');
if (typeof formId !== 'undefined' && formId !== null && typeof this.ignore[formId] === 'undefined') {
this.bindForm(formId);
} else {
Logger.instance.info('A form doesn\'t have an ID.');
}
}
};
@ -188,11 +190,11 @@ export class Form
: formElement.querySelector(uiContainerName);
/** @var {HTMLElement} newElement New element to add */
const newElement = uiContainer.querySelector('.add-tpl').content.cloneNode(true);
const newElement = uiContainer.querySelector('.oms-add-tpl').content.cloneNode(true);
// set random id for element
/** @var {string} eleId New element id */
const eleId = Form.setRandomIdForTemplateElement(newElement);
const eleId = Form.setRandomIdForElement(newElement.firstElementChild);
// If the new element has a form it should also receive a id
if (newElement.firstElementChild.getElementsByTagName('form').length > 0) {
@ -266,7 +268,7 @@ export class Form
);
// set random id for element
Form.setRandomIdForTemplateElement(newElements[i]);
Form.setRandomIdForElement(newElements[i].firstElementChild);
}
/** @var {object} remoteUrls Texts and values which come from remote sources */
@ -492,7 +494,7 @@ export class Form
newElement.push(document.querySelector(updatableTpl[i]).content.cloneNode(true));
Form.setRandomIdForTemplateElement(newElement[i]);
Form.setRandomIdForElement(newElement[i].firstElementChild);
}
const fields = [];
@ -903,17 +905,17 @@ export class Form
};
/**
* Set random id of a template element
* Set random data-id of a element
*
* @param {HTMLElement} templateElement Element to set the id for
* @param {HTMLElement} element Element to set the data-id for
*
* @return {string}
*
* @since 1.0.0
*/
static setRandomIdForTemplateElement (templateElement)
static setRandomIdForElement (element)
{
if (templateElement.firstElementChild.getAttribute('data-id') !== null) {
if (element.getAttribute('data-id') !== null && element.getAttribute('data-id') !== '') {
return;
}
@ -923,7 +925,7 @@ export class Form
eleId = 'r-' + Math.random().toString(36).substring(7);
} while (document.querySelector('[data-id="' + eleId + '"]') !== null);
templateElement.firstElementChild.setAttribute('data-id', eleId);
element.setAttribute('data-id', eleId);
return eleId;
};
@ -934,7 +936,9 @@ export class Form
const length = data.length;
const templateLength = elements.length;
for (let i = 0; i < length; ++i) {
const path = data[i].hasAttribute('data-tpl-' + type + '-path') ? data[i].getAttribute('data-tpl-' + type + '-path') : null;
const path = data[i].hasAttribute('data-tpl-' + type + '-path')
? data[i].getAttribute('data-tpl-' + type + '-path')
: null;
for (let j = 0; j < templateLength; ++j) {
// sometimes elements contains templates, they need to get handled differently
@ -981,7 +985,9 @@ export class Form
const length = data.length;
for (let i = 0; i < length; ++i) {
const matches = self.forms[formId].getFormElement().querySelectorAll('[data-tpl-' + type + '="' + data[i].getAttribute('data-tpl-' + type) + '"');
const path = data[i].hasAttribute('data-tpl-' + type + '-path') ? data[i].getAttribute('data-tpl-' + type + '-path') : null;
const path = data[i].hasAttribute('data-tpl-' + type + '-path')
? data[i].getAttribute('data-tpl-' + type + '-path')
: null;
const matchLength = matches.length;
for (let c = 0; c < matchLength; ++c) {

View File

@ -40,13 +40,15 @@ export class Tab
if (e) {
this.bindElement(e);
}
} else {
const tabs = document.getElementsByClassName('tabview');
const length = !tabs ? 0 : tabs.length;
for (let i = 0; i < length; ++i) {
this.bindElement(tabs[i]);
}
return;
}
const tabs = document.getElementsByClassName('tabview');
const length = !tabs ? 0 : tabs.length;
for (let i = 0; i < length; ++i) {
this.bindElement(tabs[i]);
}
};

View File

@ -63,52 +63,39 @@ export class Table
{
if (id !== null && typeof this.ignore[id] === 'undefined') {
this.bindTable(id);
} else {
const tables = document.getElementsByTagName('table');
const length = !tables ? 0 : tables.length;
for (let i = 0; i < length; ++i) {
const tableId = tables[i].getAttribute('id');
if (typeof tableId !== 'undefined' && tableId !== null && typeof this.ignore[tableId] === 'undefined') {
this.bindTable(tableId);
}
return;
}
const tables = document.getElementsByTagName('table');
const length = !tables ? 0 : tables.length;
for (let i = 0; i < length; ++i) {
const tableId = tables[i].getAttribute('id');
if (typeof tableId !== 'undefined' && tableId !== null && typeof this.ignore[tableId] === 'undefined') {
this.bindTable(tableId);
}
}
};
/**
* Unbind table
*
* @param {string} id Table Id
*
* @return {void}
*
* @since 1.0.0
*/
unbind (id)
{
};
/**
* Bind & rebind UI element.
*
* @param {Object} [id] Element id
* @param {Object} id Element id
*
* @return {void}
*
* @since 1.0.0
*/
bindTable (id)
bindTable (id = null)
{
if (typeof id === 'undefined' || !id) {
if (id === null) {
jsOMS.Log.Logger.instance.info('A table doesn\'t have an ID.');
return;
}
this.tables[id] = new TableView(id);
this.unbind(id);
this.bindExport(this.tables[id]);
/**

View File

@ -36,7 +36,7 @@ export class DragNDrop
if (element !== null) {
this.bindElement(element);
} else {
const elements = document.querySelectorAll('.dragcontainer');
const elements = document.querySelectorAll('.oms-dragcontainer');
const length = !elements ? 0 : elements.length;
for (let i = 0; i < length; ++i) {
@ -71,12 +71,12 @@ export class DragNDrop
}, false);
element.addEventListener('dragenter', function (e) {
const thisElement = e.target.closest('.dragcontainer ' + this.children[this.children.length - 1].tagName);
const thisElement = e.target.closest('.oms-dragcontainer ' + this.children[this.children.length - 1].tagName);
const rowIndex = Array.from(this.children).indexOf(thisElement);
const dragIndex = Array.from(self.dragging.children).indexOf(self.dragging);
const oldPlaceholder = this.querySelector('.drag-placeholder');
const oldPlaceholder = this.querySelector('.oms-drag-placeholder');
if (oldPlaceholder !== null) {
this.removeChild(oldPlaceholder);
}
@ -91,7 +91,7 @@ export class DragNDrop
placeholder.setAttribute('draggable', 'true');
jsOMS.addClass(placeholder, 'drag-placeholder');
jsOMS.addClass(placeholder, 'oms-drag-placeholder');
if (dragIndex < rowIndex) {
this.insertBefore(placeholder, thisElement.nextSibling);
@ -113,7 +113,7 @@ export class DragNDrop
element.addEventListener('dragend', function (e) {
e.preventDefault();
const oldPlaceholder = this.querySelector('.drag-placeholder');
const oldPlaceholder = this.querySelector('.oms-drag-placeholder');
if (oldPlaceholder === null) {
return;
}

View File

@ -1 +0,0 @@
/* responsible for loading external ui elements (css,html,js) */

View File

@ -29,17 +29,19 @@ export class Order
*
* @since 1.0.0
*/
bind (element)
bind (element = null)
{
if (typeof element !== 'undefined') {
if (element !== null) {
this.bindElement(element);
} else {
const elements = document.querySelectorAll('.ordercontainer');
const length = !elements ? 0 : elements.length;
for (let i = 0; i < length; ++i) {
this.bindElement(elements[i]);
}
return;
}
const elements = document.querySelectorAll('.oms-ordercontainer');
const length = !elements ? 0 : elements.length;
for (let i = 0; i < length; ++i) {
this.bindElement(elements[i]);
}
};
@ -68,7 +70,7 @@ export class Order
jsOMS.preventAll(event);
const rowLength = element.children.length;
const thisElement = event.target.closest('.ordercontainer ' + this.children[rowLength - 1].tagName);
const thisElement = event.target.closest('.oms-ordercontainer ' + this.children[rowLength - 1].tagName);
const rowId = Array.from(element.children).indexOf(thisElement);
const orderType = jsOMS.hasClass(event.target, 'order-up') ? 1 : -1;

85
UI/RemoteData.js Normal file
View File

@ -0,0 +1,85 @@
/**
* Remote data class.
*
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @since 1.0.0
*/
export class RemoteData
{
/**
* @constructor
*
* @param {Object} app Application
*
* @since 1.0.0
*/
constructor (app)
{
this.app = app;
};
/**
* Bind element
*
* @param {Object} [element] DOM element
*
* @return {void}
*
* @since 1.0.0
*/
bind (element = null)
{
if (element !== null) {
this.bindElement(element);
return;
}
const elements = document.querySelectorAll('.oms-remotecontainer');
const length = !elements ? 0 : elements.length;
for (let i = 0; i < length; ++i) {
this.bindElement(elements[i]);
}
};
/**
* Bind DOM element
*
* @param {Element} element DOM element
*
* @return {void}
*
* @since 1.0.0
*/
bindElement (element)
{
if (!element) {
return;
}
element.addEventListener('click', function (event) {
if (!jsOMS.hasClass(event.target, 'order-up')
&& !jsOMS.hasClass(event.target, 'order-down')
) {
return;
}
jsOMS.preventAll(event);
const rowLength = element.children.length;
const thisElement = event.target.closest('.ordercontainer ' + this.children[rowLength - 1].tagName);
const rowId = Array.from(element.children).indexOf(thisElement);
const orderType = jsOMS.hasClass(event.target, 'order-up') ? 1 : -1;
if (orderType === 1 && rowId > 0) {
element.insertBefore(element.children[rowId], element.children[rowId - 1]);
} else if (orderType === -1 && rowId < rowLength) {
element.insertBefore(element.children[rowId], element.children[rowId + 2]);
}
}, false);
}
};

View File

@ -1,10 +1,12 @@
import { Form } from '../UI/Component/Form.js';
import { Tab } from '../UI/Component/Tab.js';
import { Table } from '../UI/Component/Table.js';
import { ActionManager } from '../UI/ActionManager.js';
import { DragNDrop } from '../UI/DragNDrop.js';
import { Order } from '../UI/Order.js';
import { GeneralUI } from '../UI/GeneralUI.js';
import { Form } from './Component/Form.js';
import { Tab } from './Component/Tab.js';
import { Table } from './Component/Table.js';
import { ActionManager } from './ActionManager.js';
import { DragNDrop } from './DragNDrop.js';
import { Order } from './Order.js';
import { RemoteData } from './RemoteData.js';
import { GeneralUI } from './GeneralUI.js';
import { UIStateManager } from './UIStateManager.js';
/**
* UI manager for handling basic ui elements.
@ -25,14 +27,16 @@ export class UIManager
*/
constructor (app)
{
this.app = app;
this.formManager = new Form(this.app);
this.tabManager = new Tab(this.app);
this.tableManager = new Table(this.app);
this.actionManager = new ActionManager(this.app);
this.dragNDrop = new DragNDrop(this.app);
this.order = new Order(this.app);
this.generalUI = new GeneralUI(this.app);
this.app = app;
this.formManager = new Form(this.app);
this.tabManager = new Tab(this.app);
this.tableManager = new Table(this.app);
this.actionManager = new ActionManager(this.app);
this.dragNDrop = new DragNDrop(this.app);
this.order = new Order(this.app);
this.generalUI = new GeneralUI(this.app);
this.remoteData = new RemoteData(this.app);
this.uiStateManager = new UIStateManager(this.app);
const self = this;
/** global: MutationObserver */
@ -54,9 +58,9 @@ export class UIManager
*
* @since 1.0.0
*/
bind (id)
bind (id = null)
{
if (typeof id === 'undefined') {
if (id === null) {
this.formManager.bind();
this.tabManager.bind();
this.tableManager.bind();
@ -64,24 +68,28 @@ export class UIManager
this.dragNDrop.bind();
this.order.bind();
this.generalUI.bind();
} else {
const tag = document.getElementById(id);
this.generalUI.bind(tag);
this.remoteData.bind();
this.uiStateManager.bind();
if (!tag) {
return;
}
return;
}
switch (tag.tagName) {
case 'form':
this.formManager.bind(id);
break;
case 'table':
this.tableManager.bind(id);
break;
default:
this.actionManager.bind(tag);
}
const tag = document.getElementById(id);
this.generalUI.bind(tag);
if (!tag) {
return;
}
switch (tag.tagName) {
case 'form':
this.formManager.bind(id);
break;
case 'table':
this.tableManager.bind(id);
break;
default:
this.actionManager.bind(tag);
}
};
@ -133,6 +141,30 @@ export class UIManager
return this.order;
};
/**
* Get remote data manager.
*
* @return {Object}
*
* @since 1.0.0
*/
getRemoteData ()
{
return this.remoteData;
};
/**
* Get remote data manager.
*
* @return {Object}
*
* @since 1.0.0
*/
getUIStatemanager ()
{
return this.uiStateManager;
};
/**
* Get tab manager.
*

97
UI/UIStateManager.js Normal file
View File

@ -0,0 +1,97 @@
/**
* UI state manager class.
*
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @since 1.0.0
*/
export class UIStateManager
{
/**
* @constructor
*
* @param {Object} app Application
*
* @since 1.0.0
*/
constructor (app)
{
this.app = app;
};
/**
* Bind element
*
* @param {Object} [element] DOM element
*
* @return {void}
*
* @since 1.0.0
*/
bind (element = null)
{
if (element !== null) {
this.bindElement(element);
return;
}
const elements = document.querySelectorAll('.oms-ui-state');
const length = !elements ? 0 : elements.length;
for (let i = 0; i < length; ++i) {
this.bindElement(elements[i]);
}
};
/**
* Bind DOM element
*
* @param {Element} element DOM element
*
* @return {void}
*
* @since 1.0.0
*/
bindElement (element)
{
if (!element) {
return;
}
let state = JSON.parse(window.localStorage.getItem('ui-state-' + element.id));
state = state !== null ? state : {};
switch (element.tagName.toLowerCase()) {
case 'input':
if (state === '1') {
element.click();
}
element.addEventListener('change', function (event) {
if (this.getAttribute('type') === 'checkbox'
|| this.getAttribute('type') === 'radio'
) {
window.localStorage.setItem('ui-state-' + this.id, JSON.stringify('1'));
} else {
window.localStorage.setItem('ui-state-' + this.id, JSON.stringify(this.value));
}
});
break;
case 'div':
// @todo: this is not working, WHY? state is correct, but element.scrollTop is just ignored?!
element.scrollLeft = state.x;
element.scrollTop = state.y;
element.addEventListener('scroll', function () {
window.localStorage.setItem('ui-state-' + this.id, JSON.stringify({x: this.scrollLeft, y: this.scrollTop}));
});
break;
default:
break;
}
};
};