96 lines
2.9 KiB
JavaScript
96 lines
2.9 KiB
JavaScript
// SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import { Utility } from '../../core/utility';
|
|
import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager';
|
|
|
|
const REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS = 'reactive-submit-button--initialized';
|
|
|
|
@Utility({
|
|
selector: 'form',
|
|
})
|
|
export class ReactiveSubmitButton {
|
|
|
|
_element;
|
|
|
|
_requiredInputs;
|
|
_submitButton;
|
|
|
|
_eventManager;
|
|
|
|
constructor(element) {
|
|
if (!element) {
|
|
throw new Error('Reactive Submit Button utility cannot be setup without an element!');
|
|
}
|
|
|
|
this._element = element;
|
|
this._eventManager = new EventManager();
|
|
|
|
if (this._element.classList.contains(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS)) {
|
|
return false;
|
|
}
|
|
|
|
// abort if form has param data-formnorequired
|
|
if (this._element.dataset.formnorequired !== undefined) {
|
|
throw new Error('Form has formnorequired data attribute. Will skip setup of reactive submit button.');
|
|
}
|
|
|
|
this._requiredInputs = Array.from(this._element.querySelectorAll('[required]'));
|
|
if (!this._requiredInputs) {
|
|
// abort if form has no required inputs
|
|
throw new Error('Submit button has formnorequired data attribute. Will skip setup of reactive submit button.');
|
|
}
|
|
|
|
const submitButtons = Array.from(this._element.querySelectorAll('[type="submit"]'));
|
|
if (!submitButtons || !submitButtons.length) {
|
|
throw new Error('Reactive Submit Button utility couldn\'t find any submit buttons!');
|
|
}
|
|
this._submitButton = submitButtons.reverse()[0];
|
|
// abort if form has param data-formnorequired
|
|
if (this._submitButton.dataset.formnorequired !== undefined) {
|
|
return false;
|
|
}
|
|
|
|
this.setupInputs();
|
|
this.updateButtonState();
|
|
|
|
this._element.classList.add(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS);
|
|
}
|
|
|
|
destroy() {
|
|
this._eventManager.removeAllEventListenersFromUtil();
|
|
this._element.classList.remove(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS);
|
|
}
|
|
|
|
setupInputs() {
|
|
this._requiredInputs.forEach((el) => {
|
|
const checkbox = el.getAttribute('type') === 'checkbox';
|
|
const eventType = checkbox ? EVENT_TYPE.CHANGE : EVENT_TYPE.INPUT;
|
|
const valEvent = new EventWrapper(eventType,(() => {
|
|
this.updateButtonState();
|
|
}).bind(this), el );
|
|
this._eventManager.registerNewListener(valEvent);
|
|
});
|
|
}
|
|
|
|
updateButtonState() {
|
|
if (this.inputsValid()) {
|
|
this._submitButton.removeAttribute('disabled');
|
|
} else {
|
|
this._submitButton.setAttribute('disabled', 'true');
|
|
}
|
|
}
|
|
|
|
inputsValid() {
|
|
let done = true;
|
|
this._requiredInputs.forEach((inp) => {
|
|
const len = inp.value.trim().length;
|
|
if (done && len === 0) {
|
|
done = false;
|
|
}
|
|
});
|
|
return done;
|
|
}
|
|
}
|