Merge pull request #234 from tonyaellie/add-char-counts-with-max-to-lots-of-inputs

Add char counters to inputs
This commit is contained in:
Katos
2024-09-28 21:35:50 +01:00
committed by GitHub
8 changed files with 133 additions and 23 deletions

View File

@@ -2,16 +2,30 @@
<div v-if="!inline" class="form-control w-full">
<label class="label">
<span class="label-text">{{ label }}</span>
<span
:class="{
'text-red-600':
typeof value === 'string' &&
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
}"
>
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
</span>
</label>
<textarea ref="el" v-model="value" class="textarea textarea-bordered h-28 w-full" :placeholder="placeholder" />
<label v-if="limit" class="label">
<span class="label-text-alt"></span>
<span class="label-text-alt"> {{ valueLen }}/{{ limit }}</span>
</label>
</div>
<div v-else class="sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
<label class="label">
<span class="label-text">{{ label }}</span>
<span
:class="{
'text-red-600':
typeof value === 'string' &&
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
}"
>
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
</span>
</label>
<textarea
ref="el"
@@ -39,10 +53,6 @@
type: String,
default: "text",
},
limit: {
type: [Number, String],
default: null,
},
placeholder: {
type: String,
default: "",
@@ -51,6 +61,14 @@
type: Boolean,
default: false,
},
maxLength: {
type: Number,
required: false,
},
minLength: {
type: Number,
required: false,
},
});
const el = ref();

View File

@@ -2,6 +2,15 @@
<div v-if="!inline" class="form-control w-full">
<label class="label">
<span class="label-text"> {{ label }} </span>
<span
:class="{
'text-red-600':
typeof value === 'string' &&
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
}"
>
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
</span>
</label>
<input
ref="input"
@@ -15,6 +24,15 @@
<div v-else class="sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
<label class="label">
<span class="label-text"> {{ label }} </span>
<span
:class="{
'text-red-600':
typeof value === 'string' &&
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
}"
>
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
</span>
</label>
<input v-model="value" :placeholder="placeholder" class="input input-bordered col-span-3 mt-2 w-full" />
</div>
@@ -50,6 +68,14 @@
type: String,
default: "",
},
maxLength: {
type: Number,
required: false,
},
minLength: {
type: Number,
required: false,
},
});
const input = ref<HTMLElement | null>(null);

View File

@@ -3,8 +3,16 @@
<template #title> {{ $t("components.item.create_modal.title") }} </template>
<form @submit.prevent="create()">
<LocationSelector v-model="form.location" />
<FormTextField ref="nameInput" v-model="form.name" :trigger-focus="focused" :autofocus="true" label="Item Name" />
<FormTextArea v-model="form.description" label="Item Description" />
<FormTextField
ref="nameInput"
v-model="form.name"
:trigger-focus="focused"
:autofocus="true"
label="Item Name"
:max-length="255"
:min-length="1"
/>
<FormTextArea v-model="form.description" label="Item Description" :max-length="1000" />
<FormMultiselect v-model="form.labels" label="Labels" :items="labels ?? []" />
<div class="modal-action mb-6">

View File

@@ -8,8 +8,10 @@
:trigger-focus="focused"
:autofocus="true"
label="Label Name"
:max-length="255"
:min-length="1"
/>
<FormTextArea v-model="form.description" label="Label Description" />
<FormTextArea v-model="form.description" label="Label Description" :max-length="255" />
<div class="modal-action">
<div class="flex justify-center">
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> {{ $t("global.create") }} </BaseButton>

View File

@@ -9,8 +9,10 @@
:autofocus="true"
:required="true"
label="Location Name"
:max-length="255"
:min-length="1"
/>
<FormTextArea v-model="form.description" label="Location Description" />
<FormTextArea v-model="form.description" label="Location Description" :max-length="1000" />
<LocationSelector v-model="form.parent" />
<div class="modal-action">
<div class="flex justify-center">

View File

