photo Datalist validation

How to validate a datalist


HTML Markup

<div class="d-flex flex-column justify-content-center vh-100">
	<div class="container mt-5">
		<form class="bg-body-tertiary shadow p-4 rounded-4">
			<div class="row gx-4 gy-4">
				<div class="col-12 mb-4">
					<h1 class="text-center">What are your favourites</h1>
				</div>
				<div class="col-lg-4">
					<div class="input-group">
						<span class="input-group-text">What a Fruit</span>
						<input class="form-control" 
							type="text" 
							data-fruits="Apple, Banana, Orange" 
							list="fruits" name="favFruit" 
							placeholder="Select a Fruit" 
							required
							autocomplete="off"
						>
					</div>
				</div>
				<div class="col-lg-4">
					<div class="input-group">
						<span class="input-group-text">Which Country</span>
						<input class="form-control" 
							type="text" 
							data-countries="England, Germany, China" 
							list="countries" name="favCountry" 
							placeholder="Select a Country" 
							required
							autocomplete="off"
						>
					</div>
				</div>
				<div class="col-lg-4">
					<div class="input-group">
						<span class="input-group-text">What Car</span>
						<input class="form-control" 
							type="text" 
							data-cars="BMW, Ferrari, Ford" 
							list="cars" name="favCar" 
							placeholder="Select a Car" 
							required
							autocomplete="off"
						>
					</div>
				</div>
				<div class="col">
					<input class="btn shadow btn-success float-end mt-4" type="submit">
				</div>
			</div>
		</form>
	</div>
</div>
<div class="toast-container top-0 start-50 translate-middle-x mt-5">
	<div class="toast fade hide" role="alert" id="toast-1">
		<div class="toast-header">
			<img class="me-2" src="/favicon.svg" width="20" height="20" alt="logo">
			<strong class="me-auto">Submitted</strong>
			<small>Right Now</small>
			<button class="btn-close ms-2 mb-1 close" type="button" aria-label="Close" data-bs-dismiss="toast">
			</button>
		</div>
		<div class="toast-body" role="alert">
			<p data-toast-body=""></p>
		</div>
	</div>
</div>

Javascript

document.addEventListener('DOMContentLoaded', function () {
  const inputs = document.querySelectorAll('input[list]');
  const form = document.querySelector('form');
  inputs.forEach((input) => {
    const dataListId = input.getAttribute('list');
    const dataOptions = input.dataset[dataListId];
    const options = dataOptions.split(',').map((option) => option.trim());

    const datalist = document.createElement('datalist');
    datalist.id = dataListId;

    options.forEach((option) => {
      const optionElement = document.createElement('option');
      optionElement.value = option;
      optionElement.text = option;
      datalist.appendChild(optionElement);
    });

    input.parentNode.appendChild(datalist);
  });

  inputs.forEach((input) => {
    input.addEventListener('change', function () {
      let optionFound = false,
        datalist = this.list;

      const optionsArray = Array.from(datalist.options);
      optionFound = optionsArray.some((option) => option.value === this.value);

      if (optionFound) {
        this.setCustomValidity('');
      } else {
        this.setCustomValidity('Please select a valid value.');
      }
    });
  });

  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const toast = bootstrap.Toast.getOrCreateInstance(
      document.getElementById('toast-1')
    );
    const data = new FormData(form);
    const bodyText = `You are in ${data.get(
      'favCountry'
    )} driviing a ${data.get('favCar')} and eating a ${data.get('favFruit')}`;
    document.querySelector('[data-toast-body]').textContent = bodyText;
    toast.show();
    form.reset();
  });
});

That's it

Go back