Cómo configurar la autocompletar jquery-ui en Rails

Necesito ayuda sobre cómo implementar un autocompletado de jquery-ui en mi aplicación de Rails.

Quiero agregar autocompletado a un campo de texto donde el usuario puede ingresar el nombre de un cliente. Como puede haber cientos de clientes, tendré que extraer los valores de autocompletado sugeridos ‘de forma remota’, como en una tabla (al menos esto es lo que entiendo).

El punto principal que no entiendo es cómo proporcionar los valores sugeridos al cuadro de texto de autocompletado. He leído los documentos de jquery-ui, pero parece ser un poco denso en este asunto.

Así que lo que realmente busco es un ejemplo de cómo puedo hacer que esto funcione en una aplicación de Rails, no necesariamente una descripción completa de cómo se construye el javascript (eso es lo que el equipo de jquery-ui ha hecho por mí =)).

Por ejemplo, ¿cómo preparo los datos para la autocompletación y cómo adjunto la funcionalidad de autocompletado a un cuadro de texto?

Bueno, nunca obtuve una respuesta a mi pregunta anterior, así que terminé teniendo que resolverlo por mí mismo. Pensé que debería publicar la solución que surgió en caso de que haya otros tipos que se estén preguntando lo mismo.

Lo primero que debes saber es que esta es mi primera experiencia con JavaScript, y que estoy acabando con Rails. Así que, por favor, siéntase libre de editar, comente en cualquier lugar que sienta que me he equivocado con esto. Correcto o incorrecto, al menos sé que funciona de la manera que yo quería.

Creo que la mejor manera de mostrar esto es con el ejemplo. Así que lo siguiente es cómo obtuve el widget de autocompletar para que funcione en mi aplicación. Puede seguir adelante y poner el siguiente código en su aplicación, incluso si no comprende lo que está sucediendo, luego podemos repasar cómo funciona cada parte con el ejemplo. Después de esto, debe tener una idea de cómo modificarlo para su uso o refractarlo.

INCLUYA LA UI DE JQUERY EN SU APLICACIÓN DE RAILS.

Descargue una copia de jQuery UI y coloque jquery-ui-1.8.2.custom.min.js dentro de su directorio / public / javascript . También asegúrese de tener una copia de jQuery y que también esté en la misma carpeta.

Incluya el archivo jQuery UI y el archivo jQuery en su archivo application.html.erb como este.
(puede nombrar los archivos como lo desee, siempre y cuando coincidan)

<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %> 

En su descarga de jQuery UI, tendrá una carpeta que contiene todos sus datos de CSS. El nombre variará en función del tema que elija, por ejemplo, elegí el tema ‘ cupertino ‘. Coloque la carpeta completa que contiene sus datos de CSS en ‘ / public / stylesheets / ‘. Luego incluya el archivo CSS en su application.html.erb de esta manera.

 <%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %> 

EJEMPLO JAVASCRIPT AUTOCOMPLETO

Ahora tome el siguiente fragmento de código y colóquelo en una de sus ‘ nuevas ‘ vistas. Puedes usar esto en cualquier vista, pero te das cuenta de que literalmente la he tomado de una vista existente que pertenece a un controlador llamado ‘links_controller’, y está extrayendo datos de un ‘people_controller’. Espero que sepa lo suficiente sobre Rails para resolver lo que necesita cambiar para que esto funcione para usted.

– Comienza gran parte del código –

   

New link

<% form_for(@link) do |f| %> <%= f.error_messages %>

Select which person you want to link:

<%= f.label :rcvd_id %>
<%= f.text_field :rcvd_id %>

<%= f.label :link_type %>
<%= f.text_field :link_type %>

<%= f.label :summary %>
<%= f.text_area :summary %>

<%= f.label :active %>
<%= f.check_box :active %>

<%= f.submit 'Create' %>

<% end %>

– Terminar gran trozo de código –

Bien ahora para conectar los puntos.

PROPORCIONAR DATOS PARA AUTOCOMPLETE PARA UTILIZAR COMO SUGERENCIAS

Comencemos conectando algunos datos que el campo de texto de autocompletar puede mostrar en las sugerencias desplegables. El formato que utilizaremos es JSON, pero no se preocupe si no está familiarizado con él … tampoco lo estoy =). Es suficiente saber que es una forma de formatear texto para que otras partes de usted / otras aplicaciones puedan usarlo.

Los datos que el campo de texto necesitará para la autocompleta se especifican en la opción ‘ fuente: ‘. Como queremos enviar una lista de los nombres de personas y su ID a la autocompletar, colocaremos lo siguiente como fuente.

 source: '<%= people_path(:json) %>' 

El asistente de raíles anterior se traducirá a una cadena ” /people.json “. No necesita crear una página en ” /people.json “. Lo que debe hacer es decirle a su controlador de personas qué hacer cuando recibe una solicitud para / personas con el formato .json. Coloque lo siguiente en su controlador de personas:

 def index # I will explain this part in a moment. if params[:term] @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"]) else @people = Person.all end respond_to do |format| format.html # index.html.erb # Here is where you can specify how to handle the request for "/people.json" format.json { render :json => @people.to_json } end end 

