sábado, 28 de enero de 2017

HTML - ¿Qué es el DOM y porqué debería interesarme?

Uhhhh el DOM, ¿de qué está compuesto?, ¿es comestible?, ¿en que puede ayudarnos?, ¿es comestible?, ¿acaso tengo hambre y por eso sigo preguntando si es comestible?. Bueno, todo esto lo escribiré en este post.

El DOM (Document Object Model) proveé una representación estructurada del documento HTML y define una manera de poder acceder a esta estructura de tal manera que se pueda modificar facilmente tanto la estructura, los estilos y los contenidos. Es una representación completamente orientada a objetos de una página web.

Ahora respondiendo a las preguntas que nos hicimos siempre:

¿Es comestible?
- Para este momento ya debería estar claro, no, no lo es.

¿De qué está compuesto?
- Esta compuesto de cada elemento de tú página web, de hecho, incluso en caso de que tu documento no esté estructurado de manera correcta, se corrige mágicamente en el DOM. Además, es necesario tener en cuenta que distintos navegadores implementan de distinta manera su implementación del DOM.

Por ejemplo, la siguiente tabla con un pequeño error, se corrige en el DOM.

<table>
  <tbody>
    <tr>
      <td>Contenido</td>
    </tr>
</table>

El dom agrega la etiqueta de cierre del tbody
¿En que puede ayudarnos?
- Pues nos facilitá el acceso a los elementos de una página web, usualmente se puede manipular con javascript. Por ejemplo el siguiente código obtiene todos los tags td de la tabla.

document.getElementsByTagName("td")

Es útil conocer el DOM en caso de estar haciedo diseño de interfaces. Un buen ejemplo es la siguiente imagen.

En la parte inferior se puede observar una representación del DOM

Y eso es todo por ahora, keep coding >_<

lunes, 23 de enero de 2017

El ciclo de vida de un componente en Aurelia

Continuando con la serie de posts acerca del framework Aurelia para el lado del cliente, me parece pertinente, antes de pasar a temas más complejos, conocer el ciclo de vida de un componente en Aurelia.

Desde el momento en que una vista comienza a cargar hasta el instante en que la aplicación es visible para el cliente, se llama a una serie de callbacks en un orden determinad, hecho que es importante conocer para aplicar cambios dinamicamente en la pantalla en el momento en que realmente es posible hacerlo. Por ejemplo, si se quiere buscar un elemento con jquery por el id, el elemento debe encontrarse en el DOM actualmente.

Se debe tomar en cuenta que no solamente los componentes pasan por este ciclo de vida, sino también los elementos personalizados (custom elements) e incluso cualquier modelo (view-model) generado, además, no es necesario implementarlos todos, sino solamente los que se necesiten.

Los callbacks y el orden en que se llaman son:
  1. constructor (): el contructor, que es el sitio principal donde se obtienen los elementos inyectados.
  2. created (vistaPadre, vistaActual): que se llama en cuento se crean la vista (view) y el modelo (view-model), recibe como primer parámetro la vista en la cual se declara el componente.
  3. bind (contexto, contextoSobrecargado): que recibe dos parámetros, siendo el primero el más importante, y es el contexto actual al cuál nos enlazaremos.
  4. attached(): que se invoca cuando el elemento se liga al DOM, para ponerlo en contexto para los que utilizarón Jquery alguna vez, es el momento en que se llama el método $().ready(). Este es el momento ideal para inicializar los plugins necesarios.
  5. dettached(): este método es lanzado cuando el elemento se quitará del DOM. Es el inverso de attached.
  6. unbind(): una vez que el elemento se ha quitado del DOM, también debe eliminarse del contexto actual.
Ahora, vamos a probar que esto funcione realmente y que no se las estoy charlando :D

Continuaremos con la base de proyecto anterior.

Solo para recordar, se puede descargar de github:

$ git clone https://github.com/feardarkness/HotelReservationAppFE.git
$ git checkout tags/creando-elemento

Para probar que esto funciona, modificaremos los archivo src/app.js, src/app.html y src/resources/elements/bootstrap-input.js, de la siguiente manera:

Al archivo app.js, donde agregaremos un logger para imprimir un mensaje cuando el callback se haya ejecutado. Llamaremos al logger app-js, esto no es muy distinto de poner un console.log, excepto que es posible mostrar los mensajes dinamicamente cuando lo necesitemos, lo que es muy útil para realizar un debug de la aplicación.

import {bindable, bindingMode, LogManager} from 'aurelia-framework';

