Фильтр по тегам. Компонент Битрикс news

Теги храним в свойстве тип список TAGS.


news

<?$APPLICATION->IncludeComponent(
    "bitrix:news",
    "news",
    Array(
        // ...
        "DISPLAY_TOP_PAGER" => "N",
        "FILTER_FIELD_CODE" => array("",""),
        "FILTER_NAME" => "catalogFilter",
        "FILTER_PROPERTY_CODE" => array("TAGS",""),
        // ...
    )
);?>

news.php

Перед news.list

<? if ($arParams["USE_FILTER"] === "Y") {
            $APPLICATION->IncludeComponent(
                "bitrix:catalog.filter",
                "tags",
                [
                    "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
                    "IBLOCK_ID" => $arParams["IBLOCK_ID"],
                    "FILTER_NAME" => $arParams["FILTER_NAME"],
                    "FIELD_CODE" => $arParams["FILTER_FIELD_CODE"],
                    "PROPERTY_CODE" => $arParams["FILTER_PROPERTY_CODE"],
                    "CACHE_TYPE" => $arParams["CACHE_TYPE"],
                    "CACHE_TIME" => $arParams["CACHE_TIME"],
                    "CACHE_GROUPS" => $arParams["CACHE_GROUPS"],
                    "PAGER_PARAMS_NAME" => $arParams["PAGER_PARAMS_NAME"],
                    "PREFILTER_NAME" => $arParams["FILTER_NAME"],
                ],
                $component,
                ['HIDE_ICONS' => 'Y']
            );
        } ?>

catalog.filter

template.php

<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
    die();
}
/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
$this->setFrameMode(true);

use Bitrix\Main\Application;

$request = Application::getInstance()->getContext()->getRequest();
$filterTags = $request->get("catalogFilter_pf")['TAGS'];
?>
<div class="col filter-btns__box">
    <form name="<? echo $arResult["FILTER_NAME"] . "_form" ?>" id="formTags"
          action="<? echo $arResult["FORM_ACTION"] ?>" method="get">
        <input class="tag_value" type="hidden" name="catalogFilter_pf[TAGS]" value="">
        <? foreach ($arResult["ITEMS"] as $arItem) {
            if (array_key_exists("HIDDEN", $arItem)) {
                echo $arItem["INPUT"];
            }
        } ?>
        <div class="filter-btns__box">
            <button class="tag-button all__btn" type="button" data-filter-value="all">Все</button>
            <? foreach ($arResult["ITEMS"] as $arItem) { ?>
                <? if (!array_key_exists("HIDDEN", $arItem)) {
                    foreach ($arItem['LIST'] as $l => $listItem) {
                        if ($l === '') {
                            continue;
                        }
                        ?>
                        <button class="tag-button<?=(int) $filterTags === $l ? ' active' : ''?>" type="button"
                                data-filter-value="<?=$l?>"><?=$listItem?></button>
                        <?
                    } ?>
                <? }
            } ?>
        </div>
        <div class="form_cta d-none">
            <input type="submit" name="set_filter" value="<?=GetMessage("IBLOCK_SET_FILTER")?>"/>
            <input type="hidden" name="set_filter" value="Y"/>
            <input type="submit" name="del_filter" value="<?=GetMessage("IBLOCK_DEL_FILTER")?>"/>
        </div>
    </form>
</div>

script.js

document.addEventListener('DOMContentLoaded', () => {
    let formTags = document.querySelector('#formTags')

    if(formTags) {
        let valueInput = formTags.querySelector('input.tag_value')
        let tagsButtons = formTags.querySelectorAll('.tag-button')

        tagsButtons.forEach(tagButton => {
            tagButton.addEventListener('click', (e) => {
                if (tagButton.dataset.filterValue === 'all') {
                    window.location.href='/news/';
                } else {
                    valueInput.value = tagButton.dataset.filterValue
                    formTags.submit()
                }
            })
        })
    }
});

style.css

.filter-btns__box {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 15px;
    min-width:55%;
}

.filter-btns__box #formTags {
    margin: 0;
    padding: 0;
}

.filter-btns__box button {
    background: transparent;
    border: 1px solid rgba(116, 134, 151, 0.5);
    border-radius: 30px;
    color: rgba(116, 134, 151, 0.7);
    font-size: 16px;
    line-height: 1;
    padding: 12px 18px;
    transition: all 0.2s ease-in-out;
}

