项目作者: cloudedots-projects

项目描述 :
Svelte Forms Library with Validation.
高级语言: TypeScript
项目地址: git://github.com/cloudedots-projects/svelte-forms.git
创建时间: 2021-04-30T13:04:30Z
项目社区:https://github.com/cloudedots-projects/svelte-forms

开源协议:MIT License

下载


This package has been deprecatedin favour of svelte-form-validation

Welcome to @cloudedots/svelte-forms 👋

NPM Version

Svelte Forms Library

🏠 Homepage

Install

  1. npm install @cloudedots/svelte-forms yup

This package uses Yup for validation.

Basic Usage Example

demo/Basic.svelte :

  1. <script>
  2. import { createForm } from "@cloudedots/svelte-forms";
  3. import * as yup from "yup";
  4. // Create Form Instance
  5. const { form, formControl, isValid } = createForm({
  6. // Initial Form Data
  7. initialValues: {
  8. email: "",
  9. password: "",
  10. },
  11. // Form Validation using Yup
  12. validationSchema: yup.object().shape({
  13. email: yup.string().email().required(),
  14. password: yup.string().min(6).required(),
  15. }),
  16. });
  17. const onSubmit = () => {
  18. // "$form" contains current Form Data
  19. console.log($form);
  20. };
  21. </script>
  22. <form on:submit|preventDefault="{onSubmit}">
  23. <input type="text" name="email" bind:value="{$form.email}" use:formControl />
  24. <input
  25. type="password"
  26. name="password"
  27. bind:value="{$form.password}"
  28. use:formControl
  29. />
  30. <button type="submit" disabled="{!$isValid}">Submit</button>
  31. </form>

Full Usage Example

