Ali Akbar
Ali Akbar

Reputation: 141

How to add form validation in svelte

I am a svelte and js newbie. I'm trying to add validation to my forms which I've been using to send the data to firebase but I'm getting a very hard time to do so. I am taking a name and a email. I don't want to mask the email or anything special just if there's empty values going then it should tell that would be enough. If anyone know's how to do it then please let me know. Here's my code

<script>
  import tilt from "svelte-tilt";
  import { ConfettiExplosion } from "svelte-confetti-explosion";
  import { clickOutside } from "./clickOutside.js";
  import { Router, Route, Link } from "svelte-routing";
  import Privacy from "../routes/privacy.svelte";
  import { db } from "../firebase/config";
  import { collection, doc, setDoc } from "firebase/firestore";
  let data = [
"Test Data","Test"Data"
  ];
  let isVisible = false;
  let openModel = false;
  const toggleModel = () => {
    openModel = !openModel;
    if (openModel === true) {
      isVisible = true;
    }
  };
  let userName = "";
  let userMail = "";
  let addData = async () => {
    const Data = collection(db, "waitlist users");
    try {
      await setDoc(doc(Data), {
        name: userName,
        email: userMail,
      });
      toggleModel();
    } catch (error) {
      console.log(error);
    }
  };
</script>

<section class="bg lg:py-24">
  <main
    class="w-full px-3 py-4 2xl:container mx-auto flex-col-reverse lg:flex-row flex justify-between items-center"
  >
    <div class=" w-full lg:w-[30%] grid grid-cols-1 gap-5 px-4">
      {#each data as item, index}
        <div
          class="glass shadow-md  flex justify-center items-center w-full h-36 p-4"
          use:tilt
        >
          {#if index === 0}
            <p class="font-bold text-[#92A0EB]">
              {item}
            </p>
          {:else if index === 1}
            <p class="font-bold text-[#C3A7E6]">
              {item}
            </p>
          {:else}
            <p class="font-bold text-[#91C0E4]">
              {item}
            </p>
          {/if}
        </div>
      {/each}
    </div>
    <div class="w-full lg:w-[70%] text-white flex justify-center">
      <main class="max-w-xl text-center pt-14 lg:pt-0">
        <div>
          <h1 class="text-3xl md:text-5xl capitalize font-bold">
            Way to Go!
          </h1>
        </div>
        <p class=" text-base sm:ext-2xl">
          Join now:
        </p>
        <form class="py-12">
          <div>
            <label
              for="name"
              class="block mb-1 text-left font-semibold text-sm ">Name</label
            >
            <input
              type="text"
              id="name"
              required
              bind:value={userName}
              class="input"
              placeholder="John Doe"
            />
          </div>
          <div>
            <label
              for="email"
              class="block mb-1 mt-2 text-left font-semibold text-sm "
              >Email</label
            >
            <input
              type="email"
              id="email"
              required
              bind:value={userMail}
              class="input"
              placeholder="[email protected]"
            />
          </div>
          <Router>
            <p
              class="mt-2 text-[10px] sm:text-sm text-gray-700 text-right mb-1"
            >
              We’ll never share your details. Read our
              <Link to="/privacy">
                <!-- svelte-ignore a11y-missing-attribute -->
                <a
                  class="font-medium text-transparent bg-clip-text hover:underline bg-gradient-to-r from-purple-400 to-[#92a0eb]"
                >
                  Privacy Policy.
                </a>
              </Link>
            </p>
            <Route path="/privacy">
              <Privacy />
            </Route>
          </Router>
          <div class=" flex justify-end">
            <button
              on:click|preventDefault={addData}
              class="text-white bg-gradient-to-r from-[#aac0f1] via-[#aac0f1] to-#eac3ed border hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-[#aac0f1] shadow-lg shadow-[#aac0f1]  font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 "
              >Join</button
            >
          </div>
        </form>
      </main>
    </div>
    {#if openModel}
      <div
        class=" w-full h-screen top-0 left-0 right-0 fixed z-50 bg-black/70 "
      >
        <main class=" flex justify-center items-center w-full h-full relative">
          <div
            use:clickOutside
            on:click_outside={toggleModel}
            class="bg-white p-16 sm:p-20 text-center rounded-lg"
          >
            <h1 class=" font-bold text-2xl">Congratulation</h1>
            {#if isVisible}
              <ConfettiExplosion particleCount={200} force={0.3} />
            {/if}
            <p>Your request has been submitted</p>
          </div>
        </main>
      </div>
    {/if}
  </main>
</section>

Upvotes: 0

Views: 2788

Answers (2)

brunnerh
brunnerh

Reputation: 185280

You do not need any JS for basic form validation. In this case you just have to use the form properly by handling its submit event and setting required attributes on the input elements.

E.g.

<script>
    let name;
    let email;

    function onSubmit() {
        alert(`submitted: ${name} - ${email}`)
    }
</script>

<form id="form" on:submit|preventDefault={onSubmit}>
    <label>Name <input bind:value={name} required/></label>
    <label>E-Mail <input bind:value={email} type="email" required/></label>
</form>

<button form="form">Submit</button>

REPL example

Setting the type of the e-mail input to email adds additional validation on its content. If the button that submits the form is outside of the form element, you can associate it with the form using its form attribute, which has to contain the id of the form element.

The submit event of the form only gets triggered if the form is actually valid.

Upvotes: 1

Ahmad Hassan
Ahmad Hassan

Reputation: 588

Actually its quite easy you can do it using plain js logic, no need to think about its svelte based or anything else. Make a function in your script

function validation_check(userName, userMail) {
    if (userName === "") {
      return false;
    } else if (userMail === "") {
      return false;
    } else {
      return true;
    }
  }

Then make condition on button using the above function

 {#if openModel}
          <div
            class=" w-full h-screen top-0 left-0 right-0 fixed z-50 bg-black/70 "
          >
            <main
              class=" flex justify-center items-center w-full h-full relative"
            >
              <div
                use:clickOutside
                on:click_outside={toggleModel}
                class="bg-white p-16 sm:p-20 text-center rounded-lg"
              >
                <h1 class=" font-bold text-2xl">Congratulation</h1>
                {#if isVisible}
                  <ConfettiExplosion particleCount={200} force={0.3} />
                {/if}
                <p>Your request has been submitted</p>
              </div>
            </main>
          </div>
        {/if}
      {:else}
        <div class="flex justify-end">
          <p
            class="text-white bg-gradient-to-r from-[#aac0f1] via-[#aac0f1] to-#eac3ed border hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-[#aac0f1] shadow-lg shadow-[#aac0f1]  font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 "
          >
            Fill in all the details.
          </p>
        </div>
      {/if}

That's all your validation will work just fine

Upvotes: 1

Related Questions