Html5 database

Html5 no sólo trajo consigo la posibilidad de crear funcionalidades que hacen a nuestro navegador más ‘bonito’ como canvasdrag and drop o los nuevos elementos de formulario. Html5 va un poco más allá de lo que conocemos como un navegador web.

En un posteo pasado publiqué cómo guardar datos en el navegador con los objetos localStorage y sessionStorage, lo que nos permitía mantener esa información sin importar que el usuario abandonara el navegador. Pueden verlo desde aquí Guardar contenido en el navegador con html5.

Con el paso del tiempo los navegadores han tomado mayor terreno en la web, como por ejemplo Javascript con Ajax, sin embargo el navegador debe comunicarse todo el tiempo con el servidor para que una página web funcione. Por ejemplo Ajax a través de Javascript funciona como un mensajero entre el navegador y el servidor.

Ahora bien, hablar de página web es hablar de internet, una aplicación web funciona con internet, aunque esto es relativo. ¿Qué pasaría si tenemos que guardar un gran número de información pero de pronto el navegador se cierra accidentalmente, se corta la luz o simplemente no hay internet?.

Por suerte Html5 nos da la posibilidad de trabajar con una base de datos local. Ojo, dije local, eso no significa que Html5 pueda conectarse por ejemplo a MySQL como lo hace PHP, el navegador tiene su propia base. Esto nos ayuda a que el navegador guarde información de forma offline, sin depender del servidor, para no perder datos en ese juego en que se abandona el navegador por las posibilidades ya nombradas.

Bueno, antes de seguir aclaro lo que aclaro en todos los posteos que realizo en Html5, las funcionalidades nuevas no funcionan en todos los navegadores. Yo en mi caso estoy usando una de las últimas versiones de Chrome.

Para conectar a la base de datos empezaremos por crear una variable:

var db = null;

Ahora para convertir esta variable en el objeto que nos permitirá trabajar con la base de datos local debemos llamar a la función openDatabase(). Esta función recibirá cuatro parámetros: el primero será el nombre de la base de datos, si no existe la creará; el segundo es la versión, en nuestro caso será la 1.0; el tercero es una descripción de la base y el cuarto el tamaño en bytes:

var db = null;
function abrirDB(){
    try{
       db = openDatabase('db_test', '1.0', 'Database Prueba', 200000);
    }catch(e){
       document.write('La aplicacion no soporta html5 database.');
    }
}

Al llamar a la función abrirDB() la aplicación estará lista para hacer consultas a la base de datos local.

<!DOCTYPE html>
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <script type="text/javascript">
       var db = null;
       function abrirDB(){
          try{
             db = openDatabase('db_test', '1.0', 'Database Prueba', 200000);
          }catch(e){
             document.write('La aplicacion no soporta html5 database.');
          }
       }
       window.onload = function(){
          abrirDB();
       }
    </script>
 </head>
 <body>
 </body>
</html>

Al ejecutar este código la base de datos será creada si no existe.

Si están testeando esto con Chrome pueden ir a “Personaliza y “configura Google Chrome” . Luego “Herramientas” -> “ConsolaJavaScript” y aparecerá una consola, en donde habrá que pulsar el botón “Resources”

Ahí nos muestra la creación de la base de datos.

Sigamos. Como cualquier base de datos ésta tendrá tablas, para ello ejecutaremos  nuestra primer consulta que creará una tabla si ésta no existe. Para ello primero usaremos un método del objeto db, el método .transaction() que será quién se comunique con la base, a su vez éste recibirá un parámetro que será un función que se disparará una vez lograda la transacción y esta función recibirá un objeto que será el encargado de realizar las consultas con la base de datos:

function crearTablas(){
    db.transaction(function(tx){
       tx.executeSql("CREATE TABLE IF NOT EXISTS instrumento(ide integer primary key autoincrement, nombre text)");
    });
}

Si ahora ejecutamos el código debería crearnos la base de datos, y si lo volvemos a ejecutar debería verificar si existe antes de crearla.

Ahora ejecutamos ambas funciones:

window.onload = function(){
   abrirDB();
   crearTablas();
}

Bien, ahora nos falta cómo hacer las consultas sobre esta tabla. Para ello usaremos nuevamente el método executeSql(). Pero para ello vamos a detenernos en analizar un poco este método, el mismo puede recibir cuatro parámetros: el primero, que ya usamos será la consulta en sí; el segundo serán los datos de entrada de la consulta en forma de array (si no hay ninguno será un array vacío); el tercero será una función que se ejecuta una vez que la consulta nos devolvió una respuesta y el cuarto si la misma falló.