demo/Full.svelte :

  1. <script lang="ts">
  2. import { createForm } from "@cloudedots/svelte-forms";
  3. import * as yup from "yup";
  4. import UserAddressForm from "./UserAddressForm.svelte"; // Components
  5. // (Optional) Form's Data type will be automatically inferred from "initialValues" in "createForm" if type of Data is not specified
  6. type FormData = {
  7. title: string,
  8. description: string,
  9. coverImage: FileList,
  10. users: {
  11. name: string,
  12. email: string,
  13. address: {
  14. state: string,
  15. city: string,
  16. },
  17. }[],
  18. };
  19. // Create Form Instance
  20. const {
  21. form, // Svelte Store<FormData> containing Form Data
  22. state, // Svelte Store<FormState> containing Form State - { [every_property]: { _touched: boolean, _errors: string[] }}
  23. isValid, // Svelte Store<boolean> containing entire Form's validation status
  24. isTouched, // Svelte Store<boolean> containing entire Form's touched status
  25. validateForm, // Function(highlight: 'none' | 'errors' | 'all' = 'none') for manually validting entire form
  26. handleChange, // Function(event: Event) to manually updating individual form control's state - can be used in place of "formControl" Action
  27. setTouched, // Function() for manually setting Form state as "touched"
  28. updateForm, // Function() for updating Form's Structure after Form Controls are Added or Removed in cases like Form Arrays
  29. formControl, // Svelte Action to be used with <input>, <select>, <textarea> or similar HTML input elements
  30. resetForm, // Reset the Form with optional new value and clear validation
  31. } = createForm<FormData>({
  32. // Initial Values of Form
  33. initialValues: {
  34. title: "", // Simple String
  35. description: "", // Simple String
  36. coverImage: "", // File Input
  37. users: [], // Complex Form Array
  38. },
  39. // Yup Validation Schema
  40. validationSchema: yup.object().shape({
  41. title: yup.string().min(8).required(),
  42. description: yup.string(),
  43. coverImage: yup.mixed().test(value => value?.length > 0), // Custom validation because yup does not suport file objects
  44. users: yup.array().of({
  45. name: yup.string().required(),
  46. email: yup.string().email().required(),
  47. address: yup.object().shape({
  48. state: yup.string().required(),
  49. city: yup.string(),
  50. }),
  51. }),
  52. }),
  53. // CSS class validations
  54. css: {
  55. enabled: true, // use CSS classes or not
  56. validClass: "is-valid", // CSS class added to valid form controls
  57. invalidClass: "is-invalid", // CSS class added to invalid form controls
  58. useValid: true, // Add CSS classes to valid form controls
  59. useInvalid: true, // Add CSS classes to invalid form controls
  60. },
  61. validateOnChange: true, // Whether to validate on "change" event of element and form value change
  62. validateOnBlur: true, // Whether to validate on "blur" event of element
  63. });
  64. // Add new user to Users Form Array
  65. const addUser = () => {
  66. // Update Form Data
  67. $form.users = [
  68. ...$form.users,
  69. {
  70. name: "",
  71. email: "",
  72. address: {
  73. state: "",
  74. city: "",
  75. },
  76. },
  77. ];
  78. updateForm(); // Manually trigger Form Update - Required
  79. };
  80. // Remove user from Users Form Array
  81. const removeUser = (index) => () => {
  82. $form.users = $form.users.filter((_, i) => i !== index); // Update Form Data
  83. $state.users = $state.users.filter((_, i) => i !== index); // Updating State is required after removing Form Controls
  84. updateForm(); // Manually trigger Form Update - Required
  85. };
  86. // Submit Form
  87. const onSubmit = () => {
  88. console.log($form); // Get Form Data
  89. // Reset form after submit
  90. resetForm({
  91. title: "",
  92. description: "",
  93. coverImage: "",
  94. users: [],
  95. });
  96. };
  97. $: console.log($form, $state); // Log Form Data and Form State on every Change
  98. </script>
  99. <form on:submit|preventDefault={onSubmit}>
  100. <input
  101. placeholder="Title"
  102. name="title"
  103. bind:value={$form.title}
  104. use:formControl
  105. />
  106. {#if $state.title._errors?.length}
  107. {#each $state.title._errors as error}
  108. <span class="error">{error}</span>
  109. {/each}
  110. {/if}
  111. <input
  112. placeholder="Description"
  113. name="description"
  114. bind:value={$form.description}
  115. use:formControl
  116. />
  117. {#if $state.description._errors?.length}
  118. {#each $state.description._errors as error}
  119. <span class="error">{error}</span>
  120. {/each}
  121. {/if}
  122. <input
  123. name="coverImage"
  124. accept="image/*"
  125. bind:files={$form.coverImage}
  126. use:formControl
  127. />
  128. {#if $state.coverImage._errors?.length}
  129. {#each $state.coverImage._errors as error}
  130. <span class="error">{error}</span>
  131. {/each}
  132. {/if}
  133. {#if $form.coverImage?.length}
  134. <div class="image-preview">
  135. <img
  136. src={URL.createObjectURL($form.coverImage[0])}
  137. alt="Cover"
  138. height="150" />
  139. </div>
  140. {/if}
  141. {#each $form.users as user, index}
  142. <h2>
  143. User {user.name}
  144. <button type="button" on:click={removeUser(i)}>
  145. Remove User
  146. </button>
  147. </h2>
  148. <input
  149. placeholder="name"
  150. name="users[{index}].name"
  151. bind:value={user.name}
  152. use:formControl
  153. />
  154. {#if $state.users[index].name._errors?.length}
  155. {#each $state.users[index].name._errors as error}
  156. <span class="error">{error}</span>
  157. {/each}
  158. {/if}
  159. <input
  160. placeholder="email"
  161. name="users[{index}].email"
  162. bind:value={user.email}
  163. use:formControl
  164. />
  165. {#if $state.users[index].email._errors?.length}
  166. {#each $state.users[index].email._errors as error}
  167. <span class="error">{error}</span>
  168. {/each}
  169. {/if}
  170. <!-- Using with Components -->
  171. <UserAddressForm {form} {state} {formControl} {index} ></UserAddressForm>
  172. {/each}
  173. <button type="button" on:click={addUser}>
  174. Add User
  175. </button>
  176. <button type="button" on:click={() => validateForm('errors')}>
  177. Validate Form
  178. </button>
  179. <button type="submit" disabled={!$isValid}>
  180. Submit
  181. </button>
  182. </form>
  183. <style>
  184. .valid {
  185. border: 1px solid green;
  186. }
  187. .invalid {
  188. border: 1px solid red;
  189. }
  190. .error {
  191. color: red;
  192. }
  193. </style>

demo/UserAddressForm.svelte :

  1. <script lang="ts">
  2. export let form: any;
  3. export let state: any;
  4. export let formControl;
  5. export let index: number;
  6. </script>
  7. <input
  8. type="text"
  9. placeholder="State"
  10. bind:value="{$form.users[index].address.state}"
  11. name="users[{index}].address.state"
  12. use:formControl
  13. />
  14. {#if $state.users[index].address.state._errors?.length} {#each
  15. $state.users[index].address.state._errors as error}
  16. <span class="error">{error}</span>
  17. {/each} {/if}
  18. <input
  19. type="text"
  20. placeholder="City"
  21. bind:value="{$form.users[index].address.city}"
  22. name="users[{index}].address.city"
  23. use:formControl
  24. />
  25. {#if $state.users[index].address.city._errors?.length} {#each
  26. $state.users[index].address.city._errors as error}
  27. <span class="error">{error}</span>
  28. {/each} {/if}

🤝 Contributing

Contributions, issues and feature requests are welcome!

Feel free to check issues page.

Show your support

Give a ⭐️ if this project helped you!

📝 License

Copyright © 2021 Cloudedots contact@cloudedots.com.

This project is MIT licensed.