Execução de Javascript quando um widget é adicionado no back-end

19

Eu tenho widgets que possuem controles de javascript anexados a eles.

Se o widget estiver presente quando a página de administração do widget for carregada, os controles funcionarão corretamente.

Quando adiciono um novo widget, eles não funcionam corretamente, recebo a marcação, mas nenhum evento de javascript entra em vigor.

Se eu salvar o novo widget, quando o formulário for recarregado, os controles serão criados corretamente e funcionarão agora.

A atualização da página também corrige o problema, mas apenas para widgets existentes. Novos widgets ainda têm esse problema.

Especificamente, estou executando selectize em select inputs nestes pontos:

  • documento pronto
  • Ajaxcomplete

Confirmei que meu código é executado em cada evento conforme desejado, mas os resultados não são os esperados.

Aqui está um plug-in de teste que demonstra o problema:

enlace

Você verá que tenho um contador que aumenta com cada elemento de seleção que ele pode converter.

Notas:

  • Quando a página do widget é carregada, posso ver o contador aumentando no console JS conforme o esperado
  • Quando eu adiciono um novo widget, o código é executado, no entanto, ele não consegue encontrar nenhum elemento de seleção no qual ele possa ser executado, como demonstrado pelo found.length sendo 0. Esse não deve ser o caso, pois cada novo widget de esse tipo deve ter um elemento select
  • os elementos select têm uma classe para identificá-los, essa classe é removida depois que a biblioteca selectize é aplicada para evitar duplicação e reprocessamento em widgets existentes.
  • Antes de usar o selectize, usei o Select2, que tinha o mesmo problema
  • Comentando o código AJAX, esperaria que novos widgets tivessem uma entrada de seleção padrão. Eles não. Eu não sei porque este é o caso

Então, como faço o controle selectize funcionar sem dizer ao usuário para atualizar / clicar salvar antes de fazer alterações?

    
por Tom J Nowell 17.01.2014 / 02:02

2 respostas

11

Grande notícia,

Eu consertei.

Desculpas por perder sua essência no meu comentário inicial e dar uma resposta que você já havia implementado. Isso vai me ensinar a responder no meu telefone enquanto estiver em um trem!

Seu uso de ajaxstop está correto. Inferno o JS na maior parte está funcionando corretamente, você pode ver os estilos css sendo inicializados e as mudanças no DOM.

O problema está na verdade com o seu seletor.

Isso ocorre porque o conteúdo do widget não é carregado via ajax, na verdade, ele clona da coluna da esquerda, onde está oculto, e dispara uma chamada de ajax para salvar a posição do widget na coluna da direita. Isso explica por que ajaxstop funciona, mesmo que o conteúdo seja clonado. No entanto, como há uma versão oculta do widget na coluna à esquerda, seu JS está instanciando isso. Assim, quando você o arrasta para a coluna da direita, você está obtendo um clone mutilado do widget oculto.

Assim, você precisa selecionar o que está no lado esquerdo. Abaixo está o código corrigido:

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>
    
por MichaelJames 17.01.2014 / 13:22
14

Como @ aaron-holbrook comentou que uma abordagem mais limpa seria:

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});

Apenas colando aqui para referência como respostas, é muito mais fácil encontrar esses comentários

    
por chifliiiii 24.11.2014 / 19:50