Pergunta

Basicamente, estou tentando criar um gerenciador de arquivos para meu aplicativo Rails semelhante ao funcionamento da seção 'Mídia' do WordPress.Atualmente tenho um modelo chamado Asset que é onde os usuários vão para fazer upload de várias imagens.Em vários outros modelos tenho um campo para imagens que é apenas um campo de texto.Espero que quando um usuário clicar no campo de texto, ele abra um 'gerenciador de ativos' em uma janela modal com todas as imagens contidas nele Asset mostrando.Quando um usuário clica em uma das imagens, ele deve fechar o modal e preencher o campo de texto com a URL da imagem selecionada.

Eu tenho um modelo chamado Events que contém um campo de texto do qual eu estava falando.No new action Eu respondo ao js, ​​no qual carrego um parcial que contém todos os ativos em uma janela modal, exatamente como eu esperava.Meu único problema é que estou fazendo isso através de um $.getScript call e não consigo chamar nenhum javascript adicional para carregar o URL da imagem de volta no campo de texto, acho que é porque os objetos ainda não existem.De qualquer forma, vamos ao código:

controlador

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

novo.js

$('.acontainer').html('<%= render @asset %>');

página.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'));
});

Qualquer ideia seria muito apreciada, especialmente se alguém souber uma maneira melhor de fazer isso.:-)

Foi útil?

Solução

Parece que você pode estar vinculando o evento click aos elementos .acontainer img DOM que não existem no momento, já que você os recupera quando clica em .image-field.

Em geral, você deve usar jQuery.on e vincule seus eventos à raiz do documento.Isso é chamado de delegação.Quando você clica em um link, o evento irá aparecer e atingir o nó do documento, e irá tratar o evento.Dessa forma, conforme você adiciona elementos DOM via ajax ou diretamente no DOM, eles ainda obterão o manipulador de eventos pretendido.

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

No entanto, há um problema maior aqui.Parece que você tem vários elementos .image-field na página.O que você pode precisar fazer em seu manipulador .image-field é retornar HTML em vez de js, para que você possa vincular um evento ao elemento raiz do HTML recém-adicionado.Esse bloco identificará o campo de entrada específico, cujo valor pode ser definido quando uma imagem for clicada.

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

Uma observação final: você pode considerar o uso de um controlador RESTful para seus ativos.Talvez você não queira buscar um recurso (um ativo) de um controlador chamado EventsController, especialmente usando a ação de edição.Você deseja que GET AssetsController::index retorne uma lista de ativos.

Outras dicas

Nada acontece quando você clica nas imagens porque a consulta inicial para ".acontainer img" não está retornando nenhum elemento e, portanto, o manipulador de eventos não está anexado a nada.Eles ainda não foram carregados.

Você pode querer tentar jQuery live método.Ele anexa manipuladores aos elementos presentes no carregamento da página e elementos adicionados posteriormente ao DOM.


Atualizar: Como aponta @aceofspades, live está obsoleto no jQuery 1.7.Usar on em vez de.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top