export class BootstrapInput {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) texto;

  constructor() {
    this.logger = LogManager.getLogger('app-js');
    this.message = 'Hello World!';
    this.logger.info('CONSTRUCTOR iniciado');
  }

  bind(contexto, contextoSobrecargado) {
    this.logger.info('BIND iniciado');
  }

  attached() {
    this.logger.info('ATTACHED iniciado');
  }

  unbind() {
    this.logger.info('UNBIND iniciado');
  }

  detached() {
    this.logger.info('DETACHED iniciado');
  }
}



El archivo app.html, donde haremos varias cosas, primero agregamos al primer input la opción de realizar el bind del value con un atributo del modelo con la propiedad value.bind="nombres" (o sea que cuando cambie el valor del input esto se reflejara en el modelo en el atributo nombres y viceversa). El input quedará de la siguiente manera:

<input type="text" class="form-control" id="nombres" 
                     placeholder="Nombres" value.bind="nombres">

Además, en el mismo archivo (app.html) agregamos la opción de mostrar u ocultar el elemento bootstrap-input con la propiedad if.bind="nombres ==='mostrar'? true: false". Esta sentencia simplemente indica que si el valor de el atributo nombres en el modelo (app.js) tiene el valor mostrar, el elemento debe mostrarse, de lo contrario el elemento no se muestra.

Nuestro elemento queda de la siguiente manera:

<bootstrap-input texto.bind="message"
         if.bind="nombres ==='mostrar'? true: false"></bootstrap-input>

En aurelia, existe dos maneras de ocultar o mostrar un elemento, una con if.bind que oculta el elemento evitando que se dibuje incluso como html en la página (lo quita por completo del DOM), otra manera es con show.bind, lo que simplemente agrega una clase para evitar que el elemento se vea, aunque el elemento sigue cargado en el html.

Veamos pues cómo funciona:

Prueba de llamada de callbacks del ciclo de vida de un elemento en Aurelia
Se puede observar que el órden en que se llaman los callbacks es constructor - bind - attached - detached - unbind,constructor, bind y attached al crearse el elemento y detached y unbind al momento de eliminarse. Además, si se ve detalladamente los mensajes, se puede ver que el constructor solamente se llama la primera vez, esto es porque Aurelia se encarga de que cada elemento creado sea instanciado una sola vez.

Y eso es todo por ahora, para bajar una versión del proyecto hasta este punto puedes hacer:

$ git clone https://github.com/feardarkness/HotelReservationAppFE.git
$ git checkout tags/lifecycle

Keep coding!!! >_<

sábado, 21 de enero de 2017

AureliaJS: Creando elementos personalizados (custom elements) con la ayuda de aurelia-cli

Con la consola de Aurelia es posible crear elementos personalizados de una manera muy sencilla, el post mostrará como crear un elemento, como utilizarlo y como pasar información al elemento. El proyecto será realizado con la base ya creada en un post anterior.

Primero modificaremos el archivo src/app.html para agregarle unos campos al formulario y hacerlo un poco más interesante, el archivo quedará así:

<template>
 <require from="./assets/main.css"></require>
 <div class="container">
  <div class="row">
   <div class="col-xs-offset-3 col-sm-offset-3 col-md-offset-3
             col-lg-offset-3 col-xs-6 col-sm-6 col-md-6 col-lg-6">
    <h1>${message}</h1>
    <form action="" method="post" role="form">
     <legend>Formulario de registro</legend>

     <div class="form-group row">
      <label for="nombres" class="col-sm-2 control-label">Nombres</label>
      <div class="col-sm-10">
       <input type="text" class="form-control" id="nombres" 
             placeholder="Nombres">
      </div>
     </div>

     <div class="form-group row">
      <label for="apellidos" class="col-sm-2 control-label">Apellidos</label>
      <div class="col-sm-10">
       <input type="text" class="form-control" id="apellidos"
            placeholder="Apellidos">
      </div>
     </div>

     <div class="form-group row">
      <label for="mail" class="col-sm-2 control-label">Correo Electrónico</label>
      <div class="col-sm-10">
       <input type="text" class="form-control" id="mail" placeholder="Mail">
      </div>
     </div>

     <button type="submit" class="btn btn-primary">Registrarme :)</button>
    </form>
   </div>
  </div>
 </div>
</template>


Y así debería verse el formulario:

Formulario con bootstrap

Ahora, intentemos algo nuevo, primero generamos el nuevo elemento, le daremos el nombre bootstrap-input:

$ au generate element
      bootstrap-input

