feat(mass-input): automatic add before submit
This commit is contained in:
parent
7018196bc7
commit
7540a4fe5f
@ -1,3 +1,5 @@
|
||||
/* global global:writable */
|
||||
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import './mass-input.sass';
|
||||
@ -7,6 +9,11 @@ const MASS_INPUT_ADD_CELL_SELECTOR = '.massinput__cell--add';
|
||||
const MASS_INPUT_SUBMIT_BUTTON_CLASS = 'massinput__submit-button';
|
||||
const MASS_INPUT_INITIALIZED_CLASS = 'mass-input--initialized';
|
||||
|
||||
const MASS_INPUT_ADD_CHANGE_FIELD_SELECTOR = 'select, input[type=radio]';
|
||||
|
||||
// const MASS_INPUT_SAFETY_SUBMITTED_CLASS = 'massinput--safety-submitted';
|
||||
// const MASS_INPUT_SAFETY_SUBMITTED_TIMEOUT = 1000;
|
||||
|
||||
@Utility({
|
||||
selector: '[uw-mass-input]',
|
||||
})
|
||||
@ -14,11 +21,14 @@ export class MassInput {
|
||||
|
||||
_element;
|
||||
_app;
|
||||
_global;
|
||||
|
||||
_massInputId;
|
||||
_massInputFormSubmitHandler;
|
||||
_massInputForm;
|
||||
|
||||
_changedAdd = new Array();
|
||||
|
||||
constructor(element, app) {
|
||||
if (!element) {
|
||||
throw new Error('Mass Input utility cannot be setup without an element!');
|
||||
@ -27,6 +37,14 @@ export class MassInput {
|
||||
this._element = element;
|
||||
this._app = app;
|
||||
|
||||
if (global !== undefined)
|
||||
this._global = global;
|
||||
else if (window !== undefined)
|
||||
this._global = window;
|
||||
else
|
||||
throw new Error('Cannot setup Mass Input utility without window or global');
|
||||
|
||||
|
||||
if (this._element.classList.contains(MASS_INPUT_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
@ -47,8 +65,10 @@ export class MassInput {
|
||||
this._setupSubmitButton(button);
|
||||
});
|
||||
|
||||
this._massInputForm.addEventListener('submit', this._massInputFormSubmitHandler);
|
||||
this._massInputForm.addEventListener('keypress', this._keypressHandler);
|
||||
this._massInputForm.addEventListener('submit', this._massInputFormSubmitHandler.bind(this));
|
||||
this._massInputForm.addEventListener('keypress', this._keypressHandler.bind(this));
|
||||
|
||||
Array.from(this._element.querySelectorAll(MASS_INPUT_ADD_CELL_SELECTOR)).forEach(this._setupChangedHandlers.bind(this));
|
||||
|
||||
// mark initialized
|
||||
this._element.classList.add(MASS_INPUT_INITIALIZED_CLASS);
|
||||
@ -58,6 +78,26 @@ export class MassInput {
|
||||
this._reset();
|
||||
}
|
||||
|
||||
_setupChangedHandlers(addCell) {
|
||||
Array.from(addCell.querySelectorAll(MASS_INPUT_ADD_CHANGE_FIELD_SELECTOR)).forEach(inputElem => {
|
||||
if (inputElem.closest('[uw-mass-input]') !== this._element)
|
||||
return;
|
||||
|
||||
inputElem.addEventListener('change', () => { this._changedAdd.push(addCell); });
|
||||
});
|
||||
}
|
||||
|
||||
_unsafeAddCells() {
|
||||
let changedAdd = this._changedAdd;
|
||||
|
||||
Array.from(this._element.querySelectorAll(MASS_INPUT_ADD_CELL_SELECTOR)).forEach(addCell => addCell.querySelectorAll('input:not([type=checkbox]):not([type=radio])').forEach(inputElem => {
|
||||
if (inputElem.closest('[uw-mass-input]') === this._element && inputElem.value !== '')
|
||||
changedAdd.push(addCell);
|
||||
}));
|
||||
|
||||
return changedAdd;
|
||||
}
|
||||
|
||||
_makeSubmitHandler() {
|
||||
const method = this._massInputForm.getAttribute('method') || 'POST';
|
||||
const url = this._massInputForm.getAttribute('action') || window.location.href;
|
||||
@ -69,31 +109,58 @@ export class MassInput {
|
||||
}
|
||||
|
||||
return (event) => {
|
||||
let activeElement;
|
||||
let submitButton;
|
||||
let isAddCell;
|
||||
|
||||
let isMassInputSubmit = (() => {
|
||||
let activeElement;
|
||||
|
||||
// check if event occured from either a mass input add/delete button or
|
||||
// from inside one of massinput's inputs (i.e. a child is focused/active)
|
||||
activeElement = this._element.querySelector(':focus, :active');
|
||||
// check if event occured from either a mass input add/delete button or
|
||||
// from inside one of massinput's inputs (i.e. a child is focused/active)
|
||||
activeElement = this._element.querySelector(':focus, :active');
|
||||
|
||||
if (!activeElement) {
|
||||
return false;
|
||||
if (!activeElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the according massinput cell thats hosts the element that triggered the submit
|
||||
const massInputCell = activeElement.closest(MASS_INPUT_CELL_SELECTOR);
|
||||
if (!massInputCell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
submitButton = massInputCell.querySelector('.' + MASS_INPUT_SUBMIT_BUTTON_CLASS);
|
||||
if (!submitButton) {
|
||||
return false;
|
||||
}
|
||||
|
||||
isAddCell = massInputCell.matches(MASS_INPUT_ADD_CELL_SELECTOR);
|
||||
const submitButtonIsActive = submitButton.matches(':focus, :active');
|
||||
// if the cell is not an add cell the active element must at least be the cells submit button
|
||||
if (!isAddCell && !submitButtonIsActive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})();
|
||||
|
||||
let unsafeAddCells = this._unsafeAddCells();
|
||||
|
||||
if (unsafeAddCells.length > 0 && !isMassInputSubmit) {
|
||||
let addButtons = Array.from(unsafeAddCells[0].querySelectorAll('.' + MASS_INPUT_SUBMIT_BUTTON_CLASS)).filter(addButton => addButton.closest('[uw-mass-input]') === this._element);
|
||||
|
||||
if (addButtons.length > 0) {
|
||||
submitButton = addButtons[0];
|
||||
isMassInputSubmit = true;
|
||||
isAddCell = false;
|
||||
|
||||
this._element.scrollIntoView();
|
||||
// this._element.classList.add(MASS_INPUT_SAFETY_SUBMITTED_CLASS);
|
||||
// this._global.setTimeout(() => { this._element.classList.remove(MASS_INPUT_SAFETY_SUBMITTED_CLASS) }, MASS_INPUT_SAFETY_SUBMITTED_TIMEOUT)
|
||||
}
|
||||
}
|
||||
|
||||
// find the according massinput cell thats hosts the element that triggered the submit
|
||||
const massInputCell = activeElement.closest(MASS_INPUT_CELL_SELECTOR);
|
||||
if (!massInputCell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const submitButton = massInputCell.querySelector('.' + MASS_INPUT_SUBMIT_BUTTON_CLASS);
|
||||
if (!submitButton) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isAddCell = massInputCell.matches(MASS_INPUT_ADD_CELL_SELECTOR);
|
||||
const submitButtonIsActive = submitButton.matches(':focus, :active');
|
||||
// if the cell is not an add cell the active element must at least be the cells submit button
|
||||
if (!isAddCell && !submitButtonIsActive) {
|
||||
if (!isMassInputSubmit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
@use "../../app" as *
|
||||
|
||||
.massinput-list__wrapper, .massinput-list__cell
|
||||
display: grid
|
||||
grid: auto / auto 50px
|
||||
@ -12,3 +14,14 @@
|
||||
|
||||
.massinput-list__cell
|
||||
grid-column: 1 / 3
|
||||
|
||||
/* .massinput--safety-submitted
|
||||
/* animation: massinput--safety-submitted linear 1s
|
||||
|
||||
/* @keyframes massinput--safety-submitted
|
||||
/* 0%
|
||||
/* background-color: rgba(252, 153, 0, 0)
|
||||
/* 50%
|
||||
/* background-color: rgba(252, 153, 0, 0.8)
|
||||
/* 100%
|
||||
/* background-color: rgba(252, 153, 0, 0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user