Client - update input style on validation error
This commit is contained in:
@ -11,13 +11,17 @@
|
||||
message="user.REGISTER_DISABLED"
|
||||
v-if="registration_disabled"
|
||||
/>
|
||||
<form @submit.prevent="onSubmit(action)">
|
||||
<form
|
||||
:class="{ errors: formErrors }"
|
||||
@submit.prevent="onSubmit(action)"
|
||||
>
|
||||
<div class="form-items">
|
||||
<input
|
||||
v-if="action === 'register'"
|
||||
id="username"
|
||||
:disabled="registration_disabled"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
v-model="formData.username"
|
||||
:placeholder="$t('user.USERNAME')"
|
||||
/>
|
||||
@ -26,6 +30,7 @@
|
||||
id="email"
|
||||
:disabled="registration_disabled"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
type="email"
|
||||
v-model="formData.email"
|
||||
:placeholder="
|
||||
@ -39,6 +44,7 @@
|
||||
id="password"
|
||||
:disabled="registration_disabled"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
type="password"
|
||||
v-model="formData.password"
|
||||
:placeholder="
|
||||
@ -53,6 +59,7 @@
|
||||
:disabled="registration_disabled"
|
||||
type="password"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
v-model="formData.password_conf"
|
||||
:placeholder="
|
||||
action === 'reset'
|
||||
@ -91,6 +98,7 @@
|
||||
ComputedRef,
|
||||
computed,
|
||||
reactive,
|
||||
ref,
|
||||
toRefs,
|
||||
watch,
|
||||
withDefaults,
|
||||
@ -133,6 +141,7 @@
|
||||
() =>
|
||||
props.action === 'register' && !appConfig.value.is_registration_enabled
|
||||
)
|
||||
const formErrors = ref(false)
|
||||
|
||||
function getButtonText(action: string): string {
|
||||
switch (action) {
|
||||
@ -143,6 +152,9 @@
|
||||
return `buttons.${props.action.toUpperCase()}`
|
||||
}
|
||||
}
|
||||
function invalidateForm() {
|
||||
formErrors.value = true
|
||||
}
|
||||
function onSubmit(actionType: string) {
|
||||
switch (actionType) {
|
||||
case 'reset':
|
||||
@ -183,6 +195,7 @@
|
||||
() => route.path,
|
||||
async () => {
|
||||
store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
formErrors.value = false
|
||||
resetFormData()
|
||||
}
|
||||
)
|
||||
|
@ -10,7 +10,7 @@
|
||||
}}</template>
|
||||
<template #content>
|
||||
<div id="workout-form">
|
||||
<form @submit.prevent="updateWorkout">
|
||||
<form :class="{ errors: formErrors }" @submit.prevent="updateWorkout">
|
||||
<div class="form-items">
|
||||
<div class="form-item-radio" v-if="isCreation">
|
||||
<div>
|
||||
@ -41,6 +41,7 @@
|
||||
<select
|
||||
id="sport"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.sport_id"
|
||||
>
|
||||
@ -64,6 +65,8 @@
|
||||
type="file"
|
||||
accept=".gpx, .zip"
|
||||
:disabled="loading"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
@input="updateFile"
|
||||
/>
|
||||
<div class="files-help info-box">
|
||||
@ -94,6 +97,7 @@
|
||||
name="title"
|
||||
type="text"
|
||||
:required="!isCreation"
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.title"
|
||||
/>
|
||||
@ -108,6 +112,7 @@
|
||||
name="workout-date"
|
||||
type="date"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutDate"
|
||||
/>
|
||||
@ -117,6 +122,7 @@
|
||||
class="workout-time"
|
||||
type="time"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutTime"
|
||||
/>
|
||||
@ -133,6 +139,7 @@
|
||||
placeholder="HH"
|
||||
pattern="^([0-9]*[0-9])$"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutDurationHour"
|
||||
/>
|
||||
@ -145,6 +152,7 @@
|
||||
pattern="^([0-5][0-9])$"
|
||||
placeholder="MM"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutDurationMinutes"
|
||||
/>
|
||||
@ -157,6 +165,7 @@
|
||||
pattern="^([0-5][0-9])$"
|
||||
placeholder="SS"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutDurationSeconds"
|
||||
/>
|
||||
@ -171,6 +180,7 @@
|
||||
min="0"
|
||||
step="0.1"
|
||||
required
|
||||
@invalid="invalidateForm"
|
||||
:disabled="loading"
|
||||
v-model="workoutForm.workoutDistance"
|
||||
/>
|
||||
@ -279,6 +289,7 @@
|
||||
props.workout.id ? props.workout.with_gpx : props.isCreation
|
||||
)
|
||||
let gpxFile: File | null = null
|
||||
const formErrors = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
if (props.workout.id) {
|
||||
@ -291,6 +302,7 @@
|
||||
}
|
||||
function updateWithGpx() {
|
||||
withGpx.value = !withGpx.value
|
||||
formErrors.value = false
|
||||
}
|
||||
function updateFile(event: Event & { target: HTMLInputElement }) {
|
||||
if (event.target.files) {
|
||||
@ -364,6 +376,9 @@
|
||||
router.go(-1)
|
||||
}
|
||||
}
|
||||
function invalidateForm() {
|
||||
formErrors.value = true
|
||||
}
|
||||
|
||||
onUnmounted(() => store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES))
|
||||
|
||||
|
@ -39,6 +39,12 @@ input, textarea, select {
|
||||
}
|
||||
}
|
||||
|
||||
form.errors {
|
||||
:invalid {
|
||||
outline: 2px solid var(--input-error-color);
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
--card-border-color: #c4c7cf;
|
||||
--input-border-color: #9da3af;
|
||||
--input-bg-color: #FFFFFF;
|
||||
--input-error-color: #dc3545;
|
||||
--dropdown-hover-color: #eff0f5;
|
||||
|
||||
--custom-checkbox-border-color: #9da3af;
|
||||
|
Reference in New Issue
Block a user