Cette fois, à propos de l'implémentation de la fonction de recherche séquentielle Je n'ai pas beaucoup compris quand je l'ai implémenté moi-même en regardant le programme, donc je le posterai avec la signification du résultat.
La fonction de recherche séquentielle est, par exemple, lorsque les balises "ruby", "python" et "ruby on rails" existent déjà dans la base de données, et lorsque la lettre r est saisie, "ruby" et "ruby on rails" qui correspondent à la lettre r Est une fonction qui s'affiche instantanément à l'écran en tant que candidat.
Communément appelée ** Recherche incrémentielle **.
Qu'est-ce que la recherche incrémentielle? Il s'agit d'une fonction de recherche qui recherche automatiquement chaque fois que vous entrez un caractère. Il est implémenté en utilisant Ajax de JS.
Commentez Turbolinks pour que tag.js puisse être chargé.
javascript/packs/application.js
require("@rails/ujs").start()
// require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("../tag")
Créez et modifiez tag.js.
javascript/tag.js
if (location.pathname.match("posts/new")){
window.addEventListener("load", (e) => {
const inputElement = document.getElementById("post_tag_name");
inputElement.addEventListener("keyup", (e) => {
const input = document.getElementById("post_tag_name").value;
const xhr = new XMLHttpRequest();
xhr.open("GET", `search/?input=${input}`, true);
xhr.responseType = "json";
xhr.send();
xhr.onload = () => {
const tagName = xhr.response.keyword;
const searchResult = document.getElementById('search-result')
searchResult.innerHTML = ''
tagName.forEach(function(tag){
const parentsElement = document.createElement('div')
const childElement = document.createElement('div')
parentsElement.setAttribute('id', 'parents')
childElement.setAttribute('id', tag.id )
childElement.setAttribute('class', 'child' )
parentsElement.appendChild(childElement)
childElement.innerHTML = tag.name
searchResult.appendChild(parentsElement)
const clickElement = document.getElementById(tag.id)
clickElement.addEventListener("click", () => {
document.getElementById("post_tag_name").value = clickElement.textContent;
clickElement.remove();
})
})
}
});
})
};
De là, regardons de plus près le code.
javascript/tag.js
const input = document.getElementById("post_tag_name").value;
const xhr = new XMLHttpRequest();
xhr.open("GET", `search/?input=${input}`, true);
xhr.responseType = "json";
xhr.send();
Ici, Ajax est décrit après avoir assigné la valeur entrée dans l'élément avec le nom d'ID post_tag_name à "input".
Dans une édition ultérieure, nous définirons le routage associé à l'action de recherche, donc définissez le chemin d'accès à l'action de recherche avec la "méthode ouverte". À ce stade, la valeur affectée à «entrée» est définie comme paramètre de requête. De plus, le type de données de la réponse est spécifié comme "json" pour la transmission.
De plus, nous décrirons plus tard pour effectuer l'action de recherche (recherche de balises) sur le contrôleur.
Définissez-le comme la valeur correspondant à la clé appelée mot-clé, puis utilisez la description renvoyée sous forme de données json en tant que contrôleur.
javascript/tag.js
const parentsElement = document.createElement('div')
const childElement = document.createElement('div')
Ici, un élément div est créé pour afficher les résultats de la recherche incrémentielle à l'écran. Les résultats de la recherche incrémentielle seront ajoutés à l'élément div créé.
javascript/tag.js
parentsElement.setAttribute('id', 'parents')
childElement.setAttribute('id', tag.id )
childElement.setAttribute('class', 'child' )
L'ID et le nom de classe sont donnés à l'élément div créé précédemment. Attribuez l'ID de la balise à afficher à childElement. Il donne également le nom de classe pour l'attribution de CSS.
javascript/tag.js
parentsElement.appendChild(childElement)
childElement.innerHTML = tag.name
searchResult.appendChild(parentsElement)
Dans cette partie, nous ajouterons childElement en tant qu'élément enfant de parentsElement. Ensuite, générez la balise HTML à afficher sur le childElement. Enfin, nous avons ajouté parentsElement aux éléments enfants de searchResult.
javascript/tag.js
const searchResult = document.getElementById('search-result')
searchResult.innerHTML = ''
Un caractère vide est attribué au searchResult afin qu'il ne soit pas affiché deux fois après le deuxième caractère.
javascript/tag.js
const clickElement = document.getElementById(tag.id)
clickElement.addEventListener("click", () => {
document.getElementById("post_tag_name").value = clickElement.textContent;
clickElement.remove();
Lorsque vous cliquez sur la balise affichée en tant que candidat, l'élément de texte de la balise sélectionnée est défini comme la valeur du formulaire d'entrée. Enfin, la balise sélectionnée est supprimée de la liste des vues.
Ce qui précède est une série de mouvements de recherche incrémentale.
config/routes.rb
resources :posts, only: [:index, :new, :create] do
collection do
get 'search'
end
end
controller/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all.order(created_at: :desc)
end
---réduction---
def search
return nil if params[:input] == ""
tag = Tag.where(['name LIKE ?', "%#{params[:input]}%"])
render json:{ keyword: tag }
end
---réduction---
end
Ceci termine la mise en œuvre. Vérifions l'opération.
Une solution possible à l'erreur dans cette implémentation consiste à prêter attention au nom de l'ID lorsque getElementById est terminé.
Dans cette implémentation, nous avons implémenté une recherche incrémentielle du modèle post_tag de l'objet de formulaire.
De plus, lorsque vous regardez le texte intégral de js, il y a une description du chemin sur la première ligne. Cette fois, je voulais implémenter une fonction de recherche séquentielle en entrant des balises lors de la publication de nouveaux articles, donc c'est posts / new.
En dehors de ces deux points, je pense que vous pouvez copier et coller.
Oh, n'oubliez pas de désactiver les liens Turbo ou de charger tag.js.
Il y a peu d'occasions de toucher au javascript dans le programme, et je ne suis pas bon dans ce domaine, alors je ferai de mon mieux.
Recommended Posts