Utilizando Formularios en HTML - Ejercicio Práctico de HTML, CSS y Validación con Javascript

¡Hola a todos! Bienvenidos a este nuevo post donde aprenderemos a crear formularios en HTML. Una herramienta muy útil en todo sitio web, que nos permite recopilar información valiosa y comunicarnos con nuestros usuarios de una forma sencilla. También se llevará a cabo el proceso de validación del formulario para evitar que los datos se envíen con algún error.

Formularios en HTML, CSS y validación con Javascript

En este artículo verás como crear un formulario en HTML y como utilizar:

  • Inputs de texto o numéricos.
  • Radio Buttons.
  • Checkbox.
  • Botones.
  • Conocerás los atributos de cada elemento.
  • Estilos con display Grid y Flexbox.
  • Manipulación de los datos con Javascript.
  • Validación de los datos para envíarlos sin errores. 

Código HTML del formulario:

<!DOCTYPE html>
<html>
  <head>
    <title>Formularios</title>
    <meta charset="utf-8">
  </head>
  <body>    <!--form onsubmit="return validate()"-->
    <form target="_self">
      <div>
        <h1>Heladería</h1>
        <h3>Añade un producto:</h3>
      </div>
      <div>
        <label for="categoria">Categoría:</label>
        <select name="categoria" required>
          <option value="">Seleccione Categoría …</option>
          <option value="Helado">Helado</option>
          <option value="Torta">Torta</option>
        </select>
      </div>
      <div id="sabores">
        <p><strong>Sabores que ofrecemos</strong></p>
      </div>
      <div>
        <label for="sabor">Sabor:</label>
        <input name="sabor" id="sabor" class="input" type="text" required>
      </div>
      <div>
        <label for="cantidad">Cantidad:</label>
        <input name="cantidad" id="cantidad" class="input" type="number" min=1 max=100 required>
      </div>
      <div>
        <input type="radio" name="size" id="small" value="pequeño" checked><label for="small">Pequeño (2)</label>
        <input type="radio" name="size" id="medium" value="mediano"><label for="medium">Mediano (5)</label>
        <input type="radio" name="size" id="big" value="grande"><label for="big">Grande (7)</label>
      </div>
      <div>
        <strong>Complementos:</strong><br>
        <input type="checkbox" id="mani" name="mani" value="Maní"><label for="mani">Maní</label><br>
        <input type="checkbox" id="chocolate" name="chocolate" value="Chispas de chocolate"><label for="chocolate">Chispas de Chocolate</label><br>
        <input type="checkbox" id="chispas" name="chispas" value="Chispas de Colores"><label for="chispas">Chispas de Colores</label><br>
        <input type="checkbox" id="leche" name="leche" value="Leche Condensada"><label for="leche">Leche Condensada</label><br>
      </div>
      <div>
        <input type="submit" id="send-button" name="send-button" class="button">
        <input type="reset" value="Borrar" class="button">
      </div>
    </form>
    <div class="container" id="container">
      <input type="button" id="finish" class="button" value="Completar Compra">
    </div>
  </body>
</html>
Como podrán ver en el código anterior podemos encontrar los siguientes elementos:
<INPUT>: Es el elemento que permite una entrada de datos, posee el atributo type="" que indica que tipo de entrada pidimos. Puede ser:
  • type="text". Para entrada de texto.
  • type="number". En la cual solo podremos escribir números.
  • type="radio". El cual crea un "Radio Button", un conjunto de oopciones de la cual solo podrás elegir una. Al seleccionar una se des-selecciona la otra.
  • type="checkbox". El cual crea una casilla de selección (Checkbox), en la cual, a diferencia del radio button podemos seleccionar varias opciones. 
  • type="button". Para crear un botón. El texto que posee este botón se establece mediante el atributo value, que en este caso tiene como valor "Completar compra". 
  • type="submit". Similar al type="button". Ya que también crea un botón, pero que al presionar se ejecuta el evento onsubmit() que envia todos los datos del formlarios.
<SELECT> : Esta etiquet crea un menú desplegable de opciones, es de etiqueta doble (de inicio y cierre) y dentro de ella se tienen que incluir las etiquetas <OPTION> que poseen el atributo value, que almacena el valor de cada opción.
 
