[Off][Bootstrap] Carregando Javascript no Modal

750 views
Skip to first unread message

Thales Miguel

unread,
Aug 2, 2016, 9:16:59 AM8/2/16
to rails-br
Olá.
Estou implementando algumas novas funcionalidades em uma das minhas aplicações e me surgiu uma dúvida ao trabalhar com Modal.
Tenho uma View que abre um modal que é populado por outro arquivo HTML. 

Para facilitar a explicação: 
A Tela 1 chama o Modal que é populado com o HTML da Tela 2, via Javascript.
Dessa forma, ao abrir a Tela 1, as informações da Tela 2 não estão presentes e, dessa forma, não fazem parte do meu DOM e não são "vistas" pelos meus arquivos Javascrip. Ao abrir o Modal, minhas funções Javascript não funcionam.

Para corrigir isso, criei uma função para recarregar meus Javascripts quando o Modal é acionado. Isso não parece muito correto...

Tentei carregar os Javascripts de forma assíncrona também. Dessa forma, fiz menção aos arquivos JS em meu Application.html.erb e dentro do Modal.

Seria essa a melhor maneira?
Como vocês lidam com esse tipo de problema?

Me sugeriram criar Javascripts específicos para o Modal mas, como utilizo algumas funções Dentro E Fora desse Modal, eu acabaria duplicando meu código.

Desde já agradeço.

Diogo Menezes

unread,
Aug 2, 2016, 10:00:22 AM8/2/16
to rail...@googlegroups.com

Você pode melhorar isso trocando o bind das suas funções js.

Procure sobre o "on" do jquery.

Basicamente ao invés de usar

$('#obj').click(function(){...}); vc vai usar

$(document).on('click', '#obj', function(){...});


--
--
Você recebeu essa mensagem porquê está inscrito no Google
Groups "rails-br".
Para enviar uma mensagem para o grupo, mande um email para rail...@googlegroups.com
Para se descadastrar, mande um e-mail para
rails-br+u...@googlegroups.com
Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7

---
Você recebeu essa mensagem porque está inscrito no grupo "rails-br" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para rails-br+u...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Thales Miguel

unread,
Aug 2, 2016, 10:13:08 AM8/2/16
to rail...@googlegroups.com
Atualmente uso o "on" mas de outra forma:

$( "#obj" ).on( "click", function() {...});

Dessa forma que você demonstrou, eu não preciso ter o objeto carregado antes do Javascript ser executado?
Farei o teste!
--

Diogo Menezes

unread,
Aug 2, 2016, 10:26:53 AM8/2/16
to rail...@googlegroups.com
Sim dessa forma que você fez não vai funcionar mesmo pois você está associando o evendo diretamente ao elemento que não existe.

Quando você define um seletor para o on como eu fiz, você está delegando o evento aos filhos de document ( nesse caso ) que casem com o seletor '#obj' (nesse caso), isso forca esse live atach do evento.

Segue a documentação oficial:

When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.

Thales Miguel

unread,
Aug 2, 2016, 10:32:41 AM8/2/16
to rail...@googlegroups.com
Excelente, Diogo!
Muito obrigado pela explicação.
Hora de rever meus códigos!

Diogo Menezes

unread,
Aug 2, 2016, 10:46:07 AM8/2/16
to rail...@googlegroups.com
:)

Apenas complementando com um exemplo;

https://jsfiddle.net/t6txLkf3/

Repare que das 2 primeiras formas o alert só aparece no primeiro link que é o link que já estava na pagina quando o dom termina de renderizar.


O segundo link, que foi incluido dinamicamente só é afetado por um alert, gerado pelo binding a partir do document.

Thales Miguel

unread,
Aug 2, 2016, 2:32:32 PM8/2/16
to rail...@googlegroups.com
Fiz alguns testes aqui e uma dúvida apareceu.
$('body').on('click', '[data-ma-action]', function (e) {
  e.preventDefault();

  var $this = $(this);
  var action = $(this).data('ma-action');

  switch (action) {
    ...
Eu estou utilizando esse código ara executar algumas funções da minha tela como abrir um menu lateral. Como pode ser visto na primeira linha do código, eu estava passando o valor de "data-ma-action" como parâmetro.
Esse valor vem dos elementos "clicaveis" da minha aplicação. 

Ex:
<li class="hi-trigger ma-trigger" data-ma-action="sidebar-open" data-ma-target="#sidebar">
Lendo os documentos do jQuey não encontrei nada sobre passagem de valor com a forma de delegates() sugerida pelo Diogo.

Tentei fazer assim:
$(document).on('click', 'body', '[data-ma-action]', function (e) {
mas não obtive sucesso...
Dessa forma, quando clico em qualquer componente da tela, o jQuery entende que estou clicando no Body e, então, tenta buscar o atributo "data-ma-target".

Existe uma forma de continuar passando meu parâmetro utilizando delegates?

Thales Miguel

unread,
Aug 2, 2016, 2:54:58 PM8/2/16
to rail...@googlegroups.com
Acho que deixei alguma coisa passar... Já está funcionando como descrevi no primeiro código que postei.
--

Thales Miguel

unread,
Aug 2, 2016, 3:47:47 PM8/2/16
to rail...@googlegroups.com
Somente para complementar...
Alterei alguns arquivos Javascript para utilizar essa nova sintaxe e assim tirar proveito dos delegates apresentados pelo Diogo.
Enquanto fazia as alterações tive dificuldades em acessar funções não vinculadas a eventos como "click", "dbclick", "blur"... Um exemplo disse é o Bootstrap Date-Picker.
Como o date-picker é adicionado à classe quando o Javascript é carregado, ele não funcionava em meu Modal que era carregado posteriormente.
Me sugeriram o uso do jquery.initialize.
Com esse plugin baseado em MutationObserver, consegui executar a chamada do date-picker assim que o elemento foi criado no meu Modal.

Simplesmente criei uma chamada da função em meu Javascript principal, como segue:

$(".date-picker").initialize(function () {
  $(this).datetimepicker({
    format: 'DD/MM/YYYY',
    locale: 'pt-BR'
  });
});
Para os interessados, aqui está o link para esse plugin:
--

Reply all
Reply to author
Forward
0 new messages