Frage

Ich versuche im Grunde, einen Dateimanager für meine Rails-App zu erstellen, ähnlich wie der Abschnitt „Medien“ von WordPress funktioniert.Ich habe derzeit ein Modell namens Asset Hier können Benutzer verschiedene Bilder hochladen.In verschiedenen anderen Modellen habe ich ein Feld für Bilder, das nur ein Textfeld ist.Ich hoffe, dass, wenn ein Benutzer auf das Textfeld klickt, ein „Asset-Manager“ in einem modalen Fenster mit allen darin enthaltenen Bildern geöffnet wird Asset zeigen.Wenn ein Benutzer auf eines der Bilder klickt, sollte das Modal geschlossen und das Textfeld mit der URL des ausgewählten Bildes gefüllt werden.

Ich habe ein Modell namens Events das ein Textfeld enthält, über das ich gesprochen habe.Im new Aktion Ich antworte auf js, in dem ich einen Teil lade, der alle Assets in einem modalen Fenster enthält, genau wie ich es erwarten würde.Mein einziges Problem ist, dass ich das über a mache $.getScript Aufruf und ich kann kein zusätzliches Javascript aufrufen, um die Bild-URL zurück in das Textfeld zu laden. Ich vermute, das liegt daran, dass die Objekte noch nicht existieren.Wie auch immer, weiter zum Code:

Regler

def new
  @event = Event.new
  @asset = Asset.all
end
respond_to do |f|
  f.html
  f.js
end

new.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'));
});

Für alle Ideen wäre ich sehr dankbar, insbesondere wenn jemand einen besseren Weg kennt, dies zu tun.:-)

War es hilfreich?

Lösung

Es sieht so aus, als ob Sie das Click-Ereignis an die DOM-Elemente von .acontainer img binden, die zu diesem Zeitpunkt nicht vorhanden sind, da Sie sie abrufen, wenn Sie auf .image-field klicken.

Im Allgemeinen sollten Sie verwenden jQuery.on und binden Sie Ihre Ereignisse an das Dokumentstammverzeichnis.Dies nennt man Delegation.Wenn Sie auf einen Link klicken, sprudelt das Ereignis hervor und trifft auf den Dokumentknoten, der das Ereignis verarbeitet.Auf diese Weise erhalten Sie beim Hinzufügen von DOM-Elementen über Ajax oder direkt im DOM weiterhin den von Ihnen beabsichtigten Event-Handler.

$(function() {
  $(document).on('click', '.acontainer img', function(event) {
    $('.image-field').val($(this).attr('src'));
  })
});

Allerdings gibt es hier ein größeres Problem.Es hört sich so an, als hätten Sie mehrere .image-field-Elemente auf der Seite.Möglicherweise müssen Sie in Ihrem .image-field-Handler HTML anstelle von js zurückgeben, damit Sie ein Ereignis an das Stammelement des neu hinzugefügten HTML binden können.Dieser Block identifiziert das spezifische Eingabefeld, dessen Wert er festlegen kann, sobald auf ein Bild geklickt wird.

$(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'));
                });
            }
        })
    });
});

Ein letzter Hinweis: Möglicherweise möchten Sie die Verwendung eines RESTful-Controllers für Ihre Assets in Betracht ziehen.Möglicherweise möchten Sie nicht eine Ressource (ein Asset) von einem Controller namens EventsController abrufen, insbesondere nicht mit der Bearbeitungsaktion.Sie möchten, dass GET AssetsController::index eine Liste von Assets zurückgibt.

Andere Tipps

Es passiert nichts, wenn Sie auf die Bilder klicken, weil die erste Abfrage erfolgt ist ".acontainer img" gibt keine Elemente zurück und daher ist der Ereignishandler an nichts angehängt.Sie wurden noch nicht geladen.

Vielleicht möchten Sie es versuchen jQuerys live Methode.Es hängt Handler an Elemente an, die beim Laden der Seite vorhanden sind Und Elemente, die später dem DOM hinzugefügt wurden.


Aktualisieren: Wie @aceofspades betont, live ist in jQuery 1.7 veraltet.Verwenden on stattdessen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top