Как отобразить страницу с помощью ajax? - PullRequest
0 голосов
/ 10 октября 2018

У меня есть нумерация страниц, которая работает правильно, даже если я добавил фильтр для разбивки на несколько строк на одной странице, это означает, что через фильтр я могу показать 10 или 50 строк.

Небольшой дефект, который яВ моем коде есть то, что страница перезагружается, изменяя количество отображаемых строк, и то же самое происходит в кнопках нумерации страниц.

Это мой код, все работает на одной странице index2.php .

<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" onkeyup="myFunction()" placeholder="What are you looking for?">
                    </div>
                    <div class="actions btn-group">
                        <?php
                            $select_quantity = '';
                            if (isset($_POST['amount_show'])) :
                                $select_quantity = $_POST['amount_show'];
                            endif;
                        ?>
                        <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
                            <select id="amount_show" name="amount_show" onchange="this.form.submit()">
                                <option value="10" <?php if ($select_quantity==10) echo "selected"; ?>>10</option>
                                <option value="25" <?php if ($select_quantity==25) echo "selected"; ?>>25</option>
                                <option value="50" <?php if ($select_quantity==50) echo "selected"; ?>>50</option>
                                <option value="100" <?php if ($select_quantity==100) echo "selected"; ?>>100</option>
                            </select>
                        </form>
                    </div>
                </div>
            </div>
        </div>
        <?php
            if (isset($_GET['page'])) :
                $page = $_GET['page'] ?: '';
            else :
                $page = 1;
            endif;

            if (isset($_POST['amount_show'])) :
                $records_by_page = $_POST['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) :

            echo '<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>';

            $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;
            echo '</tbody>';
            echo '</table>';
            $stmt->close();


            $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;
            echo '<div class=pagination>
            <ul class="pagination">';
            if ($prev > 0) :
                echo "<li><a href='index2.php?page=1'><i class='icon-angle-double-arrow'></i></a></li>";
                echo "<li><a href='index2.php?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=active>". $page . "</a></li>";
                else :
                    echo "<li><a href='index2.php?page=$i'>$i</a></li>";
                endif;
            endfor;


            if ($page < $total_page ) :
                echo "<li><a href='index2.php?page=$next'><i class='icon-angle-right'></i></a></li>";
                echo "<li><a href='index2.php?page=$total_page'><i class='icon-angle-double-right'></i></a></li>";
            endif;

            echo '</ul></div>';

            else :
                $stmt->close();
            endif;

        ?>
    </div>
</div>

При поиске в Интернете я нашел код ajax, но, честно говоря, мне не удалось использовать код ajax или javascript / jquery.

Вы можете объяснить, какреализовать этот код ajax или как избежать небольшого дефекта перезагрузки страницы.

<script type="text/javascript">
$(document).ready(function() {  
    $('.pagination li a').on('click', function(){
        /*$('.items').html('<div class="loading"><img src="images/loading.gif" width="70px" height="70px"/><br/>Loading...</div>');*/
        $('.items').html('<div class="loading">Loading...</div>');

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

        $.ajax({
            type: "GET",
            url: "ajax.php",
            data: dataString,
            success: function(data) {
                $('.items').fadeIn(2000).html(data);
                $('.pagination li').removeClass('active');
                $('.pagination li a[data="'+page+'"]').parent().addClass('active');

            }
        });
        return false;
    });              
});    
</script>

Вот как работает мой код, как показано на следующем рисунке:

enter image description here

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Нет смысла начинать играть с jquery и асинхронными вызовами, если даже чистый html немного превышает ограничение.В исходном коде вы смешиваете POST и GET, используйте только один.

<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" onkeyup="myFunction()" placeholder="What are you looking for?">
                    </div>
                    <div class="actions btn-group">
                        <?php
    //getting both - page and record_by_page from GET
                            $records_by_page = isset($_GET['amount_show'])?$_GET['amount_show']:10;
                            $page = isset($_GET['page'])?$_GET['page']:1;
    //put page value into form to send it together with amount_show
                        ?>
                        <form method="get" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
                            <select id="amount_show" name="amount_show" onchange="this.form.submit()">
                                <option value="10" <?php if ($records_by_page==10) echo "selected"; ?>>10</option>
                                <option value="25" <?php if ($records_by_page==25) echo "selected"; ?>>25</option>
                                <option value="50" <?php if ($records_by_page==50) echo "selected"; ?>>50</option>
                                <option value="100" <?php if ($records_by_page==100) echo "selected"; ?>>100</option>
                            </select>
                            <input type="hidden" id="page" name="page" value="<?php echo $page; ?>"></input>
                        </form>
                    </div>
                </div>
            </div>
        </div>
        <?php


            $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) :

            echo '<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>';

            $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;
            echo '</tbody>';
            echo '</table>';
            $stmt->close();


            $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;
            echo '<div class=pagination>
            <ul class="pagination">';
