Главная > CodeIgniter > Ajax-пагинация. CodeIgniter, jQuery.

Ajax-пагинация. CodeIgniter, jQuery.

В данной статье рассматривается реализация Ajax-пагинации в фреймворке CodeIgniter с использованием JavaScript-библиотеки jQuery.

Для начала сделаем обычную пагинацию, а потом разберемся как реализовать  пагинацию без перезагрузки всей веб-страницы.
Здесь работающий пример: ajax-пагинация

У нас есть список автомобилей, который хранится в базе данных в таблице ex_cars:

1. Таблица в БД ex_cars (id, name, year, price)

id name year price
1 Ваз-2109 2010 8000
2 Ланос 2009 9000
3 Toyota 2010 30000
4 BMW 2009 40000
5 Audi 2010 50000
6 Opel 2009 25000
7 Skoda 2010 20000

Нам нужно вывести этот список на веб-страницу. Но поскольку база данных будет пополняться новыми автомобилями, то необходимо отображать фиксированное число записей и номера страниц в виде ссылок. Кликая по которым, мы сможем  просмотреть все необходимые нам данные. Проще говоря, нам надо прикрутить пагинацию к выводимому списку автомобилей.

В фреймворке CodeIgniter для работы с пагинацией есть библиотека pagination.

Итак, наши дальнейшие действия:

1. Создаем модель Car_model в файле application\models\car_model.php. Здесь будут функции по работе с данными, т.е. с нашей таблицей  ex_cars.

2. В конструкторе контроллера (контроллер я назвал Ajax) подключаем библиотеку pagination и нашу модель car_model.

3. Создаем метод контроллера, в котором будет реализована вся необходимая логика.

4. Создаем отображение, в которое и выведем наши данные.

Ниже смотрите код. Он содержит комментарии. Думаю, там все понятно.

Модель (файл application\models\car_model.php):


class Car_model extends Model {
   protected $table = 'ex_cars';
   // возвращает общее кол-во записей в таблице ex_cars
   function count_all()
   {
      return $this->db->count_all($this->table);
   }
   // $limit - кол-во получаемых записей
   // $offset - смещение, с какой записи начинать выборку
   function list_cars($limit,$offset)
   {
      $this->db->limit($limit,$offset);
      $query = $this->db->get($this->table);
      return $query->result();
   }
}

Контроллер (application\controllers\ajax.php):


class Ajax extends MY_Controller {
   function Ajax()
   {
      parent::MY_Controller();
      // подключаем модель
      $this->load->model('car_model');
      // подключаем библиотеку для работы с пагинацией
      $this->load->library('pagination');
   }

   function paginate($offset='')
   {
      $limit = 3; //кол-во элементов списка на одной странице
      // получаем данные из таблицы
      // $limit - кол-во запрашиваемых записей
      // $offset - смещение, т.е. с какой записи начинать выборку
      $this->data['cars'] = $this->car_model->list_cars($limit,$offset);
      // путь к веб-странице на которой делается пагинация
      $config['base_url'] = site_url('ajax/paginate');
      // получаем общее кол-во записей в таблице ex_cars
      $config['total_rows'] = $this->car_model->count_all();
      // кол-во элементов, которое мы хотим показать на странице
      $config['per_page'] = $limit;
      // инициализация пагинации на основании заданных условий
      $this->pagination->initialize($config);
      $this->data['pag_links'] = $this->pagination->create_links();
      $this->data['inner_view'] = "pagination";
      // передача данных в отображение
      // main - главное отображение, в которое выводятся все остальные
      // pagination - это отображение с нашим списком авто
      $this->load->view('main', $this->data);
   }
}

Отображение (application\views\pagination.php):


<table>
<tr>
   <th>№</th>
   <th>Марка</th>
   <th>Год</th>
   <th>Цена</th>
</tr>
<?foreach($cars as $car):?>
<tr>
   <td><?=$car->id?></td>
   <td><?=$car->name?></td>
   <td><?=$car->year?></td>
   <td><?=$car->price?></td>
</tr>
<?endforeach;?>
</table>
<?=$pag_links;?>

Итак, обычная пагинация готова.

Теперь в наш код необходимо внести некоторые дополнения и получить уже ajax-пагинацию. Что необходимо сделать? Смотрите, сейчас у нас в контроллере есть строка:


$this->data['pag_links'] = $this->pagination->create_links();

В этой строке генерируются ссылки на  страницы нашего списка (первую, вторую, следующую, предыдущую и т.д.) Эти ссылки мы и выводим в отображение. Теперь наша задача написать код, который будет перехватывать клик по этим ссылкам и вместо перенаправления, которое сейчас выполняется мы будет посылать ajax-запрос на получение необходимых данных и выводить эти данные в нужный блок.

Вносим изменения в наше отображение pagination


<script>
$(document).ready(function(){
   $('.ajax_pag a').click(function(event){
   // получаем содержимое ссылки
   var link = $(this).attr('href');
   // отменяем действие по умолчанию
   event.preventDefault();
   // посылаем ajax-запрос по полученной ссылке
   $('#ajax_content').load(link);
   });
});
</script>

<center><h3>Ajax-пагинация. JQuery, CodeIgniter.</h3>   </center>
<div id="ajax_content">
<table>
<tr>
   <th>№</th>
   <th>Марка</th>
   <th>Год</th>
   <th>Цена</th>
</tr>
<?foreach($cars as $car):?>
<tr>
   <td><?=$car->id?></td>
   <td><?=$car->name?></td>
   <td><?=$car->year?></td>
   <td><?=$car->price?></td>