Todos estos elementos debe tener el atributo id (El cual debe ser único). Nos permitirá identificar a cada objeto y manipularlos mediante codigo Javascript.

Código CSS:

@import url('https://fonts.googleapis.com/css?family=Open+Sans:200,300,400,500,600,700,800,900&display=swap');

*{
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
display:grid;
grid-template-columns: repeat(12,100px);
grid-template-rows: 1fr;
font-family: 'Open Sans', sans-serif;
width: 100%;
height: auto;
}
h1{
display: flex;
justify-content:center;
align-items: center;
}
.sizes {
display: flex;
justify-content: space-evenly;
}
.complementos label, sizes label{
padding: 0 16px;
}
.card{
border-radius: 4px;
width: 90%;
height: auto;
background: #eeeeee;
padding:8px;
margin: 16px;
display:flex;
justify-content: flex-start;
flex-wrap: wrap;
border: 2px solid #ccc;
}
form{
display:block;
padding: 16px;
margin: 16px 0 0 16px;
height: auto;
grid-column: 1/5;
grid-row: 1/2;
background: #23fffe;
border-radius: 8px 8px 0 0;
}
form div{
margin: 8px 0;
}
.input, select{
width:100%;
height: 24px;
}

.container{
grid-column: 5/12;
grid-row: 1/2;
background: #ffff00;
display:flex;
height: 100%;
margin: 16px 0 0 0;
align-items: center;
justify-content:flex-start;
flex-direction:column;
}

.button{
width:100%;
height: 40px;
margin: 4px;
outline: none;
border: none;
border-radius: 32px;
font-size: 1.2em;
font-weight: 500;
}
input[type="submit"]{
background: #2de65b;
}
input[type="reset"], input[type="button"]{
background: #e62b5a;
color:#fff;
}
#finish{
display: none;
margin: 16px 0;
background: #10ff62;
color: #000;
width: 90%;
}

@media (max-width: 480px){
body{
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
}
form{
width: calc(100%- 16px);
height: 100%;
height: 100%;
grid-row: 1/2;
grid-column: 1/2;
margin: 16px 8px 0px 8px;
display: flex;
flex-direction: column;
padding:32px;
background: #11ffff;
border: 2px solid #176afe;
}
.container{
width: 100%;
height: 100%;
display: flex;
grid-column: 1/2;
grid-row: 2/3;
background: #ffff0e;
flex-direction:column;
align-items: center;
justify-content: flex-start;
}
}

Código Javascript de validación del formulario:

