Rails4 Autocomplete Gem – Guía rápida

Como estamos aprendiendo Rails en el curso de desarrollo de aplicaciones web del 9no cuatrimestre de ingeniería en TIC, para nuestra aplicación de proyecto necesitamos agregar la función de autocompletar, pues necesitamos localizar rápidamente los datos de un cliente si este ya está registrado en nuestra bd al momento de estar creando una nueva venta o pedido.

Para este propósito utilizaremos la gema rails4-autocomplete disponible en el repositorio de Ruby Gems https://rubygems.org/gems/rails4-autocomplete donde encontramos el link para acceder a su documentación oficial y guía detallada de su uso (http://rubydoc.info/gems/rails4-autocomplete/1.1.0/frames), es necesario aclarar que en este post se utiliza la información que en la documentación oficial se especifica.

Instalación:

En el Gemfile agregar la gema rails4-autocomplete

gem ‘rails4-autocomplete’

Esta gema requiere jQuery UI, si aún no la tenemos, entonces agregar también esta gema en el Gemfile

gem “jquery-ui-rails”

 

Ejecutar bundle install para instalar las gemas en el proyecto

sc1

 

 

 

Instaladas las gemas, se invoca al instalador de rails4-autocomplete

sc2

 

 

 

Después de esto veremos que en /public/javascripts se ha creado el archivo autocomplete-rails.js

A este archivo no se le harán modificaciones.

Estableciendo los require en js y css:

Para que los archivos necesarios de esta gema puedan ser incluidos en la funcionalidad de nuestra aplicación, debemos especificarlos en los assets application.js y application.css

en assets/javascripts/applitation.js, agreguemos los require

//= require jquery.ui.all
//= require autocomplete-rails

para quedar algo similar a este ejemplo

sc3

 

 

 

 

 

 

en assets/stylesheets/applitation.css, agreguemos los require

*= require jquery.ui.theme
*= require jquery.ui.all

para quedar similar al ejemplo

sc4

 

 

 

 

 

Modificando nuestro controlador ClientsController:

debemos crear la acción que será llamada por el textbox de autocomplementar, para esto, en la guía oficial nos proporciona una estructura donde se indica

  • el nombre de la clase de respuesta
  • el nombre del campo donde se realiza la búsqueda
  • el modo de búsqueda (cualquier coincidencia o solo valores que empiecen por el criterio de búsqueda)
  • extra data (columnas o scopes como valores que deben ser devueltos en los resultados, ya que este gem sólo devuelve como resultado el id y el valor del campo de búsqueda)
  • y el encodificador de JSON que se utiliza para devolver la respuesta

Para este ejemplo, la acción ha quedado como:

sc5

 

 

 

 

El código para copiar (incluye parte del controlador como ejemplo):

class ClientsController < ApplicationController
 before_action :set_client, only: [:show, :edit, :update, :destroy]
 
 autocomplete :client, :nombre, :display_value => :nombre, :extra_data => [:direccion, :telefono, :email] do |items|
 respond_to do |format|
 format.json { render :json => @items }
 end
end
#fin de la acción autocomplete

¿Qué de las partes de este ejemplo?

  • :client, :nombre respresenta la clase y el campo de búsqueda
  • :display_value => :nombre es el campo a mostrar como respuesta, en este ejemplo está de más al ser el mismo campo de búsqueda, así que si no lo agregan, dará el mismo resultado 😀
  • :extra_data => [ … ] se incluyen los nombres de los atributos del modelo que deben incluirse en la respuesta, para nuestro ejemplo, las necesitamos porque queremos mostrar los datos del cliente 😀
  • do |items| significa que procesaremos el resultado como este alias
  • respond_to do |format|
    format.json { render :json => @items }
    end   es la configuración del tipo de respuesta que puede ofrecer nuestra acción, en este caso solo se ha agregado el render json para devolver el resultado en este formato, lo necesita el autocomplete para procesar los resultados.

Modificación del routes.rb

Es necesaria la especificación de la ruta y modo de acceso a la acción que se ha agregado a ClientsController.

sc6

 

 

 

 

Nuestra acción solo permitirá llamadas de tipo get con esta ruta.

Modificación en la vista:

En nuestro formulario de venta, localizado en /app/views/sales/_form.html.erb nos ubicamos en la parte donde se agregan los input de los datos del cliente:

En este caso, queremos que el input del nombre del cliente se convierta en un autocomplete.

Antes de realizar la modificación, este es el código que se tiene:

