【问题标题】:How to implement a Filter for a Table with php如何使用 php 实现表的过滤器
【发布时间】:2020-03-13 03:08:00
【问题描述】:

我正在为一些关于如何实现过滤器选项的数据制作概览表。

表格如下:

Process Type | Issue Total | Issue closed | Issue open
Piping       |    20       |     15       |    5
Cable pulling|

这已经是属于 Proces 类型(如管道)的各个“项目”的摘要。

“项目”与系统有关。

所以现在我想实现一个过滤器选项来过滤系统管道问题的总和

Filter: <select>
<option>1</option>
<option>2</option>
</select>
<button> Filter results</button>

Process Type | Issue Total | Issue closed | Issue open
Piping       |    20       |     15       |    5
Cable pulling|

我的问题在哪里? 此表是内容部分中包含的一个 .php 文件中的 6 个不同表之一。 我真的不知道如何在这个表上执行过滤器。

提前感谢您的任何想法/输入

【问题讨论】:

  • 你能更准确地解释你想要达到的目标吗?总和是什么意思?它是关于管道的所有三个细节的总和吗?还是您只想显示大于 1 或 2 的条目?或者您只是想显示管道问题,当有人在选择元素中选择 1 时?请更详细地描述如果有人点击按钮会发生什么。
  • 如果您不想提交表单并重新加载整个页面,那么替代方案是 AJAX。
  • @Marcel 正如我的帖子中提到的,我有几个项目类别。管道有大约 800 个项目,属于大约 20 个不同的系统(每个项目 1 个系统/1 个系统多个项目) 在我的概览表中,我现在显示所有管道问题的总和,按状态分隔。现在他们想针对不同的系统进行过滤,以仅查看系统 1 或 2 的管道问题等。

标签: php html-table


【解决方案1】:

我不确定我的数据模型是否正确。但这里有一个小例子,如何使用 PHP 过滤数据结构。在 PHP 部分之后,我将解释如何设置您的 HTML 表单,以便在您的 HTML 表格中输出所需的项目。

PHP 部分

我假设您从数据库表或 API 中读取数据。所以让我们假设我们的模型看起来像这样。该模型只是一个示例,用于展示 PHP 中面向对象的方法的外观。

<?php
declare(strict_types=1);
namespace Marcel\Model;

class Item
{
    protected $id;
    protected $systemID;
    protected $anotherProperty;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(int $id): self
    {
        $this->id = $id;
        return $this;
    }

    public function getSystemId(): ?int
    {
        return $this->systemId;
    }

    public function setSystemId(int $systemId): self
    {
        $this->systemId = $systemId;
        return $this;
    }

    public function getAnotherProperty(): ?string
    {
        return $this->anotherProperty;
    }

    public function setAnotherProperty(string $anotherProperty): self
    {
        $this->anotherProperty = $anotherProperty;
        return $this;
    }
}

如您所见,我们的项目模型只有三个属性。重要的属性将是系统 ID。稍后我们将按此属性过滤项目集合。在我们这样做之前,我们使用一个集合来存储我们所有的项目对象。为什么这个系列?在过滤集合时,集合为我们提供了一种类型安全性并使处理变得更容易。

<?php
declare(strict_types=1);
namespace Marcel\Model;

use InvalidArgumentException;
use SplObjectStorage;

class ItemCollection extends SplObjectStorage
{
    public function attach($object, $data = null): self
    {
        if (!$object instanceof Item) {
            throw new InvalidArgumentException(sprintf(
                'The given object must be of the type Item. Given: "%s"',
                get_class($object)
            ));
        }

        parent::attach($object, $data);
        return $this;
    }
}

这是我们的项目集合。该集合扩展了 PHP 内置类 SplObjectStorage,专为存储对象而设计。在这种情况下,集合只接受 Item 类型的对象。我们的集合实现了Iterator 接口,这使得集合可迭代。非常适合过滤。

接下来我们需要一个过滤器。 PHP 带来了一个内置的FilterIterator 类,这使得过滤数据结构变得容易。

<?php
declare(strict_types=1);
namespace Marcel\Filter;