@@ -96,6 +96,8 @@
label: string;
// key of ItemOut where the value is a string
ref: keyof OnlyString<NoUndefinedField<ItemOut>>;
maxLength?: number;
minLength?: number;
};
type NumberFormField = {
@@ -131,6 +133,8 @@
type: "text",
label: "Name",
ref: "name",
maxLength: 255,
minLength: 1,
},
{
type: "number",
@@ -141,26 +145,31 @@
type: "textarea",
label: "Description",
ref: "description",
maxLength: 1000,
},
{
type: "text",
label: "Serial Number",
ref: "serialNumber",
maxLength: 255,
},
{
type: "text",
label: "Model Number",
ref: "modelNumber",
maxLength: 255,
},
{
type: "text",
label: "Manufacturer",
ref: "manufacturer",
maxLength: 255,
},
{
type: "textarea",
label: "Notes",
ref: "notes",
maxLength: 1000,
},
{
type: "checkbox",
@@ -184,6 +193,7 @@
type: "text",
label: "Purchased From",
ref: "purchaseFrom",
maxLength: 255,
},
{
type: "text",
@@ -214,6 +224,7 @@
type: "textarea",
label: "Warranty Notes",
ref: "warrantyDetails",
maxLength: 1000,
},
];
@@ -222,6 +233,7 @@
type: "text",
label: "Sold To",
ref: "soldTo",
maxLength: 255,
},
{
type: "text",
@@ -480,12 +492,21 @@
<div class="border-t border-gray-300 sm:p-0">
<div v-for="field in mainFields" :key="field.ref" class="grid grid-cols-1 sm:divide-y sm:divide-gray-300">
<div class="border-b border-gray-300 px-4 pb-4 pt-2 sm:px-6">
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
<FormTextArea
v-if="field.type === 'textarea'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'text'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'number'"
@@ -522,7 +543,7 @@
<!-- <FormSelect v-model:value="field.type" label="Field Type" :items="fieldTypes" value-key="value" /> -->
<FormTextField v-model="field.name" label="Name" />
<div class="col-span-3 flex items-end">
<FormTextField v-model="field.textValue" label="Value" />
<FormTextField v-model="field.textValue" label="Value" :max-length="500" />
<div class="tooltip" data-tip="Delete">
<button class="btn btn-square btn-sm mb-2 ml-2" @click="item.fields.splice(idx, 1)">
<MdiDelete />
@@ -604,12 +625,21 @@
class="grid grid-cols-1 sm:divide-y sm:divide-gray-300"
>
<div class="border-b border-gray-300 px-4 pb-4 pt-2 sm:px-6">
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
<FormTextArea
v-if="field.type === 'textarea'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'text'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'number'"
@@ -646,12 +676,21 @@
class="grid grid-cols-1 sm:divide-y sm:divide-gray-300"
>
<div class="border-b border-gray-300 px-4 pb-4 pt-2 sm:px-6">
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
<FormTextArea
v-if="field.type === 'textarea'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'text'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'number'"
@@ -684,12 +723,21 @@
<div class="border-t border-gray-300 sm:p-0">
<div v-for="field in soldFields" :key="field.ref" class="grid grid-cols-1 sm:divide-y sm:divide-gray-300">
<div class="border-b border-gray-300 px-4 pb-4 pt-2 sm:px-6">
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
<FormTextArea
v-if="field.type === 'textarea'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'text'"
v-model="item[field.ref]"
:label="field.label"
inline
:max-length="field.maxLength"
:min-length="field.minLength"
/>
<FormTextField
v-else-if="field.type === 'number'"

View File

@@ -97,8 +97,14 @@
<BaseModal v-model="updateModal">
<template #title> Update Label </template>
<form v-if="label" @submit.prevent="update">
<FormTextField v-model="updateData.name" :autofocus="true" label="Label Name" />
<FormTextArea v-model="updateData.description" label="Label Description" />
<FormTextField
v-model="updateData.name"
:autofocus="true"
label="Label Name"
:max-length="255"
:min-length="1"
/>
<FormTextArea v-model="updateData.description" label="Label Description" :max-length="255" />
<div class="modal-action">
<BaseButton type="submit" :loading="updating"> Update </BaseButton>
</div>

View File

@@ -111,8 +111,8 @@
<BaseModal v-model="updateModal">
<template #title> Update Location </template>
<form v-if="location" @submit.prevent="update">
<FormTextField v-model="updateData.name" :autofocus="true" label="Location Name" />
<FormTextArea v-model="updateData.description" label="Location Description" />
<FormTextField v-model="updateData.name" :autofocus="true" label="Location Name" :max-length="255" :min-length="1" />
<FormTextArea v-model="updateData.description" label="Location Description" :max-length="1000" />
<LocationSelector v-model="parent" />
<div class="modal-action">
<BaseButton type="submit" :loading="updating"> Update </BaseButton>