簡體   English   中英

從 PHP 下拉列表中過濾搜索結果

[英]Filter Search Results from a Dropdown in PHP

我已經建立了一個搜索 ( https://brawlins.com/oer/index.php ),我希望用戶能夠在初始搜索后選擇過濾器來限制搜索結果。 我在我的搜索頁面 ( https://brawlins.com/oer/search.php?term= ) 的下拉菜單中填充了過濾器,但我不確定一旦用戶點擊它們后如何過濾結果。 我希望用戶也能夠選擇多個選項。 我創建了一個類來存儲過濾器。 下面是我的過濾器類的代碼:

    <?php
class filterContentProvider {

    private $conn;

    public function __construct($conn) {
        $this->conn = $conn;
    }

    public function getType ($conn) {

        $query = $this->conn->prepare("SELECT type, COUNT(*) as total FROM oer_search GROUP BY type");
        $query->execute();

        $filterHTML .= "<h3 class='filterTitle'>Type</h3>";  
        $filterHTML .= "<div class'dropdown'>";
        $filterHTML .= "<button class='btn btn-filter dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>Select - Type</button>";
        $filterHTML .= "<div class='dropdown-menu scrollable-menu' aria-labelledby='dropdownMenuButton'>";

        //$filterHTML .= "<option value=''>- Type -</option>"; 

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $type = $row["type"];
            $total = number_format($row["total"]);
            $filterHTML .= "<a class='dropdown-item' href='search.php?type=$type'>$type ($total)</a>";
        }

        $filterHTML .= "</div>";
        $filterHTML .= "</div>"; //end of dropdown

        return $filterHTML;
    }

    public function getSubject ($conn) {

        $query = $this->conn->prepare("SELECT subject, COUNT(*) as total  FROM oer_search GROUP BY subject");
        $query->execute();

        $filterHTML .= "<h3 class='filterTitle'>Subject</h3>";  
        $filterHTML .= "<div class'dropdown'>";
        $filterHTML .= "<button class='btn btn-filter dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>Select - Subject</button>";
        $filterHTML .= "<div class='dropdown-menu scrollable-menu' aria-labelledby='dropdownMenuButton'>";

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $subject = $row["subject"];
            $total = number_format($row["total"]);
            if ($subject != "") {
              $filterHTML .= "<a class='dropdown-item' href='search.php?subject=$subject'>$subject ($total)</a>";  
            }
        }

        $filterHTML .= "</div>";
        $filterHTML .= "</div>"; //end of dropdown

        return $filterHTML;
    }


    public function getLicense ($conn) {

        $query = $this->conn->prepare("SELECT license, COUNT(*) as total FROM oer_search GROUP BY license");
        $query->execute();

        $filterHTML .= "<h3 class='filterTitle'>License</h3>";  
        $filterHTML .= "<div class'dropdown'>";
        $filterHTML .= "<button class='btn btn-filter dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>Select - License</button>";
        $filterHTML .= "<div class='dropdown-menu scrollable-menu' aria-labelledby='dropdownMenuButton'>"; 

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $license = $row["license"];
            $total = number_format($row["total"]);
            if ($license != "") {
              $filterHTML .= "<a class='dropdown-item' href='index-test.php?license=$license'>$license ($total)</a>";  
            }
        }

        $filterHTML .= "</div>";
        $filterHTML .= "</div>"; //end of dropdown

        return $filterHTML;
    }

    public function getReviewed ($conn) {

        $query = $this->conn->prepare("SELECT review, COUNT(*) as total FROM oer_search GROUP BY review");
        $query->execute();

        $filterHTML .= "<h3 class='filterTitle'>Reviewed</h3>";  
        $filterHTML .= "<div class'dropdown'>";
        $filterHTML .= "<button class='btn btn-filter dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>Select - Reviewed</button>";
        $filterHTML .= "<div class='dropdown-menu scrollable-menu' aria-labelledby='dropdownMenuButton'>"; 

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $review = $row["review"];
            $total = number_format($row["total"]);
            if ($review != "") {
              $filterHTML .= "<a class='dropdown-item' href='index-test.php?review=$review'>$review ($total)</a>";  
            }
        }

        $filterHTML .= "</div>";
        $filterHTML .= "</div>"; //end of dropdown

        return $filterHTML;
    }

    public function getOrigin ($conn) {

        $query = $this->conn->prepare("SELECT source, COUNT(*) as total FROM oer_search GROUP BY source");
        $query->execute();

        $filterHTML .= "<h3 class='filterTitle'>Source</h3>";  
        $filterHTML .= "<div class'dropdown'>";
        $filterHTML .= "<button class='btn btn-filter dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>Select - Source</button>";
        $filterHTML .= "<div class='dropdown-menu scrollable-menu' aria-labelledby='dropdownMenuButton'>"; 

        while($row = $query->fetch(PDO::FETCH_ASSOC)) {
            $source = $row["source"];
            $total = number_format($row["total"]);
            if ($source != "") {
              $filterHTML .= "<a class='dropdown-item' href='index-test.php?source=$source'>$source ($total)</a>";  
            }
        }

        $filterHTML .= "</div>";
        $filterHTML .= "</div>"; //end of dropdown

        return $filterHTML;
    }

}