Ahora tenemos a todas las personas de @personas enviadas al campo de texto de autocompletar. Esto trae al siguiente punto.

DATOS DEL FILTRO UTILIZADOS PARA LA SUGERENCIA AUTOCOMPLETA, BASADOS EN LA ENTRADA

¿Cómo sabe el campo de texto de autocompletar cómo filtrar los resultados en función de lo que escribe?

El widget de autocompletar asignado al campo de texto enviará lo que escribas al campo de texto como un parámetro a tu fuente: El parámetro que se envía es ” término “. Entonces, si tuvieras que escribir “Joe” en el campo de texto, estaríamos haciendo lo siguiente:

 /people.json?term=joe 

Es por eso que tenemos lo siguiente en el controlador:

 # If the autocomplete is used, it will send a parameter 'term', so we catch that here if params[:term] # Then we limit the number of records assigned to @people, by using the term value as a filter. @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"]) # In my example, I still need to access all records when I first render the page, so for normal use I assign all. This has nothing to do with the autocomplete, just showing you how I used it in my situation. else @people = Person.all end 

Ahora que hemos limitado el número de registros asignados a @personas en función de lo que se escribe en el campo de texto de autocompletar, ahora podemos convertirlo en formato JSON para las sugerencias de autocompletar.

 respond_to do |format| format.html # index.html.erb format.json { render :json => @people.to_json } end 

Ahora, simplemente revise los comentarios dentro del “Gran trozo de código” que debería explicar el rest de cómo se relaciona esto.

Al final, debe tener un campo de texto en su página que actúa como autocompletado y un campo oculto que enviará la ID en un parámetro a su controlador.

PERSONALIZA TU PROPIO AUTOCOMPLETE

Una vez que comprenda lo anterior y desee modificarlo para su uso, debe saber que el formato JSON devuelto por su controlador se ve así:

 [{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}] 

La forma de acceder a los diferentes valores de la cadena JSON en su javascript en este caso sería:

ui.item.person.name_of_some_attribute_such_as_given_name

Bastante simple. Es muy parecido a acceder a un atributo ActiveRecord en Rails.

Una última nota. Pasé mucho tiempo buscando una forma diferente de proporcionar el valor oculto, ya que pensé que esta función debería haber sido incorporada en el widget jquery. Sin embargo, éste no es el caso. Se muestra claramente en el ejemplo jQuery oficial que la forma de enviar un valor diferente y luego se selecciona como un parámetro, es usar un campo oculto.

Bueno, espero que eso ayude a alguien.

Valle

jQuery 1.9 / 1.10 eliminó la autocompletación de teclas y agregó uiAutocomplete

 .data("uiAutocomplete") instead of .data("autocomplete") 

Después de modificar a lo anterior, funcionó para mí.

Dale’s Answer es bastante el tutorial. Una cosa a tener en cuenta es que al usar su primera consulta, el origen de datos solo devolverá las coincidencias que comiencen con la cadena que escriba. Si desea buscar en cualquier parte de la palabra, debe cambiar:

 @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"]) 

a

 @people = Person.find(:all,:conditions => ['given_name LIKE ?', "%#{params[:term]}%"]) 

(se agregó un % extra a la consulta)

Básicamente, seguí los consejos de Dale a continuación, pero mis archivos de controlador y js eran ligeramente diferentes. Su versión me estaba dando problemas por alguna razón (tal vez por actualizaciones de jquery)

Contexto: estoy tratando de autocompletar nombres de DJ escritos por los usuarios, también un newb

Controlador de DJ

  class DjsController < ApplicationController def index if params[:term] @djs = Dj.is_dj.where('lower(name) LIKE ?', "%#{params[:term].downcase}%") respond_to do |format| format.html format.json { render :json => @djs.map(&:name) } end end end end 

archivo html.erb

   

Esta es una gran ayuda.

Además de eso, en caso de que necesite recuperar la URL de la imagen del usuario, es posible que no sea posible con to_json . Para eso agrega el siguiente código en el modelo.

 def avatar_url avatar.url(:thumb) end 

Y luego en el controlador en lugar de to_json use as_json

 respond_to do |format| format.json {render :json => @users.as_json(:only => [:id,:name,:username], :methods => [:avatar_url]) } end 

Es importante tener en cuenta que si su ‘fuente’ es relativamente pequeña, por ejemplo 50 elementos, la implementación debería ser diferente (y mucho más simple). Se menciona en el cuarto párrafo del documento oficial:

https://api.jqueryui.com/autocomplete/

Al usar datos locales, todo lo que necesita hacer es obtener los datos y pasarlos al método de autocompletar, y hará el filtrado por usted. No necesita ir y venir al servidor cada vez que se ingresa un término.

 function filterByTags(tags) { $("#stories-filter").autocomplete({ source: tags, autoFocus: true }); } $("#stories-filter").click(function() { $.ajax({ dataType: 'json', method: 'GET', url: 'tags/index', data: $(this).data('project-id'), success: function (response) { if(response.success) { var tags = response.data.tags; filterByTags(tags); } }, error: function (response) { if(response.status === 422) { var $errors = 'There are no tags in this project', $errorsContainer = $('.error-container'); $errorsContainer.append($errors); $errorsContainer.show(); } } }); });