</tr>
<?endforeach;?>
</table>
<span class="ajax_pag"><?=$pag_links;?> </span>
</div> <!-- ajax_content -->

Какие изменения?

- таблицу мы поместили в блок <div> и присвоили ему id=’ajax_content’. Содержимое этого блока будет меняться при клике на ссылки пагинации.

-  вывод ссылок заключили в тег <span class=’ajax_pag’>.

- написали jQuery скрипт.

Что происходит в скрипте?

При клике на любую ссылку внутри блока с классом, мы получаем значение ссылки, по которой был произведен клик. И вместо стандартного перехода по этой ссылке, мы делаем ajax-запрос по полученному пути.
Этот запрос вернет данные в блок <div id=”ajax_content”></div>

Теперь в контроллере в метод paginate внесем проверку на тип запроса (обычный или ajax). Для обычного запроса у нас уже есть обработка, а в случае ajax-запроса мы будем выводить другое отображение, которое создадим ниже.


if(IS_AJAX){
   $this->load->view('pagination_ajax', $this->data);
}else{
   $this->data['inner_view'] = "pagination";
   // передача данных в отображение
   // main - главное отображение, в которое выводятся все остальные
   // pagination - это отображение с нашим списком авто
   $this->load->view('main', $this->data);
}

IS_AJAX – это константа, которую необходимо определить в файле
application\config\constants.php следующим образом:


define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
         strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

Теперь приведу содержимое отображения pagination_ajax, которое мы возвращаем в случае ajax-запроса.


<table>
<tr>
   <th>№</th>
   <th>Марка</th>
   <th>Год</th>
   <th>Цена</th>
</tr>
<?foreach($cars as $car):?>
<tr>
   <td><?=$car->id?></td>
   <td><?=$car->name?></td>
   <td><?=$car->year?></td>
   <td><?=$car->price?></td>
</tr>
<?endforeach;?>
</table>
<span class="ajax_pag"><?=$pag_links;?> </span>

Как видите, здесь просто вывод нашей таблицы.

Вот и все. Надеюсь, все понятно. Спасибо за внимание.

Успехов! :)



  1. MEMFIS
    21 Мар 2011 из 20:36 | #1

    Моя ошибка, всё нормально. Просто я в загружаемом виде не прописал Javascript, поэтому он вначале из вида с айаксом грузил второй вид без айакса, ну и соответственно вот такой вот цикл у мну получался))

  2. 21 Мар 2011 из 20:04 | #2

    @ MEMFIS
    Проверьте куда ссылки пагинации ведут после первого клика. Клик по ним должен обрабатываться java-скриптом. Может в изначальной вьюшке указали класс для ссылок, а в подгруженной – нет.

  3. MEMFIS
    21 Мар 2011 из 19:35 | #3

    У меня всё работает но как то странно, после первого клика по пагинации (контроллер, модель и тд всё своё) всё нормально, грузит только див. при следующем клике, не важно вперёд или назад, уже грузит страницу))
    Есть идеи в чём может быть трабл?

  4. 19 Мар 2011 из 17:16 | #4

    Аналогично. Посмотри еще статью Ajax-фильтрация.

  5. Гена
    19 Мар 2011 из 15:39 | #5

    А как ещё сделать сортировку и поиск)?

  6. alex
    22 Дек 2010 из 12:32 | #6

    Разобрался уже. Дело в том, что у меня в строке сегмент для $offset был на 4 позиции, т.е. http://site.ru/admin/object/index/2. Передавал в функцию выборки данных getlist($limit, $this->uri->segment(n));

  7. alex
    22 Дек 2010 из 12:28 | #7

    Добрый день! Сделал все как описано. Вылетает ошибка , мол параметр $offset для метода с пагинацией не идендифицирован. Если оставляю $offset=» то, пагинация не работает, параметр из строки URL не береться. Как быть подскажите.

  8. 12 Ноя 2010 из 12:16 | #8

    Вот здесь написал, что за «хрень» и как с ней быть. :)
    http://yershov.com.ua/jquery/%D0%BF%D0%BE%D0%B4%D1%81%D0%B2%D0%B5%D1%82%D0%BA%D0%B0-%D0%BA%D0%BE%D0%B4%D0%B0-jquerychili/

  9. Александр
    12 Ноя 2010 из 9:35 | #9

    Что за желтая хрень у вас вылазит при выделении текста, уберите её пожалуйста

  10. 28 Фев 2010 из 15:39 | #10

    @ Антон
    Можно и так.
    Я в отображении main вызываю
    $this->load->view($inner_view);

  11. Антон
    28 Фев 2010 из 15:01 | #11

    я имею в виду не линки, а саму таблицу
    $this->data['inner_view'] = «pagination»;
    // передача данных в отображение
    // main – главное отображение, в которое выводятся все остальные
    // pagination – это отображение с нашим списком авто
    $this->load->view(’main’, $this->data);
    как inner_view поместить в main?
    я сделал вот так
    $this->data['inner_view'] = $this->load->view(’files/list’, $this->data, true);
    и потом уже в main вставил echo $inner_view
    но не уверен, что так правильно, хотя и работает

  12. 27 Фев 2010 из 23:14 | #12

    в контроллере создаете линки и передаете в отображение main:
    $this->data['pag_links'] = $this->pagination->create_links();
    $this->load->view(’main’, $this->data);
    а в отображении main выводите:
    echo $pag_links;

  13. Антон
    27 Фев 2010 из 19:56 | #13

    А как разместить pagination в main отображении?

  1. Трекбеков пока нет.