Los nuevos elementos se crean en src/resources/elements, un archivo html y un archivo javascript.
Modificaremos los archivos bootstrap-input.js y bootstrap-input.html para realizar una prueba del enlace de los atributos del modelo con los componentes de la vista.

import {bindable} from 'aurelia-framework';

export class BootstrapInput {
  @bindable texto;
}

<template>
  <div class="form-group">
    <label for="test-input" class="control-label">Texto</label>
    <input type="text" class="form-control" id="test-input"
         value.bind="texto" placeholder="Prueba de cambio de título desde input text">
  </div>
  <div class="row">
    <h2>${texto}</h2>
  </div>
</template>

Para que se comparta el estado del atributo texto entre el modelo y la vista, es necesario enlazarlos (bind), esto se realiza en el input con la propiedad value.bind="texto", de esta manera le decimos a Aurelia que el valor (value) del input se refleje en el atributo texto (los cambios en el atributo texto en el js también se reflejan en el input, esto se conoce comunmente como two way binding).
Además, estamos agregando la sentencia ${texto} dentro de los tags h2, lo le indica a Aurelia que el valor dentro de las llaves debe reemplazarse por el valor del atributo texto en el javascript. en general para mostrar un atributo del js en la vista simplemente usamos ${nombre-atributo}.

Ahora, para importar el elemento personalizado es necesario requerirlo, modificamos el archivo app.html para requerir el elemento y mostrarlo:

<template>
 <require from="./assets/main.css"></require>
 <require from="./resources/elements/bootstrap-input"></require>
 <div class="container">
  <div class="row">
   <bootstrap-input texto.bind="message"></bootstrap-input>
  </div>
  <div class="row">

¿Qué esta pasando aquí? Primero importamos el elemento con require, y luego lo utilizamos llamando al tag bootstrap-input, además le mandamos un parámetro llamado message al elemento, el valor de message será enlazado al atributo texto del elemento bootstrap-input.js.
Se enlaza los campos de la vista principal al elemento
Ahora, escribiendo en el primer input, se puede observar la actualización automática de la pantalla, aunque los cambios se realizan únicamente en el tag h2 del elemento y no así en el título del formulario, aunque ténicamente, todos estos elementos deberían estar enlazados. Esto pasa porque la anotación bindable que se encuentra en el js de nuestro elemento es de un solo sentido por defecto (se envia el valor de la vista principal al elmento, comunmente denominado one way binding), para que se aprecie la modificación de los campos en ambos sentidos (el valor se envia de ida y de vuelta) simplemente modificamos el archivo bootstrap-input.js agregando el modo two-way.

import {bindable, bindingMode} from 'aurelia-framework';

export class BootstrapInput {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) texto;
}

Ejemplo con gif para más glamour ;p
Ahora, al modificar el input text podemos observar que los cambios se envian tanto al js del elemento, como al js de la vista principal.

Y eso es todo por ahora, para revisar el código del ejempo, clonar e ir al tag creando-elemento.

$ git clone https://github.com/feardarkness/HotelReservationAppFE.git
$ git checkout tags/creando-elemento

Keep coding!!! >_<

domingo, 15 de enero de 2017

Instalando bootstrap sass en AureliaJS

Y continuamos... esta vez agregaremos bootstrap sass a un proyecto iniciado con la cli de aurelia.

El primer paso es instalar bootstrap sass y jquery en el proyecto:

$ npm install bootstrap-sass --save
$ npm install jquery --save

Recordar que la opción --save, simplemente guardara esta librería en el archivo package json para que luego pueda instalarse facilmente con npm install.

Ahora, modificaremos el archivo aurelia.json, agregando las siguientes líneas en dependencies para que el buider de Aurelia reconozca a bootstrap y lo cargue. Es necesario que jquery este cargado primero para poder utilizar bootstrap, así que agregamos ambos.

     "jquery",
     {
       "name": "bootstrap",
       "path": "../node_modules/bootstrap-sass/assets/javascripts",
       "main": "bootstrap",
       "deps": ["jquery"],
       "exports": "$"
     }

Ahora creamos una carpeta assets (puede ser cualquier otro nombre) dentro de src, y creamos el archivo main.scss (recordar la convención de sass, cuando el nombre comienza con _ es un partial y no genera css!!!).

El el archivo de estilos simplemente agregamos la siguiente línea para asegurarnos que se esta compilando el archivo sass como css.

h1 {
  background-color: red;
}

