Acciones que dejan de funcionar en JQuery tras un evento AJAX

Posted: June 24, 2011 in Web
Tags: , , , , ,

Esta misma tarde me he encontrado con un comportamiento extraño, al menos a priori, al menos para mí…

Una página que estaba cargando contenía una tabla que mostraba datos filtrados de un modelo de datos; junto a esa tabla hay un checkbox que al marcarlo elimina el filtrado cargando sólo esa tabla. Todo esto se realiza con JQuery, asignando en el $(document).ready el id del checkbox a un evento click que llama a una función que manda una petición POST/AJAX.

var cb_check_all = $("#alarms_check_showAll");
cb_check_all.click(function() {
    alarmsPost(cb_check_all.is(':checked'));
});

El checkbox funcionaba bien, por lo que metí otro elemento también junto a la tabla que realizaba una acción sobre todos los elementos mostrados del modelo de datos; sin problema. Ahí es cuando te envalentonas…

Pensé que sería interesante que pudiera realizar esa misma acción sobre cada uno de los elementos, por lo que utilicé la misma técnica pero aplicada a clases en vez de IDs:

    var div_singular_attend = $(".EventLogSingularAttend");
    if (div_singular_attend != undefined) {
        div_singular_attend.click(function() {
            alarmsPost(cb_check_all.is(':checked'), false);
        });
    }

Pero no funcionó. El comportamiento era correcto la primera vez que lanzaba la petición AJAX, pero a partir de ahí ya no funcionaba.

Tras investigar un poco, llegué a la conclusión de que una vez se lanzaba la petición AJAX y se repintaba la tabla, los elementos de dentro de esa tabla ya no se habían visto afectados por la asignación del evento click, ya que eso se realizaba en el $(document).ready. Resultó que mi conclusión era acertada, leyendo un artículo en la Web de JQuery al respecto:

AQUÍ

El problema es que la explicación que da está un poco abarullada, y para un viernes tarde esas cosas son muy densas. La solución para el que la quiera, usar el método live del objeto en cuestión para hacer un bind del evento. La diferencia entre usar un bind y el live, es que este último mantiene un registro de los elementos a los que asignar el evento en cuestión, por lo que si se crean más tarde también tendrán asignado el comportamiento.

    var div_singular_attend = $(".EventLogSingularAttend");
    if (div_singular_attend != undefined) {
        div_singular_attend.live('click', function() {
            alarmsPost(cb_check_all.is(':checked'), false);
        });
    }
About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s