Problema con paginación de resultados en AJAX

Hola:

Estoy intentando paginar resultados de una base de datos con AJAX para no tener que andar actualizando la página mientras se navega por los registros de esta. Cuando cambio de página por primera vez, funciona todo a la perfección. Pero cuando el contenido carga los botones de navegación pasan a no funcionar (se muestran pero por mucho que hagas click no cambia de página).

Os dejo los códigos a ver si alguien se da cuenta de qué pasa:

paginador.php
<?php

// ... conexión a la base de datos ...

echo '<table>
          <thead>
            <tr>
              <th scope="col">título</th>
              <th scope="col">contenido</th>
              <th scope="col">fecha</th>
              <th scope="col">opciones</td>
            </tr>
          </thead>
          <tbody>';

$result = $mysqli->query("SELECT * FROM tabla ORDER BY id DESC");
$count = $result->num_rows;

if($count > 0){
  $rowsPerPage = 2;
  $pageNum = 1;

  if(isset($_GET['page'])) $pageNum = $_GET['page'];

  $offset = ($pageNum - 1) * $rowsPerPage;
  $total_paginas = ceil($count / $rowsPerPage);
  $result = $mysqli->query("SELECT * FROM tabla ORDER BY id DESC LIMIT $offset, $rowsPerPage");

  while($row = $result->fetch_array()){ 
    $titulo = $row['titulo'];
    $contenido = $row['contenido'];
    $fecha = $row['fecha'];

    echo "<tr>
              <td>$titulo</td>
              <td>$contenido</td>
              <td>$fecha</td>
              <td>acciones</td>
            </tr>";
  }

  echo '</tbody>
          <tfoot>
            <tr>
              <td>
                <div class="pagination">
                  <ul>';

  if($pageNum != 1)  echo '<li><a class="navigate-link" data="'.($pageNum-1).'">Anterior</a></li>';

  for($i=1; $i <= $total_paginas; $i++){
    if ($pageNum == $i)
      echo '<li class="active"><a class="navigate-link" data="'.$i.'">'.$i.'</a></li>';
    else
      echo '<li><a class="navigate-link" data="'.$i.'">'.$i.'</a></li>';
  }

  if ($pageNum != $total_paginas)  echo '<li><a class="navigate-link" data="'.($pageNum+1).'">Siguiente</a></li>';
 
  echo '</ul>
        </div>
      </td>
      <td colspan="5" style="text-align: right;">texto derecha</td>
    </tr>
  </tfoot>
</table>';

}

?>

script para la paginación
    $(document).ready(function() {    
      $('.pagination ul li a').click(function(){
        $('#content').html('Cargando...');


        var page = $(this).attr('data');        
        var dataString = 'page='+page;


        $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $('#content').html(data);
            }
        });
    });
});
en el html simplemente incluyo paginador.php
Hola!

jQuery añade los listeners sólo a los elementos actuales del documento. Cuando utilizas AJAX para cargar contenido, jQuery no ha añadido los listeners a este nuevo contenido, por lo que no funcionarán. Si muestras un mensaje por consola (console.log("mensaje")) al hacer clic, probablemente verás que el contenido sólo se ejecuta la primera vez, pues las demás veces no existen los listeners.

Para solucionar el problema debes utilizar live (para jQuery < 1.7 si es que no me equivoco) u on (para las versiones más nuevas):

$(document).ready(function() {    
      $('.pagination ul li a').[live|on]('click', function(){
        $('#content').html('Cargando...');


        var page = $(this).attr('data');        
        var dataString = 'page='+page;


        $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $('#content').html(data);
            }
        });
    });
});

[live|on] reemplaza eso por live u on, no el cuadro completo :).

Ahora sí debería funcionar.
Muchas gracias, no sabía que on reemplazaba a live (ahora entiendo por qué me daba error al utilizarlo) :)

Desafortunadamente, sigue ocurriendo lo mismo. La primera vez funciona pero después los enlaces pasan a estar inactivos :(
Hmmm, vas a tener que debuggear :P.

Pon unos echo/console.log() para mostrar las variables importantes. En el código jQuery, envía los parámetros como objetos en lugar de un string, así:

$(document).ready(function() {    
      $('.pagination ul li a').[live|on]('click', function(){
        $('#content').html('Cargando...');

        var page = $(this).attr('data');   
        console.log("Cargar página: " + page);
        var dataString = { 'page': page };


        $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $('#content').html(data);
            }
        });
    });
});

Y modifiqué un poco el paginador (Haz un respaldo de tu código antes de usar las modificaciones):

<?php

# la conexión a la base de datos va aquí (omito ponerla para no cargar esto de más código innecesario pues este no es el problema)

echo '<table>
        <thead>
         <tr>
            <th scope="col">título</th>
            <th scope="col">contenido</th>
            <th scope="col">fecha</th>
            <th scope="col">opciones</td>
          </tr>
        </thead><tbody>';

$pageNum = 0;
$rowsPerPage = 2;

// Puesto que se espera un número y los parámetros se pasan por GET,
// mejor validas que realmente sea un número y no un string (que podría
// ser una inyección SQL)
if( isset( $_GET['page'] ) && is_numeric( $_GET['page'] ) ) {
	$pageNum = $_GET['page'];
}

// La primera vez será 0 * 2 = 0, por ende comenzará en la fila 0
// La segunda vez será 1 * 2 = 2, entonces comenzará en la fila 2
// y así sucesivamente.
$offset = $pageNum * $rowsPerPage;
$result = $mysqli->query("SELECT * FROM tabla ORDER BY id DESC LIMIT $offset, $rowsPerPage");
$count = $result->num_rows;
$total_paginas = ceil( $count / $rowsPerPage );
echo "<script type=\"text/javascript\">console.log(\"Current page: $pageNum; offset: $offset; Rows per page: $rowsPerPage; Result count: $count; Total pages: $total_paginas.\");</script>";

