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>
Как видите, здесь просто вывод нашей таблицы.
Вот и все. Надеюсь, все понятно. Спасибо за внимание.
Успехов!
Моя ошибка, всё нормально. Просто я в загружаемом виде не прописал Javascript, поэтому он вначале из вида с айаксом грузил второй вид без айакса, ну и соответственно вот такой вот цикл у мну получался))
Проверьте куда ссылки пагинации ведут после первого клика. Клик по ним должен обрабатываться java-скриптом. Может в изначальной вьюшке указали класс для ссылок, а в подгруженной – нет.
У меня всё работает но как то странно, после первого клика по пагинации (контроллер, модель и тд всё своё) всё нормально, грузит только див. при следующем клике, не важно вперёд или назад, уже грузит страницу))
Есть идеи в чём может быть трабл?
Аналогично. Посмотри еще статью Ajax-фильтрация.
А как ещё сделать сортировку и поиск)?
Разобрался уже. Дело в том, что у меня в строке сегмент для $offset был на 4 позиции, т.е. . Передавал в функцию выборки данных getlist($limit, $this->uri->segment(n));
Добрый день! Сделал все как описано. Вылетает ошибка , мол параметр $offset для метода с пагинацией не идендифицирован. Если оставляю $offset=» то, пагинация не работает, параметр из строки URL не береться. Как быть подскажите.
Вот здесь написал, что за «хрень» и как с ней быть.
Что за желтая хрень у вас вылазит при выделении текста, уберите её пожалуйста
Можно и так.
Я в отображении main вызываю
$this->load->view($inner_view);
я имею в виду не линки, а саму таблицу
$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
но не уверен, что так правильно, хотя и работает
в контроллере создаете линки и передаете в отображение main:
$this->data['pag_links'] = $this->pagination->create_links();
$this->load->view(’main’, $this->data);
а в отображении main выводите:
echo $pag_links;
А как разместить pagination в main отображении?