<%= c.text_field :nombre, :placeholder => "Nombre del cliente" %>

Ahora utilizamos la sintaxis referida en la documentación oficial ‘data-delimiter’ => ‘,’

f.autocomplete_field :brand_name, autocomplete_brand_name_products_path

Ésta indica que se debe especificar el nombre del atributo del modelo, y el path de acceso a la acción de autocompletar que se ha creado en el controlador, también indica las opciones de este nuevo elemento de formulario, una de ellas son los elementos que deben actualizarse con los datos del elemento seleccionado en el autocompletar.

El código de nuestro elemento de formulario queda como:

<%= c.autocomplete_field :nombre, autocomplete_client_nombre_clients_path, :placeholder => "Nombre del cliente", :multiple => false, :update_elements => {:direccion => '#cliAhora comprobar que funcionaent_direccion', :telefono => '#client_telefono', :email 'data-delimiter' => ',' 'data-delimiter' => ',' => "#client_email"} %>

 

Donde:

  • autocomplete_client_nombre_clients_path es la ruta de acceso a la acción
  • :multiple => false indicando que los valores elegidos en el autcompletar no se envían como arreglo, sólo necesitamos un sólo valor, el nombre.
  • :update_elements => {:direccion => ‘#client_direccion’, :telefono => ‘Ahora comprobar que funciona#client_telefono’, :email => “#client_email”} indican los atributos e id’s de los elementos quAhora comprobar que funcionae deben actualizarse con los datos del elemento seleccionado.

 

Ahora comprobar que funciona

ejecuta el servidor

$ rails s

accede a crear una nueva venta

en el textbox del nombre del cliente ingresa una parte de un nombre que ya exista

sc8

 

 

 

 

Al seleccionar una opción, los elementos indicados también se les asigna su valor.

sc9

 

 

 

 

 

El hecho de tomar los valore sy asignarlos en los cuadros de texto, no garantiza la asociación de la venta con el cliente, por lo que es necesario agregar un fragmento de js que tome el id y lo asigne al input con el id sale_client_id (que se trata del atributo @sale.client_id) y al input con el id client_id (que se trata del atributo de @sale.client.id) .

Entonces en assets/javascripts/sales.js.coffee podemos agregar el código coffeescript para este propósito, pero como aún nos hace falta aprender coffeescript, lo agregaremos en application.js junto al código que se ha escrito para el manejo de la venta.

Dentro de la función $(document).ready() agregaremos el siguiente fragmento

$('#client_nombre').on('railsAutocomplete.select', function(event, data){
 //poner valores en input requeridos con datos del cliente
 $("#client_id").val(data.item.id);
 $("#sale_client_id").val(data.item.id);
});

Se trata del control del nuevo evento railsAutocomplete.select proporcionado por el gem, aquí indicamos los id de los input que deben llenarse con el id del elemento seleccionado, ya que esto no puede hacerse con el parámetro update_elements en el formulario.

sc10

 

 

 

 

 

 

Como vemos entonces, ya se actualiza el valor del ID del cliente para la venta.

pero ¿qué pasa si borramos el nombre del cliente? veremos que los campos update se limpian pero no el id del cliente que se había seleccionado, esto hace que la relación se mantenga a pesar de que hemos quitado el cliente.

Para solucionar esto, es necesario reaccionar al evento change de nuestro txt, de modo que cuando se encuentre vacío, se quite también el id de los elementos que se completaron desde js, entonces agregamos también este fragmento al js.

 //prevenir que puedan quedarse datos del cliente
 $('#client_nombre').on("keypress",function(event) {
   if($(this).val() == "")
   {
     $("#client_id").val("");
     $("#sale_client_id").val("");
   }
 });

Al borrar entonces el valor del txt y volver a escribir, todos los datos se limpiaran asegurando un poco que no se mantenga ninguna relación con un cliente.

Existen otras opciones para crear un autocompletar, como es el caso de jQuery UI autocomplete, en el cual también tendríamos que crear nuestra acción con respuesta JSON, y crear los JS donde indiquemos el source del autocomplete y procesar manualmente el llenado de los datos, sin embargo, con este gem fue más fácil su implementación.

Código fuente del proyecto: https://github.com/afelipelc/DemoRailsVentas/

go to: rails4-autocomplete guide

 

pd. si encuentras un detalle con el seguimiento de esta información, agrega tu comentario para realizar el ajuste correspondiente.

Anuncios

Escribe tu comentario:

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s