diff --git a/src/apps/dashboard/routes/users/add.tsx b/src/apps/dashboard/routes/users/add.tsx index be7a25f6c1..9e7cc0f22e 100644 --- a/src/apps/dashboard/routes/users/add.tsx +++ b/src/apps/dashboard/routes/users/add.tsx @@ -205,6 +205,7 @@ const UserNew = () => { type='text' id='txtUsername' label='LabelName' + validator={{ pattern: '^([\\w \\-\'._@+]*)([\\w\\-\'._@+])([\\w \\-\'._@+]*)$', errMessage: 'Username must not be empty and contain only numbers, letters, spaces, or the following symbols -\'._@+' }} options={'required'} /> diff --git a/src/elements/InputElement.tsx b/src/elements/InputElement.tsx index ae7e757b69..c181b53057 100644 --- a/src/elements/InputElement.tsx +++ b/src/elements/InputElement.tsx @@ -2,23 +2,30 @@ import React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react'; import globalize from 'lib/globalize'; +import './InputElementInvalidMessage.scss'; + interface CreateInputElementParams { type?: string id?: string label?: string initialValue?: string + validator?: { pattern: string, errMessage: string } options?: string } -const createInputElement = ({ type, id, label, initialValue, options }: CreateInputElementParams) => ({ +const createInputElement = ({ type, id, label, initialValue, validator, options }: CreateInputElementParams) => ({ __html: `` + /> +
+ ${validator?.errMessage || ''} +
` }); type InputElementProps = { @@ -33,7 +40,9 @@ const InputElement: FC = ({ type, id, label, + validator, options = '' + }) => { const container = useRef(null); @@ -44,14 +53,16 @@ const InputElement: FC = ({ id, label: globalize.translate(label), initialValue, + validator, options }) // eslint-disable-next-line react-hooks/exhaustive-deps ), []); const onInput = useCallback((e: Event) => { + if (validator) (e.target as HTMLElement).parentElement?.querySelector('.inputElementInvalidMessage')?.classList.add('inputReadyForValidation'); onChange((e.target as HTMLInputElement).value); - }, [ onChange ]); + }, [ onChange, validator ]); useEffect(() => { const inputElement = container?.current?.querySelector('input'); diff --git a/src/elements/InputElementInvalidMessage.scss b/src/elements/InputElementInvalidMessage.scss new file mode 100644 index 0000000000..89cba5ea8d --- /dev/null +++ b/src/elements/InputElementInvalidMessage.scss @@ -0,0 +1,8 @@ +.inputElementInvalidMessage { + color: red; + display: none; +} + +.emby-input:invalid + .inputElementInvalidMessage.inputReadyForValidation { + display: block; +}