window.onload = function(){

//Hacemos referencia a los objetos en el formulario.

const selectElement = document.forms[0].categoria;

//Accedemos a algunos objetos por su id.

const container = document.getElementById("container");

const container2 = document.getElementById("sabores");

//El boton de envio.
const sendButton = document.getElementById("send-button");

const finish = document.getElementById("finish");

//Utilizaremos dos eventos, cuando se envie el formulario
sendButton.addEventListener('click', validate);

finish.addEventListener('click', completarCompra);

//Cuando se cambie el primer campo, es decir, la categoria, el elemento select.

selectElement.addEventListener('change', showProducts);

product_list = [];
var ids = 0;

var elementos = document.forms[0].elements;

function validate(e){ //Creamos nuestra funcion de validacion     e.preventDefault();

    var patron = /^\s+/;     var opciones = ["Chocolate","Fresa","Vainilla","Mantecado","Limón"];     let categoria = elementos[0];

    //.trim() elimina espacios al principio y final de un texto.     let sabor = elementos[1].value.trim();
    var cantidad = elementos[2].value; //El sabor nuestro segundo campo no puede ser nulo, no puede tener longitud de 0, la tercera condicion indica que no pueden ser solo espacios vacios     if (categoria.selectedIndex == 0){         return false;     }
    else if (!opciones.includes(sabor)){         console.log("Opción inválida");         return false;     }
    else if(sabor == null || sabor.length == 0 || patron.test(sabor) || /\d+/.test(sabor)){         return false;     }else if(cantidad == null ||isNaN(cantidad) || cantidad <=0 || cantidad>99) {         return false;     }else{         addProduct();         //e.preventDefault();     }     if (product_list.length >0){         finish.style.display = "block";     } }

function showProducts(){     if(selectElement.value=="Helado"){         container2.textContent = "Chocolate (14.0), Vainilla (12.0), Fresa (9.98), Limón (6.0), Mantecado (7.5)";     }     else if (selectElement.value=="Torta"){         container2.textContent = "Chocolate (14.0), Vainilla (12.0), Fresa (9.98), Limón (6.0)";     } }

function addProduct () {     //event.preventDefault();     var id = ids;     let sabor = elementos[1].value.trim();     var categoria = elementos[0].value;     var tamaño = document.forms[0].size.value;

//Éstos son los checkbox     var c1 = document.getElementById("mani");     var c2 = document.getElementById("chocolate");     var c3 = document.getElementById("chispas");     var c4 = document.getElementById("leche");
    var complementos = [c1,c2,c3,c4];
    var producto = new Producto(id, categoria, sabor,elementos[2].value, tamaño, complementos);     console.log(producto.id);     ids+=1;     const element = document.createElement('div');
       element.className ="card";
element.innerHTML =
`<p><strong>${categoria} de ${producto.sabor}</strong><br>
Cantidad: ${producto.cantidad}   Precio: ${producto.precio}   Complementos: ${producto.extras}4 c/u
Total a pagar: ${producto.getTotal()}</p>
<input type="button" class="button" name="delete" value="Eliminar">`;

    container.appendChild(element);     product_list.push(producto);     document.forms[0].reset();     console.log(product_list);

    container.removeEventListener("click", deleteProduct);     container.addEventListener("click", function(e){
    console.log(e.target+": "+e.target.name+" "+ producto.id);     if(e.target.name === 'delete'){         deleteProduct(e.target, producto.id);     }
});     return false;
}

function completarCompra(){     var total = 0;     for(i=0; i< product_list.length; i++){     console.log(product_list[i]);          total+=product_list[i].getTotal();     }     alert("Monto total a pagar: "+total); }

function deleteProduct(element, id){     if(element.name === 'delete'){         element.parentElement.remove();         if(product_list.length>0){             //console.log("Eliminado: "+ product_list[id].tipo +" de "+ product_list[id].sabor);             product_list.splice(id,1);             ids-=1;         }             console.log("Productos: "+ product_list.length);     }else{
        return;     }
}

function Producto(id, tipo, sabor, cantidad, tamaño, complementos){     this.id = id;     this.tipo = tipo;     this.sabor = sabor;     this.cantidad = cantidad;     this.tamaño = tamaño;     this.extras="";
    console.log("ID: "+id);
    switch (sabor){         case "Chocolate":             this.precio = 14.00;             break;
        case "Vainilla":             this.precio = 12.00;             break;
        case "Fresa":             this.precio = 9.98;             break;
        case "Mantecado":             this.precio = 7.50;             break;
        case "Limón":             this.precio = 6.0;             break;     }     this.subtotal = this.cantidad*this.precio;
    var envase = 0;
    if(this.tamaño == "pequeño"){         envase+=2.00;     }     else if(this.tamaño == "mediano"){         envase+=5.00;
    }else{         envase+=7.00;     }
    var adicional = 0;
    for (var i=0; i<complementos.length;i++){            if(complementos[i].checked == true){                adicional+=4.00;                this.extras+=complementos[i].value+", ";            }     }
    this.getTotal = function (){         var total = this.subtotal + envase + adicional;         return total;     } 
}

Aquí les de dejo una plantilla, ahora ustedes pueden darle los estilos que gusten. Espero que les haya gustado este post. Díganme sus opiniones en los comentarios. 
 
¡Saludos y espero verlos pronto!


Si te gustó este artículo ¡Compartenos en las redes!

Publicar un comentario

3 Comentarios

  1. Hola. Desde Colombia. Felicitaciones, explicas de una manera clara. Me ayudo mucho tu información. Gracias

    ResponderEliminar
    Respuestas
    1. Muchísimas gracias, me alegra que te haya gustado el contenido y que te haya servido de utilidad

      ¡Saludos y gracias por dejar tu comentario!

      Eliminar
  2. Hola que tal, lo hice tal como esta pero al momento de darle enviar me lo limpia y no paso de ahí, crees que me puedas ayudar gracias!!

    ResponderEliminar