Vale aclarar que tanto los métodos .transaction() como .executeSql() son asíncronos, esto significa que los mismos se dispararán mientras que la aplicación web sigue funcionando normalmente y una vez que se obtenga respuesta de la base de datos se dispararán las funciones correspondientes, en el caso de .executeSql() el tercer y cuarto  parámetro se ejecutarán una vez que la consulta devuelve un resultado, ya sea correcto o por una falla. Creemos la función para insertar:

function insertarInstrumento(nombre){
    db.transaction(function(tx){
       tx.executeSql("INSERT INTO instrumento(nombre) VALUES(?)", [nombre], function(tx, respuesta){
          alert('El instrumento ha sido insertado correctamente');
       }, function(tx, respuesta){
          alert('El instrumento no ha podido ser insertado');
       });
    });
}

Como ven, en el primer parámetro escribimos la consulta; en el segundo las entradas, en nuestro caso sólo existe una, nombre, pero podríamos crear más: [entrada1, entrada2, entrada3] en forma de array; el tercero será una función que se ejecutará al devolvernos una respuesta después de la inserción y el cuarto si la consulta falló.

Ahora si lo ejecutamos:

window.onload = function(){
    abrirDB();
    crearTablas();
    insertarInstrumento('Guitarra');
    insertarInstrumento('Bajo');
    insertarInstrumento('Bateria');
    insertarInstrumento('Teclado');
}

Ahora, para hacer un update o un delete hay que seguir la misma lógica del insert, el asunto es cómo recuperar datos de un select. Para ello también debemos usar el método .executeSql(). Para recuperar los datos, si se han fijado bien cuando yo llamo al tercer y cuarto parámetro utilizo dos parámetros en ambos casos:

function(tx, respuesta){}

El segundo parámetro es un objeto que devuelve la consulta de la base de datos. Para ir recuperando de a poco los registros debemos recorrerlo con un for. Ese objeto a su vez tendrá una propiedad llamado .rows con las filas recuperadas, .rows también es un objeto, tendrá una propiedad .length para saber la cantidad de registros devueltos y un método .item() que recibirá cómo parámetro el número de la fila a recuperar. Para recuperar los datos insertados deberíamos hacer algo como esto:

<!DOCTYPE html>
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <script type="text/javascript">
       var db = null;
       function abrirDB(){
          try{
             db = openDatabase('db_test', '1.0', 'Database Prueba', 200000);
          }catch(e){
             document.write('La aplicacion no soporta html5 database.');
          }
       }
       function crearTablas(){
          db.transaction(function(tx){
             tx.executeSql('CREATE TABLE IF NOT EXISTS instrumento(ide integer primary key autoincrement, nombre text)');
          });
       }
       function mostrarResultados(){
          db.transaction(function(tx){
             tx.executeSql("SELECT * FROM instrumento", [], function(tx, respuesta){
             document.getElementById('lista').innerHTML = '';
             var ide = null;
             var nombre = null;
             var li = null;
             for(var i = 0; i < respuesta.rows.length; i++){
                ide = respuesta.rows.item(i).ide;
                nombre = respuesta.rows.item(i).nombre;
                li = document.createElement('li');
                li.innerHTML = ide + ' - ' + nombre;
                document.getElementById('lista').appendChild(li);
             }
          }, function(tx, respuesta){
             alert('No se han podido recuperar la lista de instrumentos');
          });
       });
    }
    window.onload = function(){
       abrirDB();
       crearTablas();
       mostrarResultados();
    }
 </script>
 </head>
 <body>
    <ul id="lista"></ul>
 </body>
</html>

A continuación les dejo el código de de una mini aplicación para insertar, modificar, eliminar y listar instrumentos:

