javascript / logique partielle pour un gestionnaire de fichiers
-
13-12-2019 - |
Question
J'essaie essentiellement de créer un gestionnaire de fichiers pour mon application Rails, similaire au fonctionnement de la section « Médias » de WordPress.J'ai actuellement un modèle appelé Asset
c'est là que les utilisateurs vont télécharger diverses images.Dans divers autres modèles, j'ai un champ pour les images qui n'est qu'un champ de texte.J'espère que lorsqu'un utilisateur clique sur le champ de texte, il ouvrira un « gestionnaire d'actifs » dans une fenêtre modale avec toutes les images contenues à l'intérieur. Asset
montrant.Lorsqu'un utilisateur clique sur l'une des images, il doit fermer le modal et remplir le champ de texte avec l'URL de l'image sélectionnée.
J'ai un modèle qui s'appelle Events
qui contient un champ de texte dont je parlais.Dans le new
action Je réponds à js, dans lequel je charge un partiel qui contient tous les actifs dans une fenêtre modale, comme je m'y attendais.Mon seul problème est que je fais cela via un $.getScript
appelez et je ne peux pas appeler de javascript supplémentaire pour charger l'URL de l'image dans le champ de texte, je suppose que c'est parce que les objets n'existent pas encore.Quoi qu'il en soit, passons au code :
manette
def new
@event = Event.new
@asset = Asset.all
end
respond_to do |f|
f.html
f.js
end
nouveau.js
$('.acontainer').html('<%= render @asset %>');
page.js
//when a user clicks the image field, show the asset partial
$('.image-field').click(function() {
$.getScript('edit.js');
});
// when a user clicks an image, add it's src to the image field <-- does nothing
$('.actonainer img').click(function() {
$('.image-field').val($(this).attr('src'));
});
Toutes les idées seraient très appréciées, surtout si quelqu'un connaît une meilleure façon de procéder.:-)
La solution
Il semble que vous liez l'événement click aux éléments DOM .acontainer img qui n'existent pas à ce moment-là, puisque vous les récupérez lorsque vous cliquez sur .image-field.
En général, vous devriez utiliser jQuery.on et liez vos événements à la racine du document.C’est ce qu’on appelle la délégation.Lorsque vous cliquez sur un lien, l'événement apparaîtra et frappera le nœud du document, et il gérera l'événement.De cette façon, lorsque vous ajoutez des éléments DOM via ajax ou directement dans le DOM, ils obtiendront toujours le gestionnaire d'événements souhaité.
$(function() {
$(document).on('click', '.acontainer img', function(event) {
$('.image-field').val($(this).attr('src'));
})
});
Cependant, il y a ici un problème plus important.Il semble que vous ayez plusieurs éléments .image-field sur la page.Ce que vous devrez peut-être faire dans votre gestionnaire .image-field est de renvoyer du HTML plutôt que du js, afin que vous puissiez lier un événement à l'élément racine du HTML nouvellement ajouté.Ce bloc identifiera le champ de saisie spécifique, dont il pourra définir la valeur une fois que vous aurez cliqué sur une image.
$(function() {
$(document).on('click', '.image-field',
function(event) {
var field = $(this);
$.ajax('/edit', {
success: function(data, textStatus, jqXHR) {
var blah = $(Dialog.new(data));
// Create a modal and return its root DOM element
blah.on('click', 'img',
function(event) {
field.val($(this).attr('src'));
});
}
})
});
});
Une dernière remarque, vous souhaiterez peut-être envisager d'utiliser un contrôleur RESTful pour vos actifs.Vous ne souhaiterez peut-être pas récupérer une ressource (un actif) à partir d'un contrôleur nommé EventsController, notamment à l'aide de l'action d'édition.Vous souhaitez que GET AssetsController::index renvoie une liste d’actifs.
Autres conseils
Rien ne se passe lorsque vous cliquez sur les images car la requête initiale ".acontainer img"
ne renvoie aucun élément et le gestionnaire d'événements n'est donc attaché à rien.Ils n'ont pas encore été chargés.
Vous voudrez peut-être essayer jQuery live
méthode.Il attache des gestionnaires aux éléments présents au chargement de la page et éléments ajoutés plus tard au DOM.
Mise à jour: Comme le souligne @aceofspades, live
est obsolète dans jQuery 1.7.Utiliser on
plutôt.