Ruby on Rails, parte 18: Javascript y CoffeeScript

5 Jul

Hasta ahora hemos trabajado con la interfaz de nuestro sitio, sabemos que a través de las vistas es donde se encuentra la salida de código html, utilizamos helpers y hojas de estilo también, pero nos está faltando una de las partes más importantes de una página web: Javascript.

Creo que no está de más recordar que Javascript es un lenguaje de programación del navegador, osea así como RoR es el encargado de seguir las indicaciones que el programador escribe para el funcionamiento del servidor, Javascript es el lenguaje de programación que se encarga de todo lo relacionado con el browser, ya sea Chrome, Firefox, Explorer, etc. Para pulsar un botón y qué suceda algo, para validar campos de formulario, modificar partes de la interfaz dinamicamente; necesitamos de Javascript.

Sin más palabrería haremos lo siguiente: vamos a crear un proyecto nuevo o a usar alguno que ya tengamos creados para testear. Yo en mi caso voy a usar el que creé el posteo pasado llamado clases_de_guitarra.

En esta ocasión crearemos un controlador llamado alumnos y una acción llamada calificar. Voy a aclarar que en este posteo no voy a trabajar con base de datos para no irme demasiado por las ramas, ya que hemos tenido tiempo para trabajar con base de datos en las últimas publicaciones.

Entramos al proyecto:

cd proyecto

Creamos el controlador y la acción:

rails g controller Alumnos calificar

 

Javascript, un viejo conocido

Al crear un controlador no sólo se crea el controlador y las vistas, también se crean otros archivos como una hoja de estilos con extensión .scss (ya veremos más adelante de qué se trata) y un archivo .coffee, en nuestro caso alumnos.js.coffee. Por el momento ignoremos estos archivos.

Vamos a ir a app -> views -> layouts -> application.html.erb, abrimos este archivo. Ya lo hemos abierto muchas veces pero hay una línea que hasta ahora hemos ignorado:

<%= javascript_include_tag "application" %>

Esto es un helper que permite cargar archivos Javascript, en este caso un archivo llamado “application”, así que vamos a buscar ese archivo en app -> assets -> javascripts -> application.js y lo abrimos. Es un archivo Javascript con unos comentarios, sin embargo debajo de todo abra unas líneas con este aspecto:

//= require jquery
//= require jquery_ujs
//= require_tree .

Las dos primeras cargarán dos archivos jquery, pero la última cargará todo los .js o .js.coffee que se encuentran dentro de app -> assets -> javascript. Esto desde mi punto de vista no nos sirve ya que debería haber un Javascript por cada vista y no hay razón para que todos se carguen en todas las vistas así que borramos este último:

//= require_tree .

Y dejamos los dos primeros:

//= require jquery
//= require jquery_ujs

Ahora bien, ambos archivos entonces se cargarán en todas las vistas, esto no está mal, nosotros necesitaremos Jquery en todas las vistas, o por lo menos en la mayoría, en caso de que necesites cargar otro archivo Javascript deberías agregar una nueva línea, por ejemplo:

//= require jquery
//= require jquery_ujs
//= require otro_javascript

O bien ir a application.html.erb y agregarlo con el helper:

<%= javascript_include_tag "application" %>
<%= javascript_include_tag "otro_javascript" %>

Dentro del archivo Javascript application.js además de importar los Jquery y los archivos que quieras agregar también podemos crear código que estará disponible en toda la página. Vamos a probarlo escribiendo las siguientes líneas:

$(document).ready(function(){
   alert("Javascript y Jquery estan cargados.");
});

Ahora reiniciamos el servidor:

rails s

Y entramos a http://localhost:3000/alumnos/calificar. Si apareció la ventana alert con el mensaje: “Javascript y Jquery estan cargados.” vamos bien. Ahora borramos las líneas que acabamos de crear.