<html xmlns="https://www.w3.org/1999/xhtml">
 <head>
    <title>Aca va el titulo de la pagina</title>
    <script type="text/javascript">
       var db = null;
       function iniciarDB(){
          abrirDB();
          crearTablas();
       }
       function abrirDB(){
          try{
             db = openDatabase('db_test', '1.0', 'Database Prueba', 200000);
          }catch(e){
             document.write('La aplicacion no soporta html5 database.');
          }
       }
       function crearTablas(){
          db.transaction(function(tx){
             tx.executeSql('CREATE TABLE IF NOT EXISTS instrumento(ide integer primary key autoincrement, nombre text)');
          });
       }
       function guardarInstrumento(nombre, ide, funcion_de_respuesta){
          if(ide){
             db.transaction(function(tx){
                tx.executeSql('UPDATE instrumento SET nombre = ? WHERE ide = ?', [nombre, ide], function(){
 funcion_de_respuesta(true);
                }, function(){
                   funcion_de_respuesta(false);
                });
             });
         }else{
            db.transaction(function(tx){
               tx.executeSql('INSERT INTO instrumento(nombre) VALUES(?)', [nombre], function(tx, respuesta){
                    funcion_de_respuesta(true);
               }, function(tx, respuesta){
                    funcion_de_respuesta(false);
               });
            });
         }
      }
      function eliminarInstrumento(ide, funcion_de_respuesta){
         db.transaction(function(tx){
            tx.executeSql('DELETE FROM instrumento WHERE ide = ?', [ide], function(){
               funcion_de_respuesta(true);
            }, function(){
               funcion_de_respuesta(false);
            });
         });
      }
      function cargarInstrumentoPorId(ide, funcion_de_respuesta){
         var instrumento_item = {
            ide: null,
            nombre: null
         };
         db.transaction(function(tx){
            tx.executeSql('SELECT ide, nombre FROM instrumento WHERE ide = ?', [ide], function(tx, respuesta){
               instrumento_item.ide = respuesta.rows.item(0).ide;
               instrumento_item.nombre = respuesta.rows.item(0).nombre;
               funcion_de_respuesta(true, instrumento_item);
            }, function(tx, respuesta){
               funcion_de_respuesta(false, instrumento_item);
            });
         });
      }
      function cargarInstrumentos(funcion_de_respuesta){
         var lista = new Array();
         db.transaction(function(tx){
            tx.executeSql('SELECT ide, nombre FROM instrumento', [], function(tx, respuesta){
               for(var i = 0; i < respuesta.rows.length; i++){
                  lista.push({
                     ide: respuesta.rows.item(i).ide,
                     nombre: respuesta.rows.item(i).nombre
                  });
               }
               funcion_de_respuesta(true, lista);
            }, function(){
               funcion_de_respuesta(false, lista);
            });
         });
      }
      function mostrarInstrumentos(lista){
         document.getElementById('lista').innerHTML = '';
         var ide;
         var nombre;
         var item;
         for(var i = 0; i < lista.length; i++){
            ide = lista[i].ide;
            nombre = lista[i].nombre;
            item = crearItemInstrumento(ide, nombre);
            document.getElementById('lista').appendChild(item);
         }
      }
      function crearItemInstrumento(ide, nombre){
         var li = document.createElement('li');
         var nombre_item = document.createElement('p');
         nombre_item.innerHTML = nombre;
         var boton_modificar = document.createElement('input');
         boton_modificar.type = 'button';
         boton_modificar.value = 'Modificar';
         boton_modificar.onclick = function(){
            cargarInstrumentoPorId(ide, function(respuesta, instrumento){
               if(respuesta){
                  document.getElementById('nombre_instrumento').value = instrumento.nombre;
                  document.getElementById('ide_instrumento').value = instrumento.ide;
               }else{
                  alert('Error al cargar el instrumento')
               }
            });
        }
        var boton_eliminar = document.createElement('input');
        boton_eliminar.type = 'button';
        boton_eliminar.value = 'Eliminar';
        boton_eliminar.onclick = function(){
           eliminarInstrumento(ide, function(respuesta){
              if(respuesta){
                 refrescarListaInstrumentos();
                 alert('El instrumento ha sido eliminado');
              }else{
                 alert('Error al intentar eliminar el instrumento')
              }
           });
       }
       li.appendChild(nombre_item);
       li.appendChild(boton_modificar);
       li.appendChild(boton_eliminar);
       return li;
    }
    function refrescarListaInstrumentos(){
       cargarInstrumentos(function(respuesta, lista){
          if(respuesta){
             mostrarInstrumentos(lista);
          }else{
             alert('No se han podido cargar la lista de instrumentos');
          }
       });
    }
    window.onload = function(){
       iniciarDB();
       refrescarListaInstrumentos();
       document.getElementById('boton_guardar').onclick = function(){
          if(document.getElementById('formulario').checkValidity()){
             var nombre_instrumento = document.getElementById('nombre_instrumento');
             var ide_instrumento = document.getElementById('ide_instrumento');
             guardarInstrumento(nombre_instrumento.value, ide_instrumento.value, function(respuesta){
                if(respuesta){
                   nombre_instrumento.value = '';
                   ide_instrumento.value = '';
                   refrescarListaInstrumentos();
                   alert('El registro ha sido guardado con exito');
                }else{
                   alert('El registro no ha podido ser guardado');
                }
             });
          }
       };
    }
    </script>
 </head>
 <body>
    <form id="formulario" action="javascript:void(0);">
       <ul id="lista"></ul>
       <label> Nombre del instrumento </label>
       <input type="text" id="nombre_instrumento" required />
       <input type="hidden" id="ide_instrumento" />
       <input type="submit" id="boton_guardar" value="Guardar" />
    </form>
 </body>