//add amount_show to each request
            if ($prev > 0) :
                echo "<li><a href='pagination.php?page=1&amount_show=$records_by_page'><i class='icon-angle-double-arrow'></i></a></li>";
                echo "<li><a href='pagination.php?page=$prev&amount_show=$records_by_page'><i class='icon-angle-left'></i></a></li>";
            endif;

            for ($i=1; $i<=$total_page; $i++) :
                if ($page==$i) :
                    echo "<li><a class=active>". $page . "</a></li>";
                else :
                    echo "<li><a href='pagination.php?page=$i&amount_show=$records_by_page'>$i</a></li>";
                endif;
            endfor;


            if ($page < $total_page ) :
                echo "<li><a href='pagination.php?page=$next&amount_show=$records_by_page'><i class='icon-angle-right'></i></a></li>";
                echo "<li><a href='pagination.php?page=$total_page&amount_show=$records_by_page'><i class='icon-angle-double-right'></i></a></li>";
            endif;

            echo '</ul></div>';

            else :
                $stmt->close();
            endif;

        ?>
    </div>
</div>  
0 голосов
/ 18 октября 2018

Давайте начнем с причины, по которой ваша страница перезагружается: действия браузера по умолчанию .Несколько элементов 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 на нашей существующей странице.

ОБНОВЛЕНИЕ: Я разместил упрощенный пример без кода, связанного с базой данных здесь .Я думаю, что происходит что-то странное, когда вы копируете и вставляете код из / в редактор.

Ссылки

0 голосов
/ 16 октября 2018

Ajax будет обновлять информацию на вашей странице без перезагрузки вашей страницы.Мы хотим отделить данные от HTML, чтобы мы могли изменить, какие данные мы видим.Мы не можем этого сделать, если PHP - это инструмент для записи данных в HTML.Поэтому я рекомендую разделить index2.php на несколько файлов.В этом примере используется JSON.

Сбор данных

ajax.php

<?php
$data_rows = array();

for ($i = 0; $i < 1000; $i++) {
    $data_rows[] = array(
        "id" => "id_$i",
        "title" => "title_$i",
        "description" => "description_$i",
    );
}

echo json_encode($data_rows, JSON_PRETTY_PRINT);

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

Редактировать:

ajax.php

if (isset($_GET['page'])) :
                $page = $_GET['page'] ?: '';
            else :
                $page = 1;
            endif;

            if (isset($_POST['amount_show'])) :
                $records_by_page = $_POST['amount_show'];
            else :
                $records_by_page = 10;
            endif;

$sql = "SELECT id, title, description
FROM news
ORDER BY id DESC LIMIT $localization_sql, $records_by_page";
$result = $con->query($sql);
$data_rows = array();
while ($row = $result->fetch_assoc()) {
    $data_rows = $row;
}

echo json_encode($data_rows, JSON_PRETTY_PRINT);

Ваш исходный код включает в себя соединение mysqli, этоэто данные, к которым у меня нет доступа, поэтому я не могу проверить эффективность этого скрипта.Однако это должно представить все данные, о которых вы спрашиваете.

Ajax с jQuery

script.js

$(document).ready(function() {  
 $.ajax({
            type: "GET",
            url: "ajax.php",
            dataType: "json",
            success: function(data) {
                tableRows = '';
                for (let i = 0; i < data.length; i++) {
                    tableRows += `
                    <tr>
                        <td>${data[i].id}</td>
                        <td>${data[i].title}</td>
                        <td>${data[i].description}</td>
                        <td>Edit<td>
                    </tr>`;
                }
                $("#tbody-insert").html(tableRows);
            }
    });              
}); 

Установите параметр url вашего ajaxвызовите имя php-файла, который доставляет данные.В примере я использую JSON, важно установить dataType: "json".jQuery автоматически проанализирует это для вас.Вы можете видеть в параметре успеха, data это имя массива php, который мы создали.Я использовал простой цикл for для создания группы строк таблицы, а затем вставил их в тело таблицы, которое я пометил id="tbody-insert".

Представить данные

index.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<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 id="tbody-insert">

    </tbody>
</table>

Я удалил весь PHP из вашей индексной страницы, он не очень гибкий и требует перезагрузки всей страницы перед обновлением информации.Важные моменты, на которые следует обратить внимание, - это теги сценариев, вам нужно включить jQuery, а также скрипт.js.Вам также необходимо иметь идентификатор для тела таблицы, в которую мы вставляем информацию.Вы можете обернуть ваш ajax в функцию, которая вызывается каждый раз, когда вы хотите разбить на страницы, и запрашивать ajax.php для разных страниц.Я не знаю структуру ваших данных, поэтому больше не могу помочь с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...