Search code examples
javascripttoastbuttonclick

I want to add an button onclick function, to add several toasts in javascript


I have a form. And I want to write an onClick function which whenever is clicked, a toast including inputs value appears at the end of the page. here I wrote a function that produce a toast just on the first click.

function Function1() {
  var y = document.getElementsByTagName("select")[0].value;
  var z = document.getElementsByTagName("input")[0].value;
  var x = document.getElementById("toast1");

  x.innerHTML = y + " has a " + z + "<span >&times;</span>";
  x.className = "show";
}
<form class="needs-validation" novalidate>
  <h5>Select the owner?</h5>
  <div class="form-group col mx-auto" style="width: 80%;">
    <label for="validationDefault01" class="sr-only">households</label>
    <select
      class="custom-select place-holder form-control form-control-lg OwnerName"
      style="font-size: 15px;"
      id="validationDefault01"
      style="border-radius: 2px;"
      required
    >
      <option value="" selected hidden>Choose...</option>
      <option value="Jack London"> Jack London</option>
      <option value="Sarah London"> Sarah London</option>
      <option value="Mike"> Mike</option>
    </select>
  </div>
  <br />
  <h5>What is the brand?</h5>
  <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
    <label for="validationCustom01" class="sr-only">Brand</label>
    <input
      class="form-control brand"
      type="text"
      required
      id="validationCustom01"
      style="font-size: 15px; height: 40px;"
      placeholder="Brand"
    />
    <div class="valid-feedback">correct</div>
  </div>
  <br />
  <h5>What is the model year?</h5>
  <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
    <label for="validationCustom01" class="sr-only">yyyy</label>
    <input
      class="form-control"
      type="text"
      required
      id="validationCustom01"
      style="font-size: 15px; height: 40px;"
      onkeypress="return CheckNumeric()"
      placeholder="yyyy"
    />
    <div class="valid-feedback">correct</div>
  </div>
  <br />
  <h5 class="mx-2">How much is worth?</h5>
  <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
    <div class="input-group-prepend">
      <div
        class="input-group-text font-weight-bold"
        style="
          font-size: 15px;
          background-color: rgba(50, 157, 105, 1);
          color: white;
        "
      >
        $
      </div>
    </div>
    <label for="validationDefault01" class="sr-only">deposite</label>
    <input
      type="text"
      class="form-control floatNumber"
      id="validationDefault01"
      style="font-size: 15px;"
      onkeypress="return CheckNumeric()"
      onkeyup="FormatCurrency(this)"
      placeholder="example: 10000"
      required
    />
  </div>
  <p id="demo"></p>
  <br />
  <div class="row">
    <div class="col">
      <button
        class="quebtn1 mx-auto"
        style="width: 130px;"
        type="button"
        onclick="Function1()"
      >
        Add Vehicle
      </button>
    </div>
  </div>
  <div class="row">
    <div class="col-6">
      <button class="quebtn1 float-right" type="button">Back</button>
    </div>
    <div class="col-6">
      <button class="quebtn1" type="submit">Next</button>
      <br />
    </div>
    <div class="row pt-0 mx-auto text-center">
      <div
        class="toast-body toast no-gutters"
        data-autohide="false"
        role="alert"
        aria-live="assertive"
        aria-atomic="true"
        id="toast1"
      ></div>
    </div>
  </div>
</form>

But I want when user fill the form and click on "add vehicle" button to add another vehicle again and again, each time a toast including information of the previous vehicle user added, produce.