Ok, todo lo que haré a continuación es sólo una costumbre a la hora de programar, eso no significa que esté bien, mal o que estés obligado/a a hacer lo mismo, yo por cada vista tendré un javascript y además tendré uno o más javascript que se repitan en todas las páginas para funcionalidades necesarias en todas, en este caso los dos archivos jquery y application.js.

Haremos lo siguiente, tendremos un formulario para ingresar el nombre de un alumno y una calificación. Así que vamos a app -> views -> alumnos -> calificar.html.erb y escribimos lo siguiente:

<h2> Calificaciones </h2>
<%= form_tag do %>
   <%= label_tag "nombre", "Nombre del alumno" %>
   <br />
   <%= text_field_tag "nombre", "" %>
   <br />
   <%= label_tag "calificacion", "Calificación" %>
   <br />
   <%= number_field_tag "calificacion", "", {:min => 0, :max => 10} %>
   <br />
   <%= submit_tag "Agregar", {:type => "button", :id => "boton_agregar"} %>
<% end %>
<table>
   <thead>
   <tr>
      <th style="width: 200px;"> Nombre del alumno </th>
      <th style="width: 100px;"> Calificación </th>
      <th style="width: 50px;"></th>
   </tr>
   </thead>
   <tbody id="lista">
   </tbody>
</table>

Ahora vamos a app -> assets -> javascripts, dentro de esta carpeta debería haberse creado cuando generamos el controlador y la acción un archivo llamado “alumnos.js.coffee” de ser así vamos a eliminarlo y en su lugar vamos a crear una carpeta llamada “alumnos” y dentro de esta carpeta un archivo javascript “calificar.js”, esto, insisto, es sólo una forma de trabajar mía no significa que deba ser así. Ahora dentro de ese archivo vamos a crear la lógica de la vista que acabamos de crear, al pulsar el botón deberá agregarse en la tabla un nuevo item con el nombre y la calificación del alumno, y además un link para eliminar el item. Así que dentro del archivo escribimos esto:

function calificar(){
   this.iniciar = function(){
      this.agregarItem();
      this.eliminarItem();
   };
   this.agregarItem = function(){
      $("#boton_agregar").click(function(){
         var nombre = $("#nombre").val();
         var calificacion = $("#calificacion").val();
         var item;
         item += '<tr>';
         item += '<td style="text-align: center"> ' + nombre + ' </td>';
         item += '<td style="text-align: center"> ' + calificacion + ' </td>';
         item += '<td style="text-align: center"> <a class="eliminar_item" href="javascript:void(0)"> Eliminar </a> </td>';
         item += '</tr>';
         $("#lista").append(item);
         $("#nombre").val("");
         $("#calificacion").val("");
      });
   };
   this.eliminarItem = function(){
      $("#lista").delegate(".eliminar_item", "click", function(){
         $(this).parents("tr").remove();
      });
   };
   return this.iniciar();
};
$(document).ready(function(){
   calificar();
});

Bien, si estás familiarizado/a con Javascript y Jquery, no debería resultarte difícil de entender. Es simplemente una función llamada calificar() que dentro tiene tres métodos, agregarItem() para agregar el nombre y calificación del alumno a la lista; eliminarItem() para borrar un item de la lista; y por último iniciar(), esta última llamará a las otras dos y será el método que se ejecute al llamar a la función calificar().

Luego con $(document).ready llamamos a la función para que una vez que el browser esté cargado ejecute calificar().

Ahora sólo falta cargar el código Javascript dentro de nuestra archivo de vista, así que volvemos a app -> views -> alumnos -> calificar.html.erb y en alguna parte del código agregamos lo siguiente:

<%= javascript_include_tag "alumnos/calificar" %>

El helper cargará el archivo y ahora el javascript funciona.

 

CoffeeScript, ¿Javascript o… qué es esto?

Hace unos años se inventó este lenguaje llamado CoffeeScript, esto no es una alternativa a Javascript como lo puede ser Dart, sino que nos permitirá escribir código más amigable que Javascript, pero luego nuestra aplicación lo convertirá en código .js y eso será lo que terminará leyendo el navegador: un Javascript.

