Question

J'ai besoin d'aide sur la façon de mettre en œuvre un jquery-ui autocomplete dans mon application Rails.

Je veux ajouter autocomplétion à un champ de texte où l'utilisateur peut entrer dans un nom de client. Comme il peut y avoir des centaines de clients, je dois tirer les valeurs autocomplémentation proposées « à distance », comme, d'une table (au moins ce que je comprends).

Le point principal que je suis à défaut de comprendre est comment fournir les valeurs proposées à la zone de texte de saisie semi-automatique. J'ai lu les docs jquery-ui, mais il me semble être un peu dense à ce sujet.

Alors, ce que je suis vraiment après un exemple de la façon dont je peux obtenir ce travail dans une application Rails, pas nécessairement une description complète de la façon dont le javascript est construit (c'est ce que l'équipe jquery-ui a fait pour moi =) ).

Par exemple, comment puis-je préparer les données pour la saisie semi-automatique, et comment puis-je attacher la fonctionnalité de saisie semi-automatique à une zone de texte.

Était-ce utile?

La solution

Eh bien, je ne ai jamais eu de réponse à ma question ci-dessus, donc je fini par avoir à comprendre pour moi-même. Je pensais que je devrais poster la solution que je suis venu avec dans le cas où il y a d'autres gars là-bas qui se demandent la même chose.

La première chose que vous devez savoir est que c'est ma première expérience avec le javascript, et je suis tout simplement y arrive Rails. Donc, par tous les moyens, ne hésitez pas à modifier, commentaire où vous sentez que je suis allé mal à cela. Tort ou à raison d'au moins je sais qu'il fonctionne comme je le voulais.

Je pense que la meilleure façon de montrer par l'exemple. Donc, ce qui suit est la façon dont je suis le widget autocomplete à travailler dans mon application. Vous pouvez aller de l'avant et mettre le code suivant dans votre application, même si vous ne comprenez pas ce qui se passe, alors nous pouvons aller sur la façon dont chaque partie travaille par exemple. Après cela, vous devriez avoir une idée sur la façon de le modifier pour votre usage ou réfracteurs il.


INCLURE DANS VOTRE JQUERY UI RAILS APP.

Télécharger une copie de la jQuery UI et lieu jquery-ui-1.8.2.custom. min.js dans / public / javascript répertoire. De plus, assurez-vous que vous avez une copie de jQuery lui-même et que ce soit aussi dans le même dossier.

Inclure le fichier jQuery UI et le fichier jQuery dans votre application.html.erb fichier comme celui-ci.
(vous pouvez nommer les fichiers que vous plaisez aussi longtemps qu'ils correspondent)

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

Dans votre téléchargement jQuery UI, vous aurez un dossier contenant toutes vos données CSS. Le nom varie en fonction du thème que vous avez choisi, par exemple, j'ai choisi le thème ' cupertino . Placez le dossier complet contenant vos données CSS dans ' / public / stylesheets / . Ensuite, inclure le fichier CSS dans votre application.html.erb comme celui-ci.

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


Exemple autoComplete JAVASCRIPT

Maintenant, prenez le morceau de code suivant et placez-le dans un de vos « nouvelles » vues. Vous pouvez l'utiliser dans une vue, mais se rendre compte que je l'ai littéralement pris d'une vue existante appartenant à un contrôleur appelé « links_controller », et il tire des données d'un « people_controller ». Nous espérons que vous en savez assez sur Rails pour travailler ce que vous devez changer pour que cela fonctionne pour vous.

- Begin gros morceau de code -

    <script type="text/javascript">
    $(function() {

 // Below is the name of the textfield that will be autocomplete    
    $('#select_origin').autocomplete({
 // This shows the min length of charcters that must be typed before the autocomplete looks for a match.
            minLength: 2,
 // This is the source of the auocomplete suggestions. In this case a list of names from the people controller, in JSON format.
            source: '<%= people_path(:json) %>',
  // This updates the textfield when you move the updown the suggestions list, with your keyboard. In our case it will reflect the same value that you see in the suggestions which is the person.given_name.
            focus: function(event, ui) {
                $('#select_origin').val(ui.item.person.given_name);
                return false;
            },
 // Once a value in the drop down list is selected, do the following:
            select: function(event, ui) {
 // place the person.given_name value into the textfield called 'select_origin'...
                $('#select_origin').val(ui.item.person.given_name);
 // and place the person.id into the hidden textfield called 'link_origin_id'. 
        $('#link_origin_id').val(ui.item.person.id);
                return false;
            }
        })
 // The below code is straight from the jQuery example. It formats what data is displayed in the dropdown box, and can be customized.
        .data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
 // For now which just want to show the person.given_name in the list.
                .append( "<a>" + item.person.given_name + "</a>" )
                .appendTo( ul );
        };
    });
    </script>



<h1>New link</h1>

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

<!-- Place the following text fields in your form, the names are not important. What is important is that they match the names in your javascript above -->
  <p>
        Select which person you want to link:<br /> 
<!-- This is the textfield that will autocomplete. What is displayed here is for the user to see but the data will not go anywhere -->
        <input id="select_origin"/>
<!-- This is the hidden textfield that will be given the Persons ID based on who is selected. This value will be sent as a parameter -->
      <input id="link_origin_id" name="link[origin_id]" type="hidden"/>
  </p>
<!-- end of notes -->
  <p>
    <%= f.label :rcvd_id %><br />
    <%= f.text_field :rcvd_id %>
  </p>
  <p>
    <%= f.label :link_type %><br />
    <%= f.text_field :link_type %>
  </p>
  <p>
    <%= f.label :summary %><br />
    <%= f.text_area :summary %>
  </p>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