class ItemFilterIterator extends FilterIterator
{
    protected $systemId;

    public function __construct(Iterator $iterator, int $systemId = 0)
    {
        parent::__construct($iterator);
        $this->systemId = $systemId;
    }

    public function accept(): bool
    {
        // if system id is 0 return all items
        if ($this->systemId === 0) {
            return true;
        }

        $item = $this->getInnerIterator()->current();
        return $item->getSystemId() === $this->systemId;
    }
}

这是我们的FilterIterator 实现。扩展需要系统 ID 作为构造函数中的第二个参数。系统 ID 将是我们的过滤器参数。 accept 方法将返回 true,当项目的系统 id 属性等于系统 id 过滤器参数时。如果不是,accept 方法返回 false。

让我们看看,这三个类可以为你做什么。这是一个实用的例子。首先,我将创建一些项目以用于示例目的。

<?php
declare(strict_types=1);
namspace Marcel;

use Marcel\Filter\ItemFilterIterator;
use Marcel\Model\Item;
use Marcel\Model\ItemCollection;

$item1 = (new Item())
    ->setId(1)
    ->setSystemId(1)
    ->setAnotherProperty('item 1');

$item2 = (new Item())
    ->setId(2)
    ->setSystemId(1)
    ->setAnotherProperty('item 2');

$item3 = (new Item())
    ->setId(3)
    ->setSystemId(2)
    ->setAnotherProperty('item 3');

$collection = (new ItemCollection())
    ->attach($item1)
    ->attach($item2)
    ->attach($item3);

// here comes the magic
$filter = new ItemFilterIterator($collection, 2);
foreach ($filter as $item) {
    var_dump($item);
}

在此示例中,我们有三个项目,它们属于由 sysmtem id 属性设置的两个不同系统。通常,这些项目应该来自您的数据库或您的数据集来自哪里。这些项目被设置为集合,我们使用过滤器迭代器类对其进行过滤。在这个例子中,我们只想要属于系统 2 的项目。使用此设置,foreach 循环只输出项目 3,因为系统 id 等于 2。

HTML 部分

您的 HTML 模板看起来不错。我会为你扩展一点。

<form id="my-filter-form" method="post" action="index.php">
    <label for="filter">Filter</label>
    <select name="filter" id="filter">
        <option value="">all</option>
        <option value="1">1</option>
        <option value="2">2</option>
    </select>
    <button type="submit">Filter results</button>
</form>

如你所见,我们使用了一个普通的形式,它将选择的过滤选项发送到一个名为index.php的php文件。每次有人点击“过滤结果”按钮时,都会发送表单并刷新页面。

这是一个示例 index.php 文件。

<?php
declare(strict_types=1);
namespace Marcel;

use Marcel\Filter\ItemFilterIterator;
use Marcel\Model\Item;
use Marcel\Model\ItemCollection;

// first get your items from somewhere and fill the item collection
$collection = new ItemCollection();
$collection->attach(...); // attach all the items

// check, if there 's a filter - if not use 0 to display all items
$systemID = (isset($_POST['filter'])) ? intval($_POST['filter']) : 0;

// init the filter iterator
$filter = new ItemFilterIterator($collection, $systemID);
$items = new ItemCollection();

// attach all filtered items to a new collection
foreach ($filter as $item) {
    $items->attach($item);
}
?>

<form id="my-filter-form" method="post" action="index.php">
    <label for="filter">Filter:</label>
    <select id="filter" name="filter">
        <option>all</option>
        <option value="1">system 1</option>
        <option value="2">system 2</option>
    </select>
    <button type="submit">Filter me!</button>
</form>

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>System</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($items as $item) : ?>
        <tr>
            <td><?= $item->getId() ?></td>
            <td><?= $item->getSystemId() ?></td>
            <td><?= $item->getAnotherProperty() ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

请记住,每次发送表单时页面都会重新加载。如果你想避免重新加载,你必须使用 ajax(异步 javascript 请求)。

希望这个小过滤示例有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 2010-11-07
    • 1970-01-01
    相关资源
    最近更新 更多