2008-09-17 25 views
4

Je souhaite avoir une zone de texte dans laquelle l'utilisateur peut saisir une liste Ajax contenant les noms de mon modèle. Lorsque l'utilisateur en sélectionne une, je veux que le code HTML enregistre l'ID du modèle et l'utilise lorsque le formulaire est soumis.Dans Rails, quelle est la meilleure façon d'obtenir la saisie semi-automatique qui affiche des noms mais utilise des ID?

J'ai été piquer sur le plugin auto_complete qui a été excisé dans Rails 2, mais il semble n'avoir aucune idée que cela pourrait être utile. Il y a un Railscast episode qui couvre l'utilisation de ce plugin, mais il ne touche pas à ce sujet. Les commentaires point out that it could be an issue, et point to model_auto_completer as a possible solution, qui semble fonctionner si les éléments consultés sont des chaînes simples, mais le texte inséré comprend beaucoup d'espaces indésirables si (comme je voudrais le faire), vous incluez une image dans les éléments de la liste, despite what the documentation says.

Je pourrais probablement pirater model_auto_completer en forme, et je peux encore finir par le faire, mais je suis impatient de savoir s'il y a de meilleures options là-bas.

Répondre

0

J'ai un correctif galvaudé pour les espaces indésirables de l'image. J'ai ajouté un :after_update_element => "trimSelectedItem" au hash des options du model_auto_completer (c'est le premier hash des trois donnés). Mon trimSelectedItem trouve alors le sous-élément approprié et utilise le contenu de ce pour la valeur de l'élément:

function trimSelectedItem(element, value, hiddenField, modelID) { 
    var span = value.down('span.display-text') 
    console.log(span) 
    var text = span.innerText || span.textContent 
    console.log(text) 
    element.value = text 
} 

Cependant, ceci alors va à l'encontre de l'option :allow_free_text, qui par défaut modifie le texte dès que le texte La boîte perd le focus si le texte à l'intérieur n'est pas un élément "valide" de la liste. J'ai donc dû désactiver cela aussi, en passant :allow_free_text => true dans le hachage des options (encore une fois, le premier hachage). Je préférerais que ça reste, cependant.

donc mon appel en cours pour créer l'autocomplétion est:

<%= model_auto_completer(
    "line_items_info[][name]", "", 
    "line_items_info[][id]", "", 
    {:url => formatted_products_path(:js), 
    :after_update_element => "trimSelectedItem", 
    :allow_free_text => true}, 
    {:class => 'product-selector'}, 
    {:method => 'GET', :param_name => 'q'}) %> 

et les produits/index.js.erb est:

<ul class='products'> 
    <%- for product in @products -%> 
    <li id="<%= dom_id(product) %>"> 
      <%= image_tag image_product_path(product), :alt => "" %> 
      <span class='display-text'><%=h product.name %></span> 
    </li> 
    <%- end -%> 
</ul> 
1

J'ai roulé le mien. Le processus est un peu compliqué, mais ...

Je viens de créer un champ text_field sur le formulaire avec un observateur. Lorsque vous commencez à taper dans le champ de texte, l'observateur envoie la chaîne de recherche et le contrôleur renvoie une liste d'objets (maximum de 10).

Les objets sont ensuite envoyés à rendre via un partiel qui remplit les résultats de la recherche semi-automatique dynamique. Le partiel remplit en fait les lignes link_to_remote qui reviennent au contrôleur. Link_to_remote envoie l'identifiant de la sélection de l'utilisateur, puis un RJS nettoie la recherche, remplit le nom dans le champ de texte, puis place l'identifiant sélectionné dans un champ de formulaire caché.

Ouf ... Je n'ai pas trouvé de plugin pour faire ça à ce moment là, alors j'ai roulé le mien, j'espère que tout cela a du sens.