Давайте начнем с причины, по которой ваша страница перезагружается: действия браузера по умолчанию .Несколько элементов HTML заставляют браузер переходить с текущей страницы.В данном случае нас интересуют:
#amount_show
form
представление (функция onchange
), которое отправляет новое значение через запрос POST
. - Сам paginator (со ссылками
a
), который сообщает php-скрипту, какие записи нужно извлечь с помощью запроса GET
.
Оба значения должны быть переданы в php-скрипт, чтобы он мог возвращатьправильные записи, в противном случае параметр amount
будет использоваться по умолчанию в скрипте php, даже если у нас выбрано другое значение.Чтобы сделать это, мы должны изменить передачу переменной amount
на запрос GET
.
Кроме того, при изменении значения amount
мы по умолчанию будем использовать первую страницу наИзбегайте пересчета номера страницы.Поскольку ссылки на страницы могут поэтому изменяться динамически, я не буду обрабатывать их в javascript, а в php, поскольку у нас уже есть шаблон и расчеты.Это облегчит переход к следующему этапу.
Давайте сначала разберемся с javascript:
$(document).ready(function() {
// When we change the value of the select...
// evt contains the information about the event:
// element receiving the action, the action itself, etc.
$('#amount_show').change(function(evt) {
// Cancel the default browser action
evt.preventDefault()
// Get the target url of the form (our php script)
url = $(this).parent().attr('action')
// Call the funtion that will be doing the request
ajaxLoad(url)
});
// When we click a pagination link... (Explanation below)
$('.items').on('click', '.pagination li a', function(evt) {
evt.preventDefault()
url = $(this).attr('href')
ajaxLoad(url)
});
// Do the actual request
function ajaxLoad(url) {
// How many records do we want to show ?
query_params = {
amount_show: $('#amount_show').val()
};
// Show an indication that we are working
$('.items').html('<div class="loading">Loading...</div>')
$.ajax({
type: "GET",
url: url, // Call php, it will default to page 1 if there's no parameter set
// When calling a link with a page parameter this will be smart
// enough to append the variable to the query string correctly
data: $.param(query_params),
// Handle the data return. In a perfect world, this is always successful
success: function(data) {
// Insert the data in the document.
$('.items').fadeOut('1000', function() { $(this).html(data) }).fadeIn('1000')
}
});
}
});
Строка $('.items').on('click', '.pagination li a', function(evt) {
присоединяет слушатель события делегата кЭлемент .items
, который будет реагировать на события click
, полученные .pagination li a
.Причина сделать это вместо непосредственного присоединения к самому элементу двоякая:
- Уменьшите количество элементов, к которым мы должны подключиться и прикрепить слушателя.
- Handleдинамическая вставка элементов.При переключении контента мы удаляем элементы из документа и их слушателей вместе с ними.Мы должны были бы присоединять их снова при каждой загрузке страницы, в противном случае, если не было подключенных слушателей, они вернулись бы к действию по умолчанию.Но так как этот элемент не меняется, нам не нужно это делать.
Теперь для php.Так как вы заинтересованы в использовании одного файла, я просто собираюсь что-то изменить, но это будет (в основном) то, что у вас есть сейчас.
Примечание: Возможно, я неправильно понял, что вы подразумеваете подимея все на одной странице.Если это частичный шаблон, который вы включаете в свой основной индекс, вам придется изменить цели ссылки и действие, чтобы форма указывала на него, настроить некоторые селекторы javascript, и вы можете пропустить проверку всего запроса ajax.Основные изменения:
- Удалите вызов функции
onchange
. - Измените параметр
POST
на GET
параметр. - Добавьте
.items
span
Вставить элементы, так как он не существует. Определите, является ли загрузка страницы ajax-загрузкой или обычной, используя X-Requested-With
header .Альтернативой этому является возвращение полного ответа в любом случае и его фильтрация с помощью jQuery.
<?php
if (isset($_GET['page'])) :
$page = $_GET['page'] ?: '';
else :
$page = 1;
endif;
if (isset($_GET['amount_show'])) :
$records_by_page = $_GET['amount_show'];
else :
$records_by_page = 10;
endif;
$localization_sql = ($page-1) * $records_by_page;
$sql = "SELECT id,title,description
FROM news
ORDER BY id DESC LIMIT $localization_sql, $records_by_page";
$stmt = $con->prepare($sql);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows>0) :
// Start capturing the output
ob_start();
?>
<table id="myTable" class="table table-condensed table-hover table-striped bootgrid-table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$stmt->bind_result($id,$title,$description);
while ($stmt->fetch()) :
echo '<tr>
<td>'.$id.'</td>
<td>'.$title.'</td>
<td>'.$description.'</td>
<td>Edit</td>
</tr>';
endwhile;
$stmt->close();
?>
</tbody>
</table>
<div class=pagination>
<ul class="pagination">
<?php
// When requesting an out-of-bounds page, this won't execute resulting in
// a blank page with no paginator
$sql = "SELECT * FROM news";
$stmt = $con->prepare($sql);
$stmt->execute();
$stmt->store_result();
$BD_records = $stmt->num_rows;
$stmt->close();
$con->close();
$total_page = ceil($BD_records / $records_by_page);
$prev = $page - 1;
$next = $page + 1;
if ($prev > 0) :
echo "<li><a href='" . $_SERVER['PHP_SELF'] . "?page=1'><i class='icon-angle-double-arrow'></i></a></li>";
echo "<li><a href='" . $_SERVER['PHP_SELF'] . "?page=$prev'><i class='icon-angle-left'></i></a></li>";
endif;
for ($i=1; $i<=$total_page; $i++) :
if ($page==$i) :
echo "<li><a class='page-link active' >". $page . "</a></li>";
else :
echo "<li><a class='page-link' href='" . $_SERVER['PHP_SELF'] . "?page=$i'>$i</a></li>";
endif;
endfor;
if ($page < $total_page ) :
echo "<li><a class='page-link' href='index2.php?page=$next'><i class='icon-angle-right'></i></a></li>";
echo "<li><a class='page-link' href='index2.php?page=$total_page'><i class='icon-angle-double-right'></i></a></li>";
endif;
echo '</ul></div>';
// Get the output into a variable
$results_table = ob_get_clean();
else :
$results_table = "<div>No results found</div>";
$stmt->close();
endif;
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) :
// If is an ajax request, output just the result table and exit
echo $results_table;
die;
endif;
// Print the whole page if its not an ajax request
?>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js'/>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js' />
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css' type='text/css' />
<div id='wrapper'>
<div class='container'>
<div id='news-header' class='bootgrid-header container-fluid'>
<div class='row'>
<div class='col-sm-12 actionBar'>
<div class='search-bar'>
<input type='text' id='myInput' placeholder='What are you looking for?'>
</div>
<div class='actions btn-group'>
<form action=<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>'>
<select id='amount_show' name='amount_show'>
</select>
</form>
</div>
</div>
</div>
</div>
<span class='items'>
<?php echo $results_table; ?>
</span>
</div>
</div>
Для полноты, альтернативный метод, не разделяющий ответы с помощью php, заключается в фильтрации ответа с помощьюjQuery, выполнив следующие действия в обратном вызове ajax
success
(fades пропущен):
results_table = $(data).find('.items').html()
$('.items').html(results_table)
Это преобразует ответ от сервера в объект jQuery и позволяет применять функции фильтрации как обычно.Мы извлекаем интересующий нас контент (содержимое items
: таблица результатов и разбиение на страницы), затем просто добавляем его в контейнер items
на нашей существующей странице.
ОБНОВЛЕНИЕ: Я разместил упрощенный пример без кода, связанного с базой данных здесь .Я думаю, что происходит что-то странное, когда вы копируете и вставляете код из / в редактор.
Ссылки