</html>

Saludos!

 

 

Redes sociables

    17 Replies to “Html5 database”

    1. un cordial saludo.

      felicidades por el tutorial y todo el contenido de esta pagina que la sigo paso a paso, de antemano le agradezco por compartir los conocimientos en la web.

      tengo una pregunta, tengo una pagina web y un script de base de datos para subirla al hosting no se como programar los botones de modificacion para que guarden en la base de datos del hosting y luego que me aparezca en la pagina como en una especie de grilla.

      le agradezco por su apoyo u orientacion.

      felicidades

      1. Jhon gracias a vos por comentar.

        Si tenés cuenta en gmail, agregame al chat, y te doy una mano.

        Mi coreo es fernandoggaitan(gmail.com)

        Saludos!

    2. Hola, muy útil este tutorial y muy bien explicado … lo recomiendo! :3.

      Tengo una consulta, estoy haciendo una aplicación web, que me permite guardar una serie de datos de 3 tablas diferentes y hay cierta relación entre ellas (si lo tienes o lo vas a hacer en otro tutorial te pido el link por favor xD) ¿como puedo codificar esa relación? gracias por el gran aporte! saludos!

      1. Esto, siguiendo la línea de Html5, osea vos te referís a la base de datos de Html5 o estás usando otro tipo de base de datos como MySQL, por ejemplo?

    3. Hola muchas gracias por la información a despejado algunas dudas, tengo una pregunta: hay manera de conectar siguiendo html5 phpmyadmin sin utilizar PHP?

      1. Wilmer, cómo estás.

        Sinceramente no sé si puede hacer eso, lo más probable es que no, ya que Html es un lenguaje de cliente, y no debería poder conectarse a bases de datos como MySQL.

        Saludos!

      1. No, sinceramente sólo lo he probado en Chrome. Sé que Firefox no lo aplica, tal vez esté disponible en versiones futuras, y Explorer va a dejar de existir.

        Te pido disculpas por no poder ayudarte.

        Saludos!

    4. hola buenas tardes

      quisiera que me aclararas un poco, asi entendi.

      html5 puede crear su propia bd local, es decir si alguien graba datos en desde su pc en esta bd, alguien desde otro sitio puede leer o consultar estos datos, es decir mi duda es puede una bd de estas reemplazar una bd mysql?

      1. No, es una base de datos que sólo permite trabajar en forma offline, sin conexión a internet.

        Osea pensalo de esta manera, hoy día muchas personas se conectan desde dispositivos como celulares, los cuales muchas veces pierden conexión a internet. Como por ejemplo las aplicaciones móviles que siguen funcionando aun sin conexión.

        Suponete que un usuario agrega ítems de un carro de compras, estos se guardan en su máquina y persisten aunque el usuario recargue el navegador o bien, se quede sin internet. Una vez que todo esté bien, el usuario puede enviar estos datos al servidor y se guardará todo en una base de datos en el servidor.

        Saludos!

    5. hola, tengo una duda, para la conexion de la base de datos creas la variable:
      var db = null;
      esa donde la declaras, es mi duda…
      espero me respondas

    6. que onda amigo me gusto mucho tu tutorial
      tengo una duda de si en caso de que quisiera pasar los datos de esa pagina a otra
      así como si fuese un menú principal y de allí partieras a otra pagina (href), y en esta otra se hiciera el llenado y ya en otra pagina la visualización de los datos ingresados
      te lo agradecería mucho si me pudieses proporcionar esa info.

    7. Me gusto el tutorial, yo quisiera hacer algo asi pero Online, tener la informacion disponible y que me llenen un formulario y que lo manden las veses que sean para obtener informacion directa de la web. y poderlos consultar, borrar solo yo.

    8. Muy buen tutorial !!!
      Mis felicitaciones!!!
      Esto sin duda remplazara mis bases de datos simuladas :3 hehe
      Muchas gracias por la publicación, me sirvió mucho.

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    *