.filter-btns__box .all__btn {
    background: var(--blue);
    border: 1px solid var(--blue);
    color: var(--white);
}

.filter-btns__box .all__btn.active,
.filter-btns__box .all__btn:active,
.filter-btns__box .all__btn:hover {
    background: var(--dark-blue);
    color: var(--white);
}

.filter-btns__box button.active,
.filter-btns__box button:active,
.filter-btns__box button:hover {
    background: #c6ced6;
    border: 1px solid #c6ced6;
    color: var(--greyblue);
}

.sorting-box {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin: 0 0 40px;
}

.sort-btns__box {
    align-items: center;
    display: flex;
    justify-content: flex-end;
    gap: 24px;
    margin: 4px 0 0;
    text-align: right;
}

.sort-btns__box span {
    color: var(--greyblue);
    font-size: 20px;
    font-weight: 500;
    line-height: 22px;
    letter-spacing: -0.02em;
}

.sort-btns__box button {
    background: none;
    border-left: 0;
    border-top: 0;
    border-right: 0;
    border-bottom: 2px dashed var(--greyblue);
    color: var(--greyblue);
    font-size: 20px;
    font-weight: 500;
    line-height: 22px;
    letter-spacing: -0.02em;
    opacity: 0.45;
    padding: 0;
    transition: all 0.2s ease-in-out;
}

.sort-btns__box button:active,
.sort-btns__box button:focus,
.sort-btns__box button:hover {
    border-bottom: 2px dashed transparent;
    opacity: 1;
}

.sort-btns__box .active {
    align-items: center;
    border-bottom-color: #66839f;
    color: #66839f;
    display: flex;
    justify-content: flex-end;
    margin-right: 20px;
    opacity: 1;
    position: relative;
}

.sort-btns__box .active:after {
    background: no-repeat left top / 100% 100% url(../../../../assets/img/sorting_arrow.svg);
    transform: rotateZ(180deg);
    content: "";
    display: inline-block;
    height: 15px;
    position: absolute;
    right: -20px;
    width: 13px;
}

.sort-btns__box .active.up:after {
    transform: rotateZ(0);
}

@media (max-width: 1440px) {
    .filter-btns__box button {
        padding: 10px 18px;
    }

    .sorting-box {
        margin: 0 0 34px;
    }

    .sort-btns__box span,
    .sort-btns__box button {
        font-size: 18px;
    }
}

@media (max-width: 1280px) {
    .filter-btns__box button {
        padding: 8px 16px;
    }

    .sorting-box {
        margin: 0 0 28px;
    }

    .sort-btns__box span,
    .sort-btns__box button {
        font-size: 16px;
    }
}

@media (max-width: 880px) {
    .filter-btns__box button {
        font-size: 13px;
    }

    .sorting-box .filter-btns__box {
        flex: none;
        width: 100%;
    }

    .filter-btns__box button {
        font-size: 15px;
    }

    .sorting-box {
        justify-content: flex-start;
    }

    .sort-btns__box {
        flex: none;
        justify-content: flex-start;
        margin-top: 20px;
        text-align: left;
        width: 100%;
    }

    .sort-btns__box span {
        font-size: 15px;
    }
}

@media (max-width: 732px) {
    .sorting-box {
        margin: 0 0 24px;
    }
}

@media (max-width: 480px) {
    .filter-btns__box button {
        font-size: 12px;
    }

    .filter-btns__box {
        gap: 8px;
    }

    .sort-btns__box span,
    .sort-btns__box button {
        font-size: 12px;
    }

    .sort-btns__box button {
        line-height: 16px;
    }

    .sort-btns__box {
        gap: 12px;
    }
}

@media (max-width: 375px) {
    .filter-btns__box {
        gap: 8px;
    }

    .filter-btns__box button {
        font-size: 10px;
    }

    .filter-btns__box button {
        padding: 6px 12px;
    }

    .sort-btns__box span,
    .sort-btns__box button {
        font-size: 10px;
    }
}

МОЖЕТ БЫТЬ ПОЛЕЗНО


Частенько используется вместе с сортировкой. Сортировка тут