Además, modificaremos el archivo src/app.html para asegurarnos que los estilos que aplicamos esten modificando los elementos que necesitamos. Agregaremos un pequeño formulario de bootstrap con el siguiente código:

<template>
  <div class="container">
    <div class="row">
      <div class="col-xs-offset-3 col-sm-offset-3 col-md-offset-3
            col-lg-offset-3 col-xs-6 col-sm-6 col-md-6 col-lg-6">
        <h1>${message}</h1>
        <form action="" method="post" role="form">
          <legend>Form Title</legend>

          <div class="form-group">
            <label for="">Ejemplo</label>
            <input type="text" class="form-control" placeholder="Si">
          </div>

          <button type="submit" class="btn btn-primary">Submit</button>
        </form>
      </div>
    </div>
  </div>
</template>

Comenzamos la aplicación para ver si todo esta correcto con:

$ au run --watch

Con este comando debería poder verse la aplicación en 127.0.0.1:9000

Hola Mundo sin estilos :(
¿Qué ocurrió? El formulario se puede ver, pero no se aplicaron los estilos ni de nuestro archivo sass ni de bootstrap, malas noticias...

El problema es que aún no importamos el archivo sass que creamos a la página, para hacerlo modificamos nuevamente el archivo src/app.html y le agregamos la hoja de estilos con el tag require de la siguiente manera:

<template>
  <require from="./assets/main.css"></require>
  <div class="container">

Ahora la pantalla de inicio debería mostrarnos un fondo rojo en el tag h1.

Ehhhh ya se ve el cambio

Sin embargo aún no vemos los cambios en el formulario bootstrap, así que importaremos las hojas de estilo de bootstrap desde nuestro archivo sass (probaremos esta función porque cuando comence a utilizar SASS no se podía importar de distintos directorios, aunque si se podía hacerlo desde subdirectorios). Importar los estilo desde otro archivo sass es simplemente una forma de realizar esta operación, tambien se puede modificar los sources para que la tarea de gulp-sass genere el css automaticamente.

Ahora a lo nuestro, importemos las hojas de estilo de bootstrap en el archivo :

@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";

h1 {
  background-color: red;
}

Deberiamos poder observar los cambios de inmediato

Aurelia con bootstrap-sass

Y esta hecho, super simple, ya podemos utilizar sass (en este caso bootstrap-sass también) en nuestro proyecto con Aurelia. En los siguientes blogs comenzaremos a crear elementos y otras cosillas útiles, keep coding >_<

domingo, 8 de enero de 2017

Crear proyecto con AureliaJS

Hola de nuevo!!!, ahora crearemos un proyecto con AureliaJS, un framework para frontend que en mi opinión es mejor y más simple de utilizar que Angular (cada quien tiene sus gustos!!! jeje).

Comencemos, primero es necesario instalar aurelia-cli, lo cuál es súper simple con el siguiente comando:

$ sudo npm install -g aurelia-cli

Luego, iniciamos el proyecto:

$ au new NombreProyecto

A continuación, la consola de aurelia nos presentará una serie de opciones básicas para utilizar en nuestro proyecto, detallo las elecciones más comunes en la siguiente lista, en el orden dado por  aurelia-cli 0.24.0:
- 3 (Custom: para poder elegír las opciones que se adapten mejor a nuestro proyecto)
- 1 (Babel: que permite realizar la transpilación de esnext al javascript tradicional que todos los navegadores entienden)
- 1 (Default: no minimiza los tags de html)
- 3 (Sass: para realizar la compilación de nuestros estilos)
- 1 (Yes: porque realizar tests siempre es necesario, puede parecer que no pero creanme, es necesario)
- X (En la opción de escoger editor cada uno puede escoger el que tenga a la mano, en mi caso me enamoré de WebStorm así que escogere la opción 4)
- 1 (Luego uno para crear la estructura del proyecto)
- 1 (Por último uno nuevamente para que aurelia instale las dependencias que necesitamos para iniciar, de cualquier manera las dependencias pueden instalarse despues utilizando npm install)

Y listo!!! así de simple ya se tiene un proyecto inicial con Aurelia.

Para verificar que todo este funcionando, corremos la aplicación con:

$ au run --watch

La opción watch hace que cualquier cambio que hagamos en el código se vea reflejado en el navegador de manera automática.

Ojo!!!

En caso de que la aplicación no corra, probar con:

$ export NODE_ENV=dev
$ au run --watch

Eso es todo, ahora una imagen con Aurelia en toda su gloria >_< Keep Coding!!!
Aurelia en toda su gloria