Solution

  • To understand why you aren't getting the results you're looking for, you have to understand the DOM. Currently, whenever the button is clicked, you are always changing the same DOM element.

    var x = document.getElementById("toast1");
    
    x.innerHTML = y + " has a " + z + "<span >&times;</span>";
    x.className = "show";
    

    See how you're selecting the element with the ID of toast1 and manipulating that element every time by setting its innerHTML and className?

    What you want to do is create a new element, and place that new element underneath the element with the ID of toast1.

    To create an new element, you would use createElement:

    var newEl = document.createElement("p");
    
    newEl.innerHTML = y + " has a " + z + "<span >&times;</span>";
    newEl.className = "show";
    

    And then to insert it use appendChild:

    x.appendChild(newEl);
    

    Here's the complete code:

    function Function1() {
      var y = document.getElementsByTagName("select")[0].value;
      var z = document.getElementsByTagName("input")[0].value;
      var x = document.getElementById("toast1");
      var newEl = document.createElement("div");
    
      newEl.innerHTML = y + " has a " + z + "<span >&times;</span>";
      newEl.className = "show";
      x.appendChild(newEl);
    }
    <form class="needs-validation" novalidate>
      <h5>Select the owner?</h5>
      <div class="form-group col mx-auto" style="width: 80%;">
        <label for="validationDefault01" class="sr-only">households</label>
        <select
          class="custom-select place-holder form-control form-control-lg OwnerName"
          style="font-size: 15px;"
          id="validationDefault01"
          style="border-radius: 2px;"
          required
        >
          <option value="" selected hidden>Choose...</option>
          <option value="Jack London"> Jack London</option>
          <option value="Sarah London"> Sarah London</option>
          <option value="Mike"> Mike</option>
        </select>
      </div>
      <br />
      <h5>What is the brand?</h5>
      <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
        <label for="validationCustom01" class="sr-only">Brand</label>
        <input
          class="form-control brand"
          type="text"
          required
          id="validationCustom01"
          style="font-size: 15px; height: 40px;"
          placeholder="Brand"
        />
        <div class="valid-feedback">correct</div>
      </div>
      <br />
      <h5>What is the model year?</h5>
      <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
        <label for="validationCustom01" class="sr-only">yyyy</label>
        <input
          class="form-control"
          type="text"
          required
          id="validationCustom01"
          style="font-size: 15px; height: 40px;"
          onkeypress="return CheckNumeric()"
          placeholder="yyyy"
        />
        <div class="valid-feedback">correct</div>
      </div>
      <br />
      <h5 class="mx-2">How much is worth?</h5>
      <div class="input-group mx-auto" style="border-radius: 8px; width: 75%;">
        <div class="input-group-prepend">
          <div
            class="input-group-text font-weight-bold"
            style="
              font-size: 15px;
              background-color: rgba(50, 157, 105, 1);
              color: white;
            "
          >
            $
          </div>
        </div>
        <label for="validationDefault01" class="sr-only">deposite</label>
        <input
          type="text"
          class="form-control floatNumber"
          id="validationDefault01"
          style="font-size: 15px;"
          onkeypress="return CheckNumeric()"
          onkeyup="FormatCurrency(this)"
          placeholder="example: 10000"
          required
        />
      </div>
      <p id="demo"></p>
      <br />
      <div class="row">
        <div class="col">
          <button
            class="quebtn1 mx-auto"
            style="width: 130px;"
            type="button"
            onclick="Function1()"
          >
            Add Vehicle
          </button>
        </div>
      </div>
      <div class="row">
        <div class="col-6">
          <button class="quebtn1 float-right" type="button">Back</button>
        </div>
        <div class="col-6">
          <button class="quebtn1" type="submit">Next</button>
          <br />
        </div>
        <div class="row pt-0 mx-auto text-center">
          <div
            class="toast-body toast no-gutters"
            data-autohide="false"
            role="alert"
            aria-live="assertive"
            aria-atomic="true"
            id="toast1"
          ></div>
        </div>
      </div>
    </form>


    Also, here are some tips that aren't directly related to your question:

    • There's also querySelector instead of stuff like getElementsByTagName. It lets you basically use CSS selectors to select elements, which a lot of people find easy to use.
    • For this sort of DOM manipulation, you also might want to try using the jQuery library
    • It's good to learn how DOM manipulation works for educational purposes, but on real projects the field has moved towards UI libraries like React and Vue.
    • You named your function Function1. This works, but it's better if you could name it something more descriptive, like addVehicle. That way it's more clear what it's doing. With one function Function1 is probably fine, but imagine if you had 12 functions and had to think to yourself, "Wait, what is Function3 doing again? Did I want to use Function7?"
    • It's good to learn by doing, but it's also good to mix that with a more "bottom up" approach of reading books and stuff to give you the foundation you'll need for fun projects like this.