add InputField select option & input validation

This commit is contained in:
Alex
2024-09-29 21:27:57 +02:00
parent f7c1ad2b8e
commit 797aca3bb1

View File

@@ -8,12 +8,21 @@
/** @type {string} */ /** @type {string} */
export let type = "text"; export let type = "text";
/** @type {string} */ /** @type {string|Number|null} */
export let value = ""; export let value;
/** @type {string} */ /** @type {string} */
export let placeholder = ""; export let placeholder = "";
/** @type {Number} */
export let rows = 4;
/** @type {Array<{value: string | number, label: string, color?:string}>} */
export let options = [];
/** @type {Boolean} */
export let required = false;
/** @type {string} */ /** @type {string} */
export let label = ""; export let label = "";
@@ -23,8 +32,6 @@
/** @type {boolean} */ /** @type {boolean} */
export let toUpperCase = false; export let toUpperCase = false;
const dispatch = createEventDispatcher();
/** /**
* @param {Event} event - The input event * @param {Event} event - The input event
*/ */
@@ -38,60 +45,68 @@
target.value = inputValue; // Update the input field value target.value = inputValue; // Update the input field value
} }
value = inputValue; value = inputValue;
// dispatch("input", { name, value: inputValue });
} }
} }
/** /**
* Validates the field * Validates the field
* @param {string} name - The name of the field * @param {string} name - The name of the field
* @param {string} value - The value of the field * @param {string|Number|null} value - The value of the field
* @param {Boolean} required - The requirements of the field
* @returns {string|null} The error message or null if valid * @returns {string|null} The error message or null if valid
*/ */
function validateField(name, value) { function validateField(name, value, required) {
if (
value === null ||
(typeof value === "string" && !value.trim() && !required)
)
return null;
switch (name) { switch (name) {
case "first_name":
case "last_name":
case "address":
case "city":
case "account_holder_name":
case "bank":
return value.trim() ? null : $t("required");
case "birth_date":
case "membership_start_date": case "membership_start_date":
return value.trim() ? null : $t("required_date"); return typeof value === "string" && value.trim()
? null
: $t("validation.date");
case "email": case "email":
return /^\S+@\S+\.\S+$/.test(value) ? null : $t("invalid_email"); return typeof value === "string" && /^\S+@\S+\.\S+$/.test(value)
? null
: $t("validation.email");
case "password": case "password":
case "password2": case "password2":
if (!value.trim()) { if (typeof value === "string" && value.length < 8) {
return null; return $t("validation.password");
}
if (value.length < 8) {
return $t("required_password");
} }
if (otherPasswordValue && value !== otherPasswordValue) { if (otherPasswordValue && value !== otherPasswordValue) {
return $t("required_password_match"); return $t("validation.password_match");
} }
return null; return null;
case "phone": case "phone":
return /^\+?[0-9\s()-]{7,}$/.test(value) ? null : $t("invalid_phone"); return typeof value === "string" && /^\+?[0-9\s()-]{7,}$/.test(value)
? null
: $t("validation.phone");
case "zip_code": case "zip_code":
return /^\d{5}$/.test(value) ? null : $t("invalid_zip_code"); return typeof value === "string" && /^\d{5}$/.test(value)
? null
: $t("validation.zip_code");
case "iban": case "iban":
return /^[A-Z]{2}\d{2}[A-Z0-9]{1,30}$/.test(value) return typeof value === "string" &&
/^[A-Z]{2}\d{2}[A-Z0-9]{1,30}$/.test(value)
? null ? null
: $t("invalid_iban"); : $t("validation.iban");
case "bic": case "bic":
return /^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$/.test(value) return typeof value === "string" &&
/^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$/.test(value)
? null ? null
: $t("invalid_bic"); : $t("validation.bic");
default: default:
return null; return typeof value === "string" && !value.trim() && required
? $t("validation.required")
: null;
} }
} }
$: error = validateField(name, value); $: error = validateField(name, value, required);
$: selectedOption = options.find((option) => option.value == value);
$: selectedColor = selectedOption ? selectedOption.color : "";
</script> </script>
<div class="input-box"> <div class="input-box">
@@ -100,22 +115,49 @@
{#if error} {#if error}
<span class="error-message">{error}</span> <span class="error-message">{error}</span>
{/if} {/if}
{#if type === "select"}
<select
{name}
bind:value
{required}
class="input select"
style={selectedColor ? `color: ${selectedColor};` : ""}
>
{#each options as option}
<option value={option.value}>{option.label}</option>
{/each}
</select>
{:else if type === "textarea"}
<textarea
{name}
{placeholder}
{required}
{value}
{rows}
class="input textarea"
style="height:{rows * 1.5}em;"
/>
{:else}
<input <input
{name} {name}
{type} {type}
{placeholder} {placeholder}
{value} {value}
{required}
on:input={handleInput} on:input={handleInput}
on:blur={handleInput} on:blur={handleInput}
class="input" class="input"
/> />
{/if}
</div> </div>
</div> </div>
<style> <style>
.select {
padding-right: 1.5em;
}
.input-error-container { .input-error-container {
display: flex; display: flex;
flex-direction: column;
align-items: flex-end; align-items: flex-end;
width: 100%; width: 100%;
max-width: 444px; max-width: 444px;
@@ -131,4 +173,17 @@
.input { .input {
width: 100%; width: 100%;
} }
input,
textarea,
select {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
color: white;
}
textarea {
resize: vertical;
min-height: 100px;
}
</style> </style>