Как реализовать фильтр для таблицы с php - PullRequest
0 голосов
/ 11 марта 2020

Я работаю над таблицей обзора для некоторых данных, пытающихся понять, как реализовать параметр фильтра.

Таблица выглядит следующим образом:

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|

Где у меня проблема? Эта таблица является одной из 6 различных таблиц в одном файле. php, который включен в раздел содержимого. Я действительно не знаю, как выполнить фильтр для этой таблицы.

Заранее спасибо за любую идею / inout

1 Ответ

0 голосов
/ 12 марта 2020

Я не уверен, правильно ли я понял вашу модель данных. Но вот небольшой пример, как фильтровать структуры данных с помощью PHP. После части PHP я объясню, как настроить форму HTML, чтобы выводить нужные элементы в таблицу HTML.

PHP Part

Я предполагаю, что вы читаете свои данные из таблицы базы данных или 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;
    }
}

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

<?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, который упрощает фильтрацию структур данных, например p ie.

<?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. Расширению нужен системный идентификатор в качестве второго параметра в конструкторе. Системный идентификатор будет нашим аргументом фильтра. Метод accept вернет true, если свойство системного идентификатора элемента равно аргументу фильтра системного идентификатора. Если нет, метод 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 l oop просто выводит элемент 3, потому что системный идентификатор равен 2.

HTML Part

Ваш 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>

Как видите, мы используем обычную форму, которая отправит выбранную опцию фильтра в файл php с именем index.php. Каждый раз, когда кто-то нажимает кнопку «Фильтровать результаты», отправляется форма, и страница обновляется.

Вот пример индекса. php file.

<?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 запросы).

Надеюсь, этот небольшой пример фильтрации поможет.

...