¡Comencemos!

Vamos nuestro archivo app -> assets -> javascripts -> alumnos -> calificar.js y cambiamos la extensión de este archivo de modo que el nombre sea calificar.js.coffee. Si ahora recargamos la página Rails nos devolverá un error, esto es porque la sintaxis de CoffeeScript es diferente a la de Javascript.

Acá les dejo la página con la documentación de CoffeeScript:

http://jashkenas.github.com/coffee-script/

Si le pegamos una pequeña hojeada veremos las diferencias que tiene este lenguaje con Javascript. Por ejemplo, en CoffeeScript las variables no deben definirse con la palabra var. Por ejemplo, lo que en Javascript es:

var nombre = "Fernando";

En CoffeeScript es:

nombre = "Fernando"

Tampoco podemos usar la palabra function. Si quisiéramos crear una función que en Javascript es:

function sumar(num1, num2){
   alert(num1 + num2);
}

En CoffeeScript:

sumar = (num1, num2) ->
   alert num1 + num2

En caso de que quieras escribir un código Javascript que no sepas como es en CoffeeScript podés visitar este sitio:

http://js2coffee.org/

Que te permitirá escribir el código Javascript y te lo convertirá a CoffeeScript y viceversa.

Pero volviendo a nuestra aplicación habrá que cambiar el código que daba error por un código CoffeeScript para que funcione, así que vamos a modificar el archivo calificar.js.coffee por lo siguiente:

calificar = () ->
   this.iniciar = () ->
      this.agregarItem();
      this.eliminarItem();
   this.agregarItem = () ->
      $("#boton_agregar").click ->
         nombre = $("#nombre").val();
         calificacion = $("#calificacion").val();
         item = '';
         item += '<tr>';
         item += '<td style="text-align: center"> ' + nombre + ' </td>';
         item += '<td style="text-align: center"> ' + calificacion + ' </td>';
         item += '<td style="text-align: center"> <a class="eliminar_item" href="javascript:void(0)"> Eliminar </a> </td>';
         item += '</tr>';
         $("#lista").append(item);
         $("#nombre").val("");
         $("#calificacion").val("");
   this.eliminarItem = () ->
      $("#lista").delegate(".eliminar_item", "click", ->
         $(this).parents("tr").remove();
      );
   return this.iniciar();
$(document).ready ->
   calificar();

 

Usar Javascript o CoffeeScript dependerá de vos. En mi caso yo usaría Javascript para todo lo relacionado con librerías, archivos disponibles en todo el sitio y CoffeScript lo dejaría para la lógica de cada acción, osea que por cada acción tendrá un .js.coffee.

Saludos

Anterior: Ruby on Rails, parte 17: Scaffolding

Siguiente: Ruby on Rails, parte 19: Ajax

 

Redes sociables

    5 thoughts on “Ruby on Rails, parte 18: Javascript y CoffeeScript

    1. Estimado, darte las gracias por lo que aprendí en tus tutoriales de rails, ahora que ya sé un poco más de lo básico, me gustaría por ayudarte a seguir desarrollando este tutorial con un post relacionado a la continuación de esto, puede ser el uso de alguna gema como inherited resources, active admin, carrierwave, si te interesa me avisas.

      Saludos.

      Sergio.

      • Sergio, la verdad es que yo no retomé el tutorial de RoR, porque probé otras tecnologías como Laravel o Node.js/Express, y como en mi trabajo desarrollo con PHP y nunca con RoR, entonces no me dediqué más a investigar.

        Pero lo que me decís me parece muy bueno, si querés podés enviarme algún material, o algún enlace a algún sitio, ya sea tuyo o de otra persona, de los temas que vos creás.

        Gracias, por pasarte.

        Saludos!

    2. Estimado,
      He estado un poco ocupado con el trabajo, pero este fin de semana voy a armar algo con rails 4 más active admin y te envío.

      Saludos.

      Sergio.

    Comments are closed.