?>

這是我在 search.php 頁面上使用的代碼。 任何幫助將非常感激。

<?php   
include("config.php");
include("classes/siteResultsProvider.php");
include("classes/imageResultsProvider.php");
include("classes/filterContentProvider.php");
include("classes/filterImageProvider.php");

    if(isset($_GET["term"])){
        $term = $_GET["term"];
    }

    if(isset($_GET["collection"])){
        $collection = $_GET["collection"];
    }
    else {
        $collection = "open_content";
    }

    $page = isset($_GET["page"]) ? $_GET["page"] : 1;

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <title>SOAR</title>
<?php
include("header.php");
?>

    <div class="wrapper">
        <div class="header">
            <div class="headerContent">
                <div class="searchContainer">
                    <form action="search.php" method="GET">
                        <div class="searchBarContainer">
                            <input type="hidden" name="collection" value="<?php echo $collection; ?>">
                            <input class="searchBox" type="text" name="term" value="<?php echo htmlspecialchars($term, ENT_QUOTES) ?>" aria-label="search box">
                            <button class="searchButton">
                                <img src="images/search-icon.png" alt="search icon">
                            </button>
                        </div>
                    </form>
                </div>

            </div><!--end of headerContent-->

            <div class="tabsContainer">
                <ul class="tabList">
                    <li class="<?php echo $collection == 'open_content' ? 'active' : '' ?>">
                        <a href='<?php echo "search.php?term=$term&collection=open_content"; ?>'><i class="fas fa-book-open"></i> Open Content</a>
                    </li>
                    <li class="<?php echo $collection == 'images' ? 'active' : '' ?>">
                        <a href='<?php echo "search.php?term=$term&collection=images"; ?>'><i class="fas fa-images"></i> Images</a>
                    </li>
                </ul>
            </div>
        </div><!--end of header-->