- Fin Big Chunk du Code -

Bon maintenant pour relier les points.


SUGGESTIONS DE DONNEES POUR FOURNIR saisie semi-automatique à utiliser comme

Commençons par connecter des données que le champ de texte de saisie semi-automatique peut afficher dans le menu déroulant des suggestions. Le format que nous allons utiliser est JSON, mais ne vous inquiétez pas si vous n'êtes pas familier avec elle ... je ne suis point =). Il est assez bon de savoir qu'il est un moyen de format texte afin que d'autres parties de la vôtre / d'autres applications peuvent l'utiliser.

Les données du champ de texte aura besoin pour la saisie semi-automatique est spécifié dans le source: 'option. Parce que nous voulons envoyer une liste des noms des peuples et leur carte d'identité à la saisie semi-automatique, nous allons mettre les éléments suivants comme source.

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

Les rails Helper ci-dessus se traduira par une chaîne " /people.json ". Vous n'avez pas besoin de créer une page à " /people.json ". Ce que vous avez besoin de faire est de dire votre people_controller ce qu'il faut faire quand il reçoit une demande de / personnes avec le format .json. Il faut mettre dans votre people_controller:

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

Maintenant, nous avons tous les gens @people être envoyés au textfield autocomplete. Cela fait apparaître le point suivant.


DATA filtre utilisé pour SUGGESTION saisie semi-automatique, fonction de l'entrée

Comment le savoir autocomplete textfield comment filtrer les résultats en fonction de ce que vous tapez?

Le widget de saisie semi-automatique affecté à l'textfield envoie tout ce que vous tapezdans le champ de texte en tant que paramètre à votre source :. Le paramètre envoyé est " terme ". Donc, si vous tapez « Joe » dans le champ de texte, nous ferions ce qui suit:

/people.json?term=joe

C'est pourquoi nous avons ce qui suit dans le contrôleur:

# 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

Maintenant que nous avons limité le nombre d'enregistrements attribués à @people en fonction de ce qui est tapé dans le champ de texte de saisie semi-automatique, nous pouvons maintenant transformer en format JSON pour les suggestions de saisie semi-automatique.

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

Maintenant, juste en revue les commentaires à l'intérieur du « Big Chunk of Code » qui devrait expliquer le reste de la façon dont ce lien ensemble.

A la fin, vous devriez avoir un champ de texte sur votre page qui agit comme autocomplete et un champ caché qui envoie l'ID dans un paramètre à votre contrôleur.


adaptez votre propre saisie semi-automatique

Une fois que vous comprenez ce qui précède et vous souhaitez le modifier pour votre utilisation, vous devez savoir que le format JSON retour de votre apparence de contrôleur comme ceci:

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

La façon d'accéder aux différentes valeurs de la chaîne JSON dans votre javascript dans ce cas serait:

ui.item.person.name_of_some_attribute_such_as_given_name

Jolie, simple. Beaucoup comme l'accès à un attribut ActiveRecord dans Rails.

Une dernière note. J'ai passé beaucoup de temps à la recherche d'une autre façon de fournir la valeur cachée, car je pensais que cette fonction aurait dû être intégrée dans le widget jquery. Cependant, ce n'est pas le cas. Il est clairement indiqué dans l'exemple de jQuery officiel que le moyen d'envoyer une valeur différente alors sélectionnée en tant que paramètre, est d'utiliser un champ caché.

Eh bien, je espère que quelqu'un aide.

Dale

Autres conseils

jQuery 1,9 / 1,10 éliminé le remplissage automatique du clavier et ajouté uiAutocomplete

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

Après avoir modifié ci-dessus, il a travaillé pour moi.

Réponse de Dale est tout à fait le tutoriel. Une chose à noter est que l'utilisation de votre première requête, la source de données ne renverrait aussi Début avec la chaîne que vous tapez. Si vous voulez rechercher sur le mot, vous devez changer:

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

à

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

(ajouté un % supplémentaire à la requête)

Je essentiellement suivi les conseils de Dale ci-dessous, mais mes fichiers de contrôleur et js ont été diff- légèrement sa version a été me donne des problèmes pour une raison quelconque (peut-être bc des mises à jour jquery)

Contexte: Je suis en train de noms de saisie semi-automatique de DJ tapés par les utilisateurs - aussi newb

DJ Controller

 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

fichier html.erb

  <script type="text/javascript">

$(function() {  
    $('#select_origin').autocomplete({
        source: '<%= djs_path(:json) %>'
      })

    $('.submit-comment').click(function(){
      var dj_name = $('#select_origin').val();
      $('#link_origin_id').val(dj_name);
    })

})

</script>

Ceci est une grande aide.

En plus en cas si vous avez besoin d'aller chercher url de l'image de l'utilisateur, il pourrait ne pas être possible avec to_json. Pour cela ajouter le code suivant dans le modèle.

def avatar_url
    avatar.url(:thumb)
end

Et puis dans le contrôleur au lieu de to_json utilisation as_json

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

Il est important de noter que si votre « source » est relativement faible, par exemple 50 éléments, la mise en œuvre devrait être différente (et beaucoup plus simple). Il est mentionné dans le quatrième paragraphe du document officiel:

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

Lors de l'utilisation des données locales tout ce que vous devez faire est d'obtenir les données et le transmettre à la méthode de saisie semi-automatique, et il fera le filtrage pour vous. Vous n'avez pas besoin de revenir en arrière au serveur chaque fois qu'un terme es entré.

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();
      }
    }
  });
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top