if($count > 0){
    while ($row = $result->fetch_array()) { 
      $titulo = $row['titulo'];
      $contenido = $row['contenido'];
      $fecha = $row['fecha'];
      echo "<tr>
                <td>$titulo</td>
                <td>$contenido</td>
                <td>$fecha</td>
                <td>acciones</td>
              </tr>";
     }
    echo '</tbody>
            <tfoot>
              <tr>
                <td>';
   echo '<div class="pagination"><ul>';
    if ($pageNum != 1)        echo '<li><a class="navigate-link" data="'.($pageNum-1).'">Anterior</a></li>';
        for ($i=1; $i <= $total_paginas; $i++) {
          if ($pageNum == $i)
            echo '<li class="active"><a class="navigate-link" data="'.$i.'">'.$i.'</a></li>';
          else
            echo '<li><a class="navigate-link" data="'.$i.'">'.$i.'</a></li>';
     }
        if ($pageNum != $total_paginas)          echo '<li><a class="navigate-link" data="'.($pageNum+1).'">Siguiente</a></li>';        echo '</ul></div></td>';
        echo '        <td colspan="5" style="text-align: right;">texto derecha</td>
          </tr> 
       </tfoot></table>';}
?>
Por unos problemas en el servidor no puedo acceder al panel de control y por tanto a modificar los archivos, espero tenerlo lo antes solucionado para probar a ver qué dice la consola y demás, en cuanto pueda mostraré aquí los resultados.

Muchas gracias por tu ayuda skaparate :)
Cambiando los códigos por cómo me dijiste sólo me detecta que hay una página de resultados XD
[FONT=Consolas]Current page: 0; offset: 0; Rows per page: 2; Result count: 2; Total pages: 1.[/FONT]

Creo que se debe a que calcula todo en base a los registros limitados (lo hace teinendo en cuenta el LIMIT $offset, $rowsPerPage), le he añadido los console.log a los códigos actuales (tuve que hacerles modificaciones [por ejemplo, lo de las SQLi] aunque siguen funcionando igual), y la primera vez carga todo bien, pero al clickar después sobre los enlaces no muestra nada en la consola.

Dejo el archivo jQuery con AJAX:
$(document).ready(function() {  


    $('.pagination-enlace').on('click', function(){
      var page = $(this).attr('data');
      var dataString = { 'page': page };
      console.log("Cargar página: " + page);
      $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $('#content').html(data);
            }
        });
    });
    
    $('#pagination').change(function(){
      var $page = $(this).find('option:selected');
      var selectedValue = $page.val();
      console.log("Cargar página: " + selectedValue);
      var dataString = { 'page': selectedValue };
      $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $('#content').html(data);
            }
        });
    });
    
});

Ahora utilizo un select para elegir la página y al cambiar de opción cambia de página (como dije antes, pasa lo mismo, la primera vez funciona bien y luego es como si estuviera inactivo). Esta es la parte final del código donde creo los enlaces de paginación:
  echo '</tbody><tfoot>
           <tr>
             <td><div id="btn-pagination-group">';
             if ($pageNum != 1)
               echo '<a class="pagination-enlace btn-pagination" data="'.($pageNum-1).'">ANTERIOR</a>';
        echo '<select style="height: 30px;" class="btn-pagination" name="pagination" id="pagination">';
        for ($i=1; $i <= $total_paginas; $i++) {
          if ($pageNum == $i)
            echo '<option selected>'.$i.'</option>';
          else
            echo '<option value="'.$i.'">'.$i.'</option>';
        }
        echo '</select>';
       if ($pageNum != $total_paginas)
          echo '<a class="pagination-enlace btn-pagination" data="'.($pageNum+1).'">SIGUIENTE</a>';
        echo '</div></td>
              <td colspan="5" style="text-align: right;"><em>texto derecha</em></td>
          </tr>
        </tfoot></table>';

De esta manera, al cargar la página el console.log dice (hay 7 registros en la base de datos):
Current page: 1; offset: 0; Rows per page: 2; Result count: 7; Total pages: 4.


Al cambiar a la página 3 por ejemplo:
Cargar página: 3
Current page: 3; offset: 4; Rows per page: 2; Result count: 7; Total pages: 4.

El PHP funciona bien en todas las páginas, así que el error debe estar en el script. Me parece raro que deje de estar activo después de hacer click.
He probado a hacer una cosa que me pareció que no funcionaría pero sí, ha funcionado y ahora va a la perfección!!
En vez de poner el script en la página donde incluyo el archivo paginador.php, lo he puesto como un echo en paginador.php
echo '<script type="text/javascript">
$(document).ready(function() {  


    $(".pagination-enlace").on("click", function(){
      var page = $(this).attr("data");
      var dataString = { "page": page };
      console.log("Cargar página: " + page);
      $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $("#content").html(data);
            }
        });
    });
    
    $("#pagination").change(function(){
      var $page = $(this).find("option:selected");
      var selectedValue = $page.val();
      console.log("Cargar página: " + selectedValue);
      var dataString = { "page": selectedValue };
      $.ajax({
            type: "GET",
            url: "paginador.php",
            data: dataString,
            success: function(data) {
              $("#content").html(data);
            }
        });
    });
    
});
    </script>';

Y ahora sí funciona bien todo el rato :)
Muchas gracias por la ayuda skaparate!!