<!-------------------------beginning of main section where seach results will display-------------------------->
        <?php
                if($collection == "open_content") {
                    $filters = new filterContentProvider($conn);
                }
                else {
                    $filters = new filterImageProvider($conn);
                }

           if($collection == "open_content") {

                $filterType = $filters->getType($conn);
                $filterSubject = $filters->getSubject($conn);
                $filterOrigin = $filters->getOrigin($conn);
                $fitlerLicense = $filters->getLicense($conn);
                $filterReviewed = $filters->getReviewed($conn);

                echo "<div class='filterContainer'>
                        <div class='filterContent'>
                            <div class='filter'>
                                $filterType
                            </div>
                            <div class='filter'>
                                $filterSubject
                            </div>
                            <div class='filter'>
                                $filterOrigin
                            </div>
                            <div class='filter'>
                                $fitlerLicense
                            </div>
                            <div class='filter'>
                                $filterReviewed
                            </div>
                        </div>
                     </div>"; 
            }
            else {

                $imageFilterOrigin = $filters->getImageOrigin($conn);
                $imageFilterLicense = $filters->getImageLicense($conn);

                echo "<div class='filterContainer'>
                            <div class='filterContent'>
                                <div class='filter'>
                                    $imageFilterOrigin
                                </div>
                                <div class='filter'>
                                    $imageFilterLicense
                                </div>
                            </div>
                         </div>"; 

            }

        ?>

        <div class="mainResultsSection">

            <?php

                if($collection == "open_content") {
                    $resultsProvider = new siteResultsProvider($conn);
                    $pageSize = 25;
                }
                else {
                    $resultsProvider = new imageResultsProvider($conn);
                    $pageSize = 50;
                }  

                $numResults = $resultsProvider->getNumResults($term);

                echo "<p class='resultsCount'>" . number_format($numResults) . " results found</p>";

                echo $resultsProvider->getResultsHTML($page, $pageSize, $term);
            ?>

        </div>

        <div class="paginationContainer">
            <div class="pageButtons">
                <div class="pageNumberContainer">
                    <img src="images/pageStart.png" alt="Start of page image">
                </div>

                <?php
                    $pagesToShow = 10;
                    $numPages = ceil($numResults / $pageSize);
                    $pagesLeft = min($pagesToShow, $numPages);

                    $currentPage = $page - floor($pagesToShow / 2);

                    if($currentPage < 1) {
                        $currentPage = 1;
                    }

                    if($currentPage + $pagesLeft > $numPages + 1) {
                        $currentPage = $numPages + 1  - $pagesLeft;
                    }

                    while($pagesLeft != 0 && $currentPage <= $numPages) {

                        if($currentPage == $page) {
                            echo "<div class='pageNumberContainer'>
                                <img src='images/pageSelected.png' alt='selected page page image'/>
                                <span class='pageNumber'>$currentPage</span>
                                </div>";
                        }
                        else {
                            echo "<div class='pageNumberContainer'>
                                    <a href='search.php?term=$term&collection=$collection&page=$currentPage'>
                                        <img src='images/page.png' alt='pages image'/>
                                        <span class='pageNumber'>$currentPage</span>
                                    </a>
                                </div>";
                        }

                        $currentPage++;
                        $pagesLeft--;

                    }
                ?>

                <div class="pageNumberContainer">
                    <img src="images/pageEnd.png" alt="End of page image">
                </div>
            </div>

        </div><!--end of pagination container-->
    </div><!--end of wrapper-->

    <script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
    <script type="text/javascript" src="js/script.js"></script>
</body>
</html>

似乎您需要做一些事情才能使其正常工作。

如果您希望結果是異步的:

  1. 為您選擇的輸入添加一個 onchange 事件。 (類似於onchange="addFilter('type', this.value)" )見https://www.w3schools.com/jsref/event_onchange.asp
  2. 讓 onchange 函數 ( addFilter ) 通過 AJAX 請求將過濾器和查詢字符串發送回您的 PHP 腳本。 如果您使用 jQuery, get方法對您有用。 https://api.jquery.com/jquery.get/
  3. 使用您傳遞的 $_GET 參數在 PHP 中提取新結果。 (就像您已經在腳本中所做的那樣。)您將只想回顯結果——而不是頁面的導航和其他元素。
  4. 使用(類似於$('#myContainer').html(results);在 jQuery 中)更新頁面上的搜索結果
  5. 此外,最好更新地址欄中的 URL 參數如何在不重新加載頁面的情況下修改 URL?

這是一個非常簡單的例子:

測試文件

<?php

// Look up the results here
// You'll probably want to do something more performant that this; it's just a lazy example. :)
// ...
$query = $this->conn->prepare("SELECT type, COUNT(*) as total FROM oer_search WHERE type LIKE :type AND subject LIKE :subject GROUP BY type");
$query->execute([
  'type' => isset($_GET['type'] ? $_GET['type'] : '%',
  'subject' => isset($_GET['subject'] ? $_GET['subject'] : '%',
]);
// ...
?>

索引.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="jquery-3.4.1.min.js"></script>
  <script>
    function addFilter(name, value) {
      var url = '/test.php?';
      var urlParams = new URLSearchParams(window.location.search);
      var keys = urlParams.keys();
      for(key of keys) { 
        if (key == name) {
          continue;
        }
        url += key + '=' + urlParams.get(key) + '&';
      }

      url += name + '=' + value;
      window.history.pushState({}, "", );
      $.get(url, function(data) {
        $('#results').html(data);
      });
    }
  </script>
</head>
<body>
  <select onchange="addFilter('type', this.value)">
    <option></option>
    <option>value 1</option>
    <option>value 2</option>
  </select>
  <select onchange="addFilter('subject', this.value)">
    <option></option>
    <option>value 1</option>
    <option>value 2</option>
  </select>
  <div id="results"></div>
</body>
</html>

如果您不關心/希望頁面重新加載:

只需讓onchange事件再次提交帶有搜索參數的表單即可。 如果您使用 jQuery,則submit方法將起作用。 確保在選擇輸入中適當地選擇選項,否則它們每次都會清除(因此無法設置多個)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM