The click event does not fire after reloading the content by an AJAX request in Symfony2

1

I have the following controller :

public function indexAction(Request $request)
    {
        if (!$request->isXmlHttpRequest())
        {
            $this->denyAccessUnlessGranted('ROLE_ESP_NAC', null, 'Imposible acceder a este recurso !!');

            $repositoryRiesgos = $this->getDoctrine()->getRepository('AppBundle:Riesgo');


            $listado = $repositoryRiesgos->findAll(); //findByPages($request->get('page', 1));
            return $this->render('AppBundle:CodifRiesgos:index.html.twig', array('riesgos' => $listado));
        } else
        {
            try
            {
                $this->denyAccessUnlessGranted('ROLE_ESP_NAC', null, 'Imposible acceder a este recurso !!');
            } catch (AccessDeniedException $denyExc)
            {
                return new Response($denyExc->getMessage(), 403);
            }

            $repositoryRiesgos = $this->getDoctrine()->getRepository('AppBundle:Riesgo');
            $listado = $repositoryRiesgos->findAll();

            return $this->render('AppBundle:CodifRiesgos:tablaRiesgos.html.twig', array('riesgos' => $listado));
        }
    }

Even in the controller I practically repeated the code for both the request via AJAX and the normal one.

Now the template index.html.twig is as follows:

{% extends "::base.html.twig" %}

{% block title %} PAMI - Codificadores {% endblock %}

{% block principal %}    
    <br/>
    <div class="breadcrumb">        
        <a href="{{ path('app_homepage') }}">Inicio<span class="glyphicon glyphicon-chevron-right"></a>&nbsp;
        Riesgos<a class="lnkRecargarRiesgos" href="{{ path('riesgos_listado') }}"> <span class="glyphicon glyphicon-refresh"></span></a>               
    </div>           

    <div id="tablaDatos">
        <table id="tablaRiesgos" class="table table-condensed table-hover table-responsive">
            <thead>
                {% if app.user and is_granted('ROLE_ESP_NAC') %}
                    <tr>
                        <th colspan="5"><a id="lnkRegistrarRiesgo" href="{{ path('riesgos_registrar_nuevo') }}"><span class="glyphicon glyphicon-plus"></span> Nuevo</a></th>
                    </tr>               
                {% endif %}
                <tr>
                    <th>Nombre</th>
                    <th>Descripci&oacute;n</th>
                    <th>Alto</th>
                    <th>Editar</th>
                    <th>Eliminar</th>
                </tr>
            </thead>
            <tbody>
                {% for riesgo in riesgos%}
                    <tr id="filaRiesgo_{{ riesgo.id }}">
                        <td>{{ riesgo.nombre }}</td>
                        <td>{{ riesgo.descripcion }}</td>
                        <td>
                            {% if riesgo.calificaComoAltoRiesgo %}
                                <span class="glyphicon glyphicon-hand-up"></span>
                            {% endif %}
                        </td>
                        <td><a class="lnkEditarRiesgo" href="{{ path('riesgos_editar', {'id':riesgo.id}) }}"><span class="glyphicon glyphicon-edit"></span></a></td>
                        <td><a class="lnkEliminarRiesgo" href="{{ path('riesgos_eliminar', {'id':riesgo.id}) }}"><span class="glyphicon glyphicon-remove"></span></a></td>
                    </tr>
                {% endfor %}
            </tbody>            
        </table>   
    </div>

{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript">
        $(document).ready(function(){

            $('a.lnkRecargarRiesgos').on('click', function(e) {
                    e.preventDefault();
                    var url = $(this).attr('href');
                    $.ajax({
                        'datatypes': 'html',
                        'type': 'GET',
                        'url': url,
                        beforeSend: function() {
                            $('#indicador').addClass('cargando-satisfactorio').fadeIn('fast');
                        }
                    }).done(function(data) {
                        $('#tablaDatos').html(data);
                    }).fail(function(jqXHR) {
                        $('#indicador').removeClass('cargando-satisfactorio').addClass('cargando-error').html(jqXHR.responseText);
                    }).always(function() {
                        $('#indicador').fadeOut('slow', function() {
                            $(this).removeClass('cargando-error').html("<span class='glyphicon glyphicon-time'></span> Cargando...");
                        });
                    });
                });           


                $('#tablaRiesgos tbody tr a.lnkEliminarRiesgo').on('click', function(e) {
                    e.preventDefault();
                    var idRiesgo = $(this).attr('id');
                    var url=$(this).attr('href');
                    var trPadre=$(this).parents('tr');
                    $.ajax({
                        'datatypes': 'html',
                        'type': 'GET',
                        'url': url,
                        beforeSend: function() {
                            $('#indicador').addClass('cargando-satisfactorio').fadeIn('fast');
                        }
                    }).done(function(data) {
                        $(trPadre).remove();
                        $('#indicador').html(data);
                    }).fail(function(jqXHR) {
                        $('#indicador').removeClass('cargando-satisfactorio').addClass('cargando-error').html(jqXHR.responseText);
                    }).always(function() {
                        $('#indicador').fadeOut(4900, function() {
                            $(this).removeClass('cargando-error').html("<span class='glyphicon glyphicon-time'></span> Cargando...");
                        });
                    });
                });
        });
    </script>
{% endblock %}

The problem is this:

  • When the template is initially loaded, the onclick event associated with a.lnkEliminarRiesgo works correctly.
  • Then, by clicking on the a.lnkRecargarRiesgos , I reload the same updated information (through AJAX) in div#tablaDatos .
  • But now, as the a.lnkEliminarRiesgo was rebuilt, the event .on('click',... that had originally associated does not fire. Instead, the link of href is followed because e.preventDefault() was not executed.
  • I want the on-click event to continue functioning as it did at the beginning.

    I do not know if my approach to working with the templates in Symfony2 is incorrect or I'm missing something or I'm not focusing well on the use of asynchronous calls, or the way I'm including the JavaScript.

        
    asked by Francisco 02.10.2016 в 01:34
    source

    3 answers

    0

    At the time of bindear events, I started the filter on a label div with id='vistas' , that for this specific application will be in that element where all the views of the AJAX calls are loaded, therefore this does not will disappear from the page. And in the case of the delete functionality, it is always done in a table with id = 'tableData'   $('#vistas').find('#tablaDatos tbody tr a.lnkEliminarRegistro').on('click', function(e) { ... }

    In this way, the event link click will always be maintained on the labels <a> with class, for example: lnkEliminarRegistro .

    That way, the implementation for the functionality eliminates all the tables of the views loaded within <div class='vistas'></div>

        
    answered by 02.10.2016 / 23:44
    source
    1

    I recommend linking it this way:

    $(document).on("click",'a.lnkEliminarRiesgo', function (event, xhr, settings) {
    //Contenido Script
    });
    

    In the previous answers the bind is done at body , if the body changes it can break the bind or even generate something known as "double firing" ... that is why it is recommended to make the link to the document. The callback xhr and settings are also instantiated, which can help you in the debug.

    You should also check if the function requires plugging follow this trend or you will have to recharge the plugging numbers of times and make the unbind broken.

        
    answered by 23.06.2017 в 21:13
    0

    One of the correct ways to do it is

    $('body').on('click', '#tablaRiesgos tbody tr a.lnkEliminarRiesgo', function(e) { ... }
    

    This way, you keep the event linked to the body element (which in theory, will not vary in the DOM of your application) and you make a filtering on the #tablaRiesgos tbody tr a.lnkEliminarRiesgo selector, so it is not necessary to continuously link an event click with newly created elements.

        
    answered by 24.04.2017 в 08:29