From ae1a0cbf2079c376d3d612211d230526a3370ebd Mon Sep 17 00:00:00 2001 From: Maicol Battistini Date: Sat, 9 Oct 2021 14:33:52 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20=F0=9F=9A=B8=20Migliorata=20validazion?= =?UTF-8?q?e=20dei=20form?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/Components/Pages/RecordsPage.jsx | 6 ++-- resources/js/WebComponents/TextArea.js | 25 ++++++++++++++ resources/js/WebComponents/TextField.js | 33 +++++++++++++++++++ resources/js/WebComponents/index.js | 7 ++-- resources/js/app.js | 21 ------------ resources/js/utils.js | 23 ++++++++++++- 6 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 resources/js/WebComponents/TextArea.js create mode 100644 resources/js/WebComponents/TextField.js diff --git a/resources/js/Components/Pages/RecordsPage.jsx b/resources/js/Components/Pages/RecordsPage.jsx index 0397bb1b5..60f43577a 100644 --- a/resources/js/Components/Pages/RecordsPage.jsx +++ b/resources/js/Components/Pages/RecordsPage.jsx @@ -157,8 +157,8 @@ export default class RecordsPage extends Page { return fields.map((field, fieldIndex) => ( - + )) .toArray(); })()} @@ -229,7 +229,7 @@ export default class RecordsPage extends Page { if (form.isValid()) { const data = {}; - form.find('mwc-textfield, mwc-textarea') + form.find('text-field, text-area') .each((index, field) => { const key = this.saveModelWithSnakeCase ? snakeCase(field.id) : field.id; data[key] = field.value; diff --git a/resources/js/WebComponents/TextArea.js b/resources/js/WebComponents/TextArea.js new file mode 100644 index 000000000..bb984d4e4 --- /dev/null +++ b/resources/js/WebComponents/TextArea.js @@ -0,0 +1,25 @@ +import {TextArea as MWCTextArea} from '@material/mwc-textarea'; + +export default class TextArea extends MWCTextArea { + get nativeValidationMessage() { + return this.formElement.validationMessage; + } + + firstUpdated() { + if (this.validationMessage) { + this._initialValidationMessage = this.validationMessage; + } + super.firstUpdated(); + } + + reportValidity() { + const isValid = super.reportValidity(); + // Note(cg): override validationMessage only if no initial message set. + if (!this._initialValidationMessage && !isValid) { + this.validationMessage = this.nativeValidationMessage; + } + return isValid; + } +} + +window.customElements.define('text-area', TextArea); diff --git a/resources/js/WebComponents/TextField.js b/resources/js/WebComponents/TextField.js new file mode 100644 index 000000000..b78f6cf6a --- /dev/null +++ b/resources/js/WebComponents/TextField.js @@ -0,0 +1,33 @@ +import {TextField as MWCTextField} from '@material/mwc-textfield'; + +export default class TextField extends MWCTextField { + get nativeValidationMessage() { + return this.formElement.validationMessage; + } + + /** + * Fix mwc-textfield when handling validation message + * It gets native input validation message when no default validationMessage is set. + * + * Related issue: + * https://github.com/material-components/material-components-web-components/issues/971 + * + */ + firstUpdated() { + if (this.validationMessage) { + this._initialValidationMessage = this.validationMessage; + } + super.firstUpdated(); + } + + reportValidity() { + const isValid = super.reportValidity(); + // Note(cg): override validationMessage only if no initial message set. + if (!this._initialValidationMessage && !isValid) { + this.validationMessage = this.nativeValidationMessage; + } + return isValid; + } +} + +window.customElements.define('text-field', TextField); diff --git a/resources/js/WebComponents/index.js b/resources/js/WebComponents/index.js index 67e601546..93cb26f41 100644 --- a/resources/js/WebComponents/index.js +++ b/resources/js/WebComponents/index.js @@ -1,5 +1,6 @@ // noinspection JSUnusedGlobalSymbols -export { default as Drawer } from './MaterialDrawer'; -export { default as TopAppBar } from './TopAppBar'; - +export {default as Drawer} from './MaterialDrawer'; +export {default as TextArea} from './TextArea'; +export {default as TextField} from './TextField'; +export {default as TopAppBar} from './TopAppBar'; diff --git a/resources/js/app.js b/resources/js/app.js index 6f19c9b9b..240503b27 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -40,24 +40,3 @@ createInertiaApp({ m.mount(el, app); } }); - -$.fn.isValid = function () { - if (this.prop('tagName') - .toLowerCase() === 'form') { - let isValid: boolean = true; - - this.find('mwc-textfield, mwc-textarea') - .each((index: number, field: HTMLInputElement) => { - if (!field.checkValidity()) { - isValid = false; - return false; - } - - return true; - }); - - return isValid; - } - - return this[0].checkValidity(); -}; diff --git a/resources/js/utils.js b/resources/js/utils.js index 2038331e1..9d09c0835 100644 --- a/resources/js/utils.js +++ b/resources/js/utils.js @@ -1,9 +1,11 @@ // noinspection JSUnusedGlobalSymbols +import {type Cash} from 'cash-dom/dist/cash'; + /** * Check if class/object A is the same as or a subclass of class B. */ -export function subclassOf(A: {...}, B: {...}): boolean { +export function subclassOf(A: { ... }, B: { ... }): boolean { // noinspection JSUnresolvedVariable return A && (A === B || A.prototype instanceof B); } @@ -51,3 +53,22 @@ export async function showSnackbar(message: string, duration: number = 5000, acc }); return reasonPromise; } + +export function isFormValid(element: Cash | HTMLFontElement) { + let form = element; + + if (form instanceof HTMLFormElement) { + form = $(form); + } + + let isValid: boolean = true; + + form.find('text-field, text-area') + .each((index: number, field: HTMLInputElement) => { + if (!field.reportValidity()) { + isValid = false; + } + }); + + return isValid; +}