'Svelte - Form submission and action
I am trying to submit a form using svelte and yup. Whenever the form is submitted, the information must be send into the action part of the form (a CGI on a cgi-bin folder). It has been replaced now by stackoverflow url for debugging purpose.
<script>
import { createForm } from 'svelte-forms-lib';
import * as yup from "yup";
const phoneRegExp = /^(?:(?:\+|00)32[\s.-]{0,3}(?:\(0\)[\s.-]{0,3})?|0)((?:(?:[\s.-]?\d{2}){1})|(?:(?:[\s.-]?\d{3}){1}))((?:[\s.-]?\d{2}){3}|(?:[\s.-]?\d{3}){2})$/
const { form, errors, state,touched,isValid,isSubmitting,isValidating, handleChange, handleSubmit } = createForm({
initialValues: {
name: '',
email: '',
phone: '',
availability: ' ',
vieprivee: false,
},
validationSchema: yup.object().shape({
name: yup
.string()
.required("Name is required")
.min(3, "Name is too short"),
email: yup
.string()
.email("Format is invalid")
.when('phone',{
is:(phone) => !phone || phone.length ===0,
then: yup.string().email().required().default(''),
otherwise:yup.string().default('')
}),
phone: yup
.string()
.when('email',{
is:(email) => !email || email.length === 0,
then: yup
.string()
.matches(phoneRegExp, "Format is invalid")
.required()
.default(''),
otherwise: yup.string().default('')
}),
vieprivee: yup
.bool()
.required("Consent is required")
.oneOf([true],"Consent is required"),
availability: yup
.mixed()
.notRequired()
.default(" "),
},[['email','phone']]),
validate: (values) => {
alert(JSON.stringify(values));
}
onSubmit: values => {
alert(JSON.stringify(values));
}
});
</script>
<style>
.hide { position:absolute; top:-1px; left:-1px; width:1px; height:1px; }
</style>
<iframe name="hiddenFrame" class="hide"></iframe>
<form action="http://stackoverflow.com" target="hiddenFrame" id="formContact" on:submit={handleSubmit} class:valid={$isValid}>
<!-- action="./cgi-bin/feedback_form.cgi" method="post" -->
<div id="veterinexpowin" />
<label for="name">Name</label>
<input
id="name"
name="name"
on:keyup={handleChange}
on:blur={handleChange}
bind:value={$form.name} />
{#if $errors.name && $touched.name}<small>{$errors.name}</small>{/if}
<label for="phone">Phone</label>
<input
id="phone"
name="phone"
on:keyup={handleChange}
on:blur={handleChange}
bind:value={$form.phone} />
{#if $errors.phone && $touched.phone}<small>{$errors.phone}</small>{/if}
<label for="email">Email</label>
<input
id="email"
name="email"
on:keyup={handleChange}
on:blur={handleChange}
bind:value={$form.email} />
{#if $errors.email && $touched.email}<small>{$errors.email}</small>{/if}
<label for="availability">Comments / Availability</label>
<textarea
id="availability"
name="availability"
on:keyup={handleChange}
on:blur={handleChange}
bind:value={$form.availability} />
{#if $errors.availability && $touched.availability}<small>{$errors.availability}</small>{/if}
<br>
<input
type="checkbox"
id="vieprivee"
name="vieprivee"
class="checkboxvieprivee"
on:change={handleChange}
on:blur={handleChange}
bind:value={$form.vieprivee}/>
<label for="vieprivee"><span class="spanvieprivee">I read and understand the <a href="PolitiqueViePriveeByVets.pdf" target="_blank"> GDPR</a> <br/>
and I accept it.</span></label>
{#if $errors.vieprivee}<small>{$errors.vieprivee}</small>{/if}
<button
id="contactButton"
type="submit"
class="contactButton"
disabled={!$isValid}
value="Submit">
Send
</button>
</form>
- The first field is for the name and is required.
- The second field is for the phone and is only required if the third field(mail) is not filled in.
- The third field is for the mail. It is only required if the second field(phone) is not filled in.
- The fourth field is for the comments or the availability. It is not mandatory.
- The last field is a checkbox. It must be checked to submit the form.
My error is that the action is not triggered. I'm not sure how to debug that.
Thanks for yout help
Solution 1:[1]
So after playing around with the 'on:submit' tag I found that leaving the handleSubmit only in the button was working. and calling as expected my CGI.
Solution 2:[2]
You can use:
event.stopPropagation();
event.preventDefault();
Example Svelte Component:
<script>
function validate(event) {
let valid = true;
// perform validation here...
// set validate to false as necessary
if (!valid) {
event.stopPropagation();
event.preventDefault();
}
}
</script>
<main>
<form method="post" action="/path/to/post" on:submit={(e) => validate(e)}>
<label for="email">Email:</label><br />
<input type="text" id="email" name="email" value="" /><br />
<input type="submit" value="Submit" />
</form>
</main>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Charley |
| Solution 2 | Evan Closson |
