Enforce required label form fields before preview and create
This commit is contained in:
@@ -45,7 +45,7 @@ export function renderLabelCreatePage() {
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-body p-4">
|
||||
<form class="vstack gap-3" @submit.prevent="create()" autocomplete="off">
|
||||
<form class="vstack gap-3" @submit.prevent="create()" autocomplete="off" x-ref="labelForm">
|
||||
<div class="position-relative search-field-with-clear">
|
||||
<label class="form-label">Search item definitions</label>
|
||||
<input class="form-control pe-5" type="text" x-model="form.search" @input="onSearchInput()" placeholder="Search by item name" autocomplete="off" />
|
||||
@@ -98,8 +98,8 @@ export function renderLabelCreatePage() {
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<label class="form-label">Stock type</label>
|
||||
<select class="form-select" x-model="form.stockType" x-ref="stockTypeSelect" autocomplete="off">
|
||||
<label class="form-label">Stock type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" x-model="form.stockType" x-ref="stockTypeSelect" autocomplete="off" required>
|
||||
<template x-for="option in stockTypeOptions" :key="option.value">
|
||||
<option :value="option.value" x-text="option.label"></option>
|
||||
</template>
|
||||
@@ -232,6 +232,7 @@ export function renderLabelCreatePage() {
|
||||
class="form-control pe-5"
|
||||
type="text"
|
||||
x-model="locationSearch"
|
||||
x-ref="locationInput"
|
||||
@input="onLocationInput()"
|
||||
@keydown.escape="locationPickerOpen = false"
|
||||
@click="openLocationPicker()"
|
||||
@@ -284,8 +285,8 @@ export function renderLabelCreatePage() {
|
||||
<div class="form-text" x-show="selectedLocationPath" x-text="selectedLocationPath"></div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<label class="form-label">Production date</label>
|
||||
<input class="form-control" type="date" x-model="form.productionDate" />
|
||||
<label class="form-label">Production date <span class="text-danger">*</span></label>
|
||||
<input class="form-control" type="date" x-model="form.productionDate" required />
|
||||
</div>
|
||||
<div class="col-12 col-md-6 grouped-field-with-clear">
|
||||
<div class="grouped-field-footer mb-1">
|
||||
@@ -647,12 +648,14 @@ export function labelCreatePageData(store) {
|
||||
this.form.locationId = String(location.id);
|
||||
this.locationSearch = location.name;
|
||||
this.locationPickerOpen = false;
|
||||
this.syncLocationValidity();
|
||||
this.persistDraft();
|
||||
},
|
||||
clearLocation() {
|
||||
this.form.locationId = '';
|
||||
this.locationSearch = '';
|
||||
this.locationPickerOpen = true;
|
||||
this.syncLocationValidity();
|
||||
this.persistDraft();
|
||||
},
|
||||
openLocationPicker() {
|
||||
@@ -669,6 +672,7 @@ export function labelCreatePageData(store) {
|
||||
if (this.selectedLocation && this.locationSearch !== this.selectedLocation.name) {
|
||||
this.form.locationId = '';
|
||||
}
|
||||
this.syncLocationValidity();
|
||||
},
|
||||
handleLocationFocusOut(event) {
|
||||
const nextTarget = event.relatedTarget;
|
||||
@@ -721,6 +725,7 @@ export function labelCreatePageData(store) {
|
||||
);
|
||||
|
||||
this.locationSearch = selected ? selected.name : '';
|
||||
this.syncLocationValidity();
|
||||
},
|
||||
applyItemLocation(locationUuidB64) {
|
||||
if (!locationUuidB64) {
|
||||
@@ -737,6 +742,34 @@ export function labelCreatePageData(store) {
|
||||
|
||||
this.form.locationId = String(location.id);
|
||||
this.locationSearch = location.name;
|
||||
this.syncLocationValidity();
|
||||
},
|
||||
syncLocationValidity() {
|
||||
const input = this.$refs.locationInput;
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.locationSearch.trim()) {
|
||||
input.setCustomValidity('Please select a storage location.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.form.locationId) {
|
||||
input.setCustomValidity('Please choose a location from the list.');
|
||||
return;
|
||||
}
|
||||
|
||||
input.setCustomValidity('');
|
||||
},
|
||||
validateBeforeSubmit() {
|
||||
this.syncLocationValidity();
|
||||
const form = this.$refs.labelForm;
|
||||
if (!form) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return form.reportValidity();
|
||||
},
|
||||
syncExpireDateFromDays() {
|
||||
if (this.form.expireDays === '') {
|
||||
@@ -826,6 +859,14 @@ export function labelCreatePageData(store) {
|
||||
};
|
||||
},
|
||||
async preview() {
|
||||
this.submitError = '';
|
||||
this.fieldErrors = {};
|
||||
|
||||
if (!this.validateBeforeSubmit()) {
|
||||
this.previewState.error = 'Please fill out the required fields before previewing the label.';
|
||||
return;
|
||||
}
|
||||
|
||||
await runAsyncState(this.previewState, async () => {
|
||||
this.successMessage = '';
|
||||
const result = await previewLabel(store, this.buildPayload());
|
||||
@@ -840,6 +881,11 @@ export function labelCreatePageData(store) {
|
||||
this.submitError = '';
|
||||
this.fieldErrors = {};
|
||||
|
||||
if (!this.validateBeforeSubmit()) {
|
||||
this.submitError = 'Please fill out the required fields before creating the stock entry.';
|
||||
return;
|
||||
}
|
||||
|
||||
await runAsyncState(this.createState, async () => {
|
||||
try {
|
||||
const entry = await createStockEntry(store, this.buildPayload());
|
||||
|
||||
Reference in New Issue
Block a user