ساخت فیلتر محصولات با جاوا اسکرپیت و کوئری PHP

ساخت فیلتر محصولات با جاوا اسکرپیت و کوئری PHP

فیلتر محصولات PHP و جاوا اسکریپت – در این آموزش از javascript برای ساخت کنترل فرم فیلتر استفاده می کنیم و در پایان اطلاعات فیلتر را به صورت query string در آدرس URL می آوریم و امکان استفاده از این اطلاعات در PHP با سوپر گلوبال GET_$ امکان پذیر می باشد .

دموی فیلتر محصولات


در این آموزش از کتابخانه های جاوا اسکریپت select2 , persian date picker , Ion.RangeSlider و … استفاده می کنیم بنابراین می توانید کل پروژه را از اینجا دانلود کنید .

فایل index.html

<!DOCTYPE html>
<html lang="fa" dir="rtl">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Premium Multipurpose Admin & Dashboard Template">
    <title>فیلتر حرفه ای با query string - رپید کد</title>


    <link href="https://rapidcode.ir/wp-content/themes/rapidcode/static/image/sample/Logo.png" id="favicon.ico"
        rel="shortcut icon" type="ico">
    <link href="assets/css/bootstrap.min.css" id="bootstrap.all.min" rel="stylesheet" type="text/css">
    <link href="assets/css/icons.css" id="icons" rel="stylesheet" type="text/css">
    <link href="assets/css/sweetalert2.min.css" id="sweetalert2" rel="stylesheet" type="text/css">
    <link href="assets/css/select2.min.css" id="select2" rel="stylesheet" type="text/css">
    <link href="assets/css/persian-datepicker.min.css" id="datepicker.jalali" rel="stylesheet" type="text/css">
    <link href="assets/css/persian-datepicker-custom.min.css" id="datepicker.jalali.theme" rel="stylesheet"
        type="text/css">
    <link href="assets/css/ion.rangeSlider.min.css" id="ion.rangeSlider" rel="stylesheet" type="text/css">
    <link href="assets/css/app.css" id="app" rel="stylesheet" type="text/css">
    <link href="assets/custom/main.css" id="main" rel="stylesheet" type="text/css">
</head>

<body data-layout="detached" data-topbar="colored" class="product_list_php">

    <div class="container-fluid">
        <!-- Begin page -->
        <div id="layout-wrapper">

            <header id="page-topbar">
                <div class="navbar-header">
                    <div class="container-fluid">
                        <div class="float-right">

                            <div class="dropdown d-inline-block d-lg-none ml-2">
                                <button type="button" class="btn header-item noti-icon waves-effect"
                                    id="page-header-search-dropdown" data-toggle="dropdown" aria-haspopup="true"
                                    aria-expanded="false">
                                    <i class="mdi mdi-magnify"></i>
                                </button>
                                <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right p-0"
                                    aria-labelledby="page-header-search-dropdown">

                                    <form class="p-3">
                                        <div class="form-group m-0">
                                            <div class="input-group">
                                                <input type="text" class="form-control" placeholder="جستجو ..."
                                                    aria-label="Recipient's username">
                                                <div class="input-group-append">
                                                    <button class="btn btn-primary" type="submit"><i
                                                            class="mdi mdi-magnify"></i></button>
                                                </div>
                                            </div>
                                        </div>
                                    </form>
                                </div>
                            </div>



                            <div class="dropdown d-none d-lg-inline-block ml-1">
                                <button type="button" class="btn header-item noti-icon waves-effect"
                                    data-toggle="fullscreen">
                                    <i class="mdi mdi-fullscreen"></i>
                                </button>
                            </div>

                            <div class="dropdown d-inline-block">
                                <button type="button" class="btn header-item waves-effect"
                                    id="page-header-user-dropdown" data-toggle="dropdown" aria-haspopup="true"
                                    aria-expanded="false">
                                    <img class="rounded-circle header-profile-user"
                                        src="https://secure.gravatar.com/avatar/0c55399c2cb5d0deb2b1c5420ee0d49c?s=256&d=mm&r=g"
                                        alt="Header Avatar">
                                    <span class="d-none d-xl-inline-block ml-1">حسین باقری</span>
                                    <i class="mdi mdi-chevron-down d-none d-xl-inline-block"></i>
                                </button>
                                <div class="dropdown-menu dropdown-menu-right">
                                    <!-- item-->
                                    <a class="dropdown-item" href="#"><i
                                            class="bx bx-user font-size-16 align-middle mr-1"></i> پروفایل</a>
                                    <div class="dropdown-divider"></div>
                                    <a class="dropdown-item text-danger" href="#"><i
                                            class="bx bx-power-off font-size-16 align-middle mr-1 text-danger"></i>
                                        خروج</a>
                                </div>
                            </div>

                        </div>
                        <div>
                            <!-- LOGO -->
                            <div class="navbar-brand-box">
                                <a href="index-2.html" class="logo logo-dark">
                                    <span class="logo-sm">
                                        <img src="https://rapidcode.ir/wp-content/themes/rapidcode/static/image/sample/Logo.png"
                                            alt="" height="20">
                                    </span>
                                    <span class="logo-lg">
                                        <img src="https://rapidcode.ir/wp-content/themes/rapidcode/static/image/sample/Logo.png"
                                            alt="" height="17">
                                    </span>
                                </a>

                                <a href="/" class="logo logo-light">
                                    <span class="logo-sm">
                                        <img src="https://rapidcode.ir/wp-content/themes/rapidcode/static/image/sample/Logo.png"
                                            alt="" height="20">
                                    </span>
                                    <span class="logo-lg">
                                        <img src="https://rapidcode.ir/wp-content/themes/rapidcode/static/image/sample/Logo.png"
                                            alt="" height="55">
                                    </span>
                                </a>
                            </div>

                            <button type="button"
                                class="btn btn-sm px-3 font-size-16 header-item toggle-btn waves-effect"
                                id="vertical-menu-btn">
                                <i class="fa fa-fw fa-bars"></i>
                            </button>

                        </div>

                    </div>
                </div>
            </header>
            <!-- ============================================================== -->
            <!-- Start right Content here -->
            <!-- ============================================================== -->
            <div class="main-content">

                <div class="page-content">

                    <!-- start page title -->
                    <div class="row">
                        <div class="col-12">
                            <div class="page-title-box d-flex align-items-center justify-content-between">
                                <h4 class="page-title mb-0 font-size-18">لیست محصولات</h4>
                            </div>
                        </div>
                    </div>
                    <!-- end page title -->

                    <div class="row">
                        <div class="col-xl-12">

                            <div class="row">

                                <div class="col-md-12">
                                    <div class="card">
                                        <div class="card-body">

                                            <form data-route="index.html" action="" id="filter-form" method="post"
                                                novalidate>

                                                <a href="#block-wrapper-filter" data-toggle="collapse">
                                                    <h4 class="col-12 text-sm-center btn btn-info">فیلتر</h4>
                                                </a>

                                                <div class="collapse" id="block-wrapper-filter"
                                                    data-parent="#filter-form">
                                                    <div class="row" id="filter-wrapper">
                                                        <div class="filter-checklist">

                                                            <div class="select2-wrapper sort-wrapper input-wrapper active"
                                                                data-name="sort">
                                                                <select id="sort-select2" class="select2">
                                                                    <input type="text" id="sort"
                                                                        class="ds-none the-value select2-content-list"
                                                                        value="">
                                                                </select>
                                                            </div>

                                                            <button type="button" id="clear-filter"
                                                                class="btn btn-danger waves-effect waves-light">پاکسازی
                                                                فیلتر</button>

                                                            <div class="btn-group dropright">
                                                                <button type="button"
                                                                    class="btn btn-info waves-effect waves-light dropdown-toggle"
                                                                    data-toggle="dropdown" aria-haspopup="true"
                                                                    aria-expanded="false">
                                                                    <i class="mdi mdi-chevron-right"></i>فیلتر بر اساس
                                                                </button>
                                                                <div class="switch-list dropdown-menu">

                                                                </div>
                                                            </div>

                                                        </div>

                                                    </div>
                                                    <div class="text-sm-right mb-5">
                                                        <button type="submit"
                                                            class="btn btn-lg btn-block btn-success">جستجو</button>
                                                    </div>
                                                </div>

                                            </form>

                                            <table id="datatable-product-list" class="datatable table table-bordered"
                                                data-options='{"columnDefs":[{"orderable":false,"targets":13},{"orderable":false,"targets":1}]}'>
                                                <thead>
                                                    <tr>
                                                        <th data-filter data-input="numberSeperator" data-name="id">شناسه
                                                        </th>
                                                        <th data-name="thumbnail">تصویر</th>
                                                        <th data-filter data-input="text" data-name="title">عنوان</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":500000000,"from":0,"to":499000000,"step":10,"prefix":"<span class=\"d-inline-block\">تومان</span> "}'
                                                            data-name="price">قیمت (تومان)</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":10000000,"from":0,"to":9990000,"step":10,"prefix":"<span class=\"d-inline-block\">فروش</span> "}'
                                                            data-name="sale_count">تعداد فروش</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":10000000,"from":0,"to":9990000,"step":10,"prefix":"<span class=\"d-inline-block\">موجودی</span> "}'
                                                            data-name="entity">موجودی</th>
                                                        <th data-filter data-input="selectMultiple"
                                                            data-values='["<option selected value=\"1\">موجود</option>","<option value=\"0\">ناموجود</option>"]'
                                                            data-name="entity_x_val">وضعیت موجودی</th>
                                                        <th data-filter data-input="selectMultiple"
                                                            data-values='["<option selected value=\"1\">منتشرشده</option>","<option value=\"2\">ناموجود دستی</option>","<option value=\"3\">پیش نویس</option>"]'
                                                            data-name="status_page">وضعیت صفحه</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":10000000,"from":0,"to":9990000,"step":10,"prefix":"<span class=\"d-inline-block\">عدد پرسش</span> "}'
                                                            data-name="comments_questions_count">تعداد پرسش ها</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":10000000,"from":0,"to":9990000,"step":10,"prefix":"<span class=\"d-inline-block\">عدد رتبه</span> "}'
                                                            data-name="comments_rate_count">تعداد رتبه ها</th>
                                                        <th data-filter data-input="numberRange"
                                                            data-options='{"min":0,"max":5,"from":1,"to":4.8,"step":0.1,"prefix":"<span class=\"d-inline-block\">رتبه</span> "}'
                                                            data-name="comments_rate">رتبه</th>
                                                        <th data-filter data-input="dateRange"
                                                            data-options='{"timePicker": {"enabled": false}}'
                                                            data-name="timestamp_created_at">تاریخ انتشار</th>
                                                        <th data-filter data-input="dateRange"
                                                            data-options='{"timePicker": {"enabled": false}}'
                                                            data-name="timestamp_updated_at">تاریخ بروزرسانی</th>
                                                        <th>عملیات</th>
                                                    </tr>
                                                </thead>

                                                <tbody>


                                                    <tr>
                                                        <td data-seperator="true">1336</td>
                                                        <td><img width="70"
                                                                src="https://dkstatics-public.digikala.com/digikala-products/9db64cde85334e3bf4a6571547d339c57867f11f_1634032209.jpg?x-oss-process=image/resize,m_lfit,h_300,w_300/quality,q_80">
                                                        </td>
                                                        <td>گوشی موبایل اپل مدل iPhone 13 A2634 دو سیم‌ کارت ظرفیت 128
                                                            گیگابایت و رم 4 گیگابایت</td>
                                                        <td data-seperator="true">32999000</td>
                                                        <td data-seperator="true">3201</td>
                                                        <td data-seperator="true">0</td>
                                                        <td>
                                                            <div class="badge badge-large badge-pill badge-danger">
                                                                ناموجود</div>
                                                        </td>
                                                        <td>ناموجود پویا</td>
                                                        <td data-seperator="true">6446</td>
                                                        <td data-seperator="true">5542</td>
                                                        <td>4.8</td>
                                                        <td data-value="1651918585" data-date-persianed="true">
                                                            1401-02-17 14:46:25</td>
                                                        <td data-value="1651918590" data-date-persianed="true">
                                                            1401-02-17 14:46:30</td>
                                                        <td>
                                                            <form action="" method="POST">
                                                                <input type="hidden" name="product_id" value="1336">
                                                                <a href="edit"
                                                                    class="btn btn-info waves-effect waves-light table-action-button"
                                                                    id="action_edit">ویرایش</a>
                                                                <input
                                                                    class="btn btn-danger waves-effect waves-light table-action-button"
                                                                    name="action_delete" id="action_delete"
                                                                    type="button" value="حذف">
                                                            </form>
                                                        </td>
                                                    </tr>

                                                    <tr>
                                                        <td data-seperator="true">17</td>
                                                        <td><img width="70"
                                                                src="https://dkstatics-public.digikala.com/digikala-products/6207b3bf015d7fff97e9e04868497ac6a30474a3_1630140408.jpg?x-oss-process=image/resize,m_lfit,h_300,w_300/quality,q_90">
                                                        </td>
                                                        <td>گوشی موبایل سامسونگ مدل Galaxy A12 Nacho SM-A127F/DS</td>
                                                        <td data-seperator="true">3689000</td>
                                                        <td data-seperator="true">200</td>
                                                        <td data-seperator="true">15</td>
                                                        <td>
                                                            <div class="badge badge-large badge-pill badge-success">
                                                                موجود</div>
                                                        </td>
                                                        <td>منتشر شده</td>
                                                        <td data-seperator="true">4</td>
                                                        <td data-seperator="true">5</td>
                                                        <td>4.5</td>
                                                        <td data-value="1651918685" data-date-persianed="true">
                                                            1401-02-17 14:48:05</td>
                                                        <td data-value="1651918690" data-date-persianed="true">
                                                            1401-02-17 14:48:10</td>
                                                        <td>
                                                            <form action="" method="POST">
                                                                <input type="hidden" name="product_id" value="17">
                                                                <a href="edit"
                                                                    class="btn btn-info waves-effect waves-light table-action-button"
                                                                    id="action_edit">ویرایش</a>
                                                                <input
                                                                    class="btn btn-danger waves-effect waves-light table-action-button"
                                                                    name="action_delete" id="action_delete"
                                                                    type="button" value="حذف">
                                                            </form>
                                                        </td>
                                                    </tr>

                                                    <tr>
                                                        <td data-seperator="true">18</td>
                                                        <td><img width="70"
                                                                src="https://dkstatics-public.digikala.com/digikala-products/ac6a9c2f04fc386e2d42b4ffdecef759259d0e83_1645449789.jpg?x-oss-process=image/resize,m_lfit,h_800,w_800/quality,q_90">
                                                        </td>
                                                        <td>گوشی موبایل شیائومی مدل Redmi Note 11 دو سیم‌ کارت ظرفیت 128
                                                            گیگابایت و رم 6 گیگابایت</td>
                                                        <td data-seperator="true">5399000</td>
                                                        <td data-seperator="true">131</td>
                                                        <td data-seperator="true">5</td>
                                                        <td>
                                                            <div class="badge badge-large badge-pill badge-success">
                                                                موجود</div>
                                                        </td>
                                                        <td>ناموجود دستی</td>
                                                        <td data-seperator="true">13</td>
                                                        <td data-seperator="true">19</td>
                                                        <td>4.7</td>
                                                        <td data-value="1651918785" data-date-persianed="true">
                                                            1401-02-17 14:49:45</td>
                                                        <td data-value="1651918790" data-date-persianed="true">
                                                            1401-02-17 14:49:50</td>
                                                        <td>
                                                            <form action="" method="POST">
                                                                <input type="hidden" name="product_id" value="18">
                                                                <a href="edit"
                                                                    class="btn btn-info waves-effect waves-light table-action-button"
                                                                    id="action_edit">ویرایش</a>
                                                                <input
                                                                    class="btn btn-danger waves-effect waves-light table-action-button"
                                                                    name="action_delete" id="action_delete"
                                                                    type="button" value="حذف">
                                                            </form>
                                                        </td>
                                                    </tr>


                                                </tbody>

                                            </table>

                                        </div>
                                    </div>

                                </div>

                            </div>

                        </div>

                    </div>
                    <!-- End row -->

                </div>
                <!-- End Page-content -->
                <!-- end main content-->
                <footer class="footer">
                    <div class="container-fluid">
                        <div class="row">
                            <div class="col-sm-6">
                                <div class="text-sm-right d-none d-sm-block">
                                    <script>
                                        document.write(new Date().getFullYear())
                                    </script> © RapidCode.iR
                                </div>
                            </div>
                            <div class="col-sm-6">
                                <div class="text-sm-right d-none d-sm-block">
                                    کتابخانه مجازی برنامه نویسان - رپید کد
                                </div>
                            </div>
                        </div>
                    </div>
                </footer>
            </div>

        </div>
        <!-- END layout-wrapper -->
    </div>
    <!-- end container-fluid -->

    <script id="jquery" src="assets/js/jquery.min.js"></script>
    <script id="bootstrap.bundle.min" src="assets/js/bootstrap.bundle.min.js"></script>
    <script id="app.init" src="assets/custom/app.init.js"></script>
    <script id="sweetalert2" src="assets/js/sweetalert2.min.js"></script>
    <script id="select2" src="assets/js/select2.min.js"></script>
    <script id="select2FaSrc" src="assets/js/i18n/fa.min.js"></script>
    <script id="datepicker.jalali.date" src="assets/js/persian-date.min.js"></script>
    <script id="datepicker.jalali" src="assets/js/persian-datepicker.min.js"></script>
    <script id="ion.rangeSlider" src="assets/js/ion.rangeSlider.min.js"></script>
    <script id="product.list.min" src="assets/custom/product.list.js"></script>

</body>

</html>


استایل main.css

/* ================> page=* */

.ds-none{
    display: none;
}

table {
    width: 100%;
}

.form-group {
    overflow: hidden;
    border: 1px solid #d8d8d8;
    padding: 5px
}

.drag-top {
    position: relative;
    top: -20px;
}

.select2-results__option[aria-selected],
.select2-container--default .select2-results__option[aria-selected=true] {
    background-color: #f1f1f1;
}

/* ================> page=product.list.php */

.table td, .table th{
    padding: 0.45rem;
}

#filter-wrapper{
    box-shadow: 0 0 5px #e5e5e5;
    border-radius: 4px;
    padding: 25px 21px 21px 21px;
    margin-bottom: 25px;
    position: relative;
    min-height: 100px;
}

#filter-wrapper .filter-checklist{
    display: block;
    text-align: left;
    width: 100%;
    position: relative;
    top: -13px;
    left: 0;
}

#filter-wrapper .filter-checklist .select2-wrapper{
    display: inline-block;
}

.input-wrapper{
    border: 1px solid #f0f0f0;
    display: none;
}

.input-wrapper.active{
    display: block;
}

.input-wrapper .navigator{
    width: 35%;
    margin: 15px 5px;
}

.input-wrapper .navigator#from , .input-wrapper #from-label{
    margin-top: 15px;
    float: right;
}

.input-wrapper .navigator#to , .input-wrapper #to-label{
    margin-top: 15px;
    float: left;
}

#query{
    display: inline-block;
    width: 25%;
}

.dataTables_length {
    display: none;
}

.table-action-button[name=action_edit] {
    margin-bottom: 15px;
}

#action_edit {
    margin-bottom: 15px;
}

.badge-large {
    font-size: 14px;
    padding-bottom: 7px;
}




اسکریپت app.init.js برای کنترل فرم و ساخت کوئری استرینگ

$(document).ready(function () {

    /* ================> Functions */

    window.getCurrentQuery = function () {
        const params = new URL(document.location.href).searchParams;
        return params;
    }

    window.onMultipleSelect2Change = function (e, extraParam = null) {
        const thisElement = $(e.target);

        if (extraParam == "queryCheck" && (thisElement.val() == null || thisElement.val() == "")) {
            const firstOption = thisElement.find("option").first();
            if (firstOption.length)
                thisElement.val(firstOption.val()).trigger("change");
        }

        const thisElementParent = thisElement.parent();
        const thisElementContentList = thisElementParent.find('.select2-content-list');
        if (thisElementContentList.length && thisElement.val() != "") {
            thisElementContentList.val(thisElement.val());
            thisElementContentList.trigger("input")
        }

    }

	window.seperateNumber = function (val, preverseZero = false) {

        const value = val.toString().replace(/,/gi, "").replace(/\D/gi, "");

        if (isNaN(Number(value))) return false;

        let seperatedValue = new Intl.NumberFormat('en-US', { style: "decimal" }).format(value);

        if (seperatedValue == 0 && !preverseZero) seperatedValue = '';

        return {
            seperatedValue: seperatedValue,
            value: value
        };
    }

    window.generateSelect2Feature = function (element, options = {}) {
        if (typeof select2 == "undefined") return false;
        const res = element.select2(options);
        return res;
    }

    window.elementSeperator = function (index, element) {
        const currentElement = $(element);

        let val = currentElement.text();
        let finalVal = seperateNumber(val, true);
        currentElement.text(finalVal['seperatedValue'])

        currentElement.attr('data-value', finalVal['value']);
    }

    window.onInputNumberSeperator = function (e) {
        const thisElement = $(e.target);

        const val = seperateNumber(thisElement.val());
        const seperatedValue = val['seperatedValue'] === false ? '' : val['seperatedValue'];

        thisElement.val(seperatedValue);
        thisElement.attr('data-value', val['value']);
        thisElement.trigger('seperatedvalue');
    }

    window.getDataOptionPlugin = function (element, options) {

        const dataOptions = element.attr('data-options') ? JSON.parse(element.attr('data-options')) : {};
        const mOptions = Object.assign({}, options);

        for (const key of Object.keys(dataOptions)) {
            const currentElement = dataOptions[key];
            mOptions[key] = currentElement;
        }

        return mOptions;
    }

    window.generateIonRangeSliderFeature = function (element, options = {}) {
        if (typeof $().ionRangeSlider === "undefined") return false;

        const mOptions = getDataOptionPlugin(element, options);

        const res = element.ionRangeSlider(mOptions);
        return res;
    }

    window.generatePersianDatepickerFeature = function (element, options = {}) {
        if (typeof persianDatepicker === "undefined") return false;

        const mOptions = getDataOptionPlugin(element, options);

        const res = element.persianDatepicker(mOptions);

        element.on('input', res, function (e) {
            const pd = e.data;
            const thisElement = $(e.target)
            const val = thisElement.val();
            if (val) {
                const timestamp = val * 1000;
                pd.setDate(timestamp)
            }
        });


        return res;
    }

    window.syncRangeSliderAndInput = function (data) {

        const thisElement = data.input;
        const thisElementParent = thisElement.parent();

        const fromDOM = thisElementParent.find(".navigator#from");
        const toDOM = thisElementParent.find(".navigator#to");

        if (fromDOM.length && toDOM.length) {


            if ((!fromDOM.attr('data-initial') && !toDOM.attr('data-initial'))) {

                function syncInitialValueToRanger(e) {
                    if (!e.thisElement.data('ionRangeSlider')) {
                        setTimeout(syncInitialValueToRanger, 100, e);
                        return false;
                    }

                    if (e.fromDOM.val() != "" && e.toDOM.val() != "") {
                        e.thisElement.data('ionRangeSlider').update({
                            from: fromDOM.val(),
                            to: toDOM.val()
                        });
                    } else {
                        e.fromDOM.val(e.from);
                        e.toDOM.val(e.to);
                    }


                    e.fromDOM.attr('data-initial', "true");
                    e.toDOM.attr('data-initial', "true");
                }

                setTimeout(syncInitialValueToRanger, 100, {
                    fromDOM: fromDOM,
                    toDOM: toDOM,
                    thisElement: thisElement,
                    from: data.from,
                    to: data.to,
                })


            } else {
                if (typeof data['from'] != "undefined") {
                    fromDOM.val(data.from)
                    fromDOM.trigger("input")
                }

                if (typeof data['to'] != "undefined") {
                    toDOM.val(data.to)
                    toDOM.trigger("input")
                }
            }


            function onInput(e) {
                const thisElement = $(this);
                const thisElementVal = thisElement.val();
                const ion = e.data.ion;

                if (!isNaN(Number(e.data.min)) && !isNaN(Number(e.data.max))) {

                    const options = sweetAlertOptions.info;
                    options.title = "حد مجاز";
                    options.text = "مقدار داده شده از حد مجاز رد شده است";
                    if (!(e.data.min <= thisElementVal)) {
                        Swal.fire(options);
                        thisElement.val(e.data.min);
                        return false;
                    } else if (!(thisElementVal <= e.data.max)) {
                        Swal.fire(options);
                        thisElement.val(e.data.max);
                        return false;
                    }
                }


                if (thisElement.attr('id') == "from")
                    ion.data('ionRangeSlider').update({ from: thisElementVal })
                else if (thisElement.attr('id') == "to") {
                    ion.data('ionRangeSlider').update({ to: thisElementVal })
                }

            }

            fromDOM.off("input", onInput).on("input", {
                ion: thisElement,
                from: data.from,
                to: data.to,
                min: data.min,
                max: data.max
            }, onInput);


            toDOM.off("input", onInput).on("input", {
                ion: thisElement,
                from: data.from,
                to: data.to,
                min: data.min,
                max: data.max
            }, onInput)

        }
    }

    // filter functions
    window.generateFilterInput = function (inputName) {
        const inputList = {
            "text": `<div class="input-wrapper col-4" data-name="x-wrapper"> <center> <div>x-title</div> </center> <input class="form-control mt-2 the-value" type="text" id="x-id"> </div>`,
            "numberSeperator": `<div class="input-wrapper col-4" data-name="x-wrapper"> <center> <div>x-title</div> </center> <input type="text" data-seperator="true" class="form-control mt-2 the-value" id="x-id"></div>`,
            "numberRange": `<div class="input-wrapper multi-value col-4" data-name="x-wrapper"> <center> <div>x-title</div> </center> <input type="text" id="x-id" data-options='x-options' class="ion-ranger"> <label id="from-label" for="from">از</label> <input class="form-control form-control-sm from the-value navigator" type="number" id="from" placeholder="از"> <input class="form-control form-control-sm to the-value navigator" type="number" id="to" placeholder="تا"> <label id="to-label" for="to">تا</label> </div>`,
            "selectMultiple": `<div class="input-wrapper multi-value col-4" data-name="x-wrapper"> <center class="mb-2"> <div>x-title</div> </center> <select class="form-control select2 select2-multiple" multiple data-options='x-options'>x-options-value</select> <input type="text" id="x-id" class="ds-none the-value select2-content-list" value=""> </div>`,
            "dateRange": `<div class="input-wrapper multi-value col-4" data-name="x-wrapper"> <center class="mb-2"> <div>x-title</div> </center> <div class="row"> <div class="col-6"> <label for="from-date">از</label> <input type="text" id="from-date" class="form-control from the-value x-id date-picker-shamsi" data-options='x-options'> </div> <div class="col-6"> <label for="to-date">تا</label> <input type="text" id="to-date" class="form-control to the-value x-id date-picker-shamsi" data-options='x-options'> </div> </div> </div>`,
            "switch": `<div class="custom-control custom-switch mb-2" dir="ltr"> <input type="checkbox" class="custom-control-input active-filter" data-id="x-id" id="for-x-id" x-checked> <label class="custom-control-label" for="for-x-id">x-title</label> </div>`,
            "option": `<option value="x-value" x-selected>x-title</option>`,
        }

        if (!inputList[inputName]) return false;

        return inputList[inputName];
    }

    window.filterInputOnInput = function (e) {
        const thisElement = $(e.target);
        const thisElementParent = thisElement.parents(filterOptions.inputWrapper);
        let key = thisElementParent.attr('data-name');
        let value = '';

        if (!thisElementParent.hasClass("active")) return false;

        if (thisElementParent.find("input.from,input.to").length) {
            let from, to;
            from = thisElementParent.find('input.from').val();
            to = thisElementParent.find('input.to').val();
            value = `${from},${to}`;
        }
        else {
            value = thisElementParent.find(filterOptions.valueInput).attr('data-value') ? thisElementParent.find(filterOptions.valueInput).attr('data-value') : thisElementParent.find(filterOptions.valueInput).val();
        }

        const map = `${key}=${value}`;

        return map;

    }

    window.checkQueryForFilters = function () {

        if (!$(filterOptions.wrapper).length) return false;

        let params = getCurrentQuery();
        params = Array.from(params.entries());

        const iteratedList = [];

        var select2SetValue = function (select2DOM, value) {
            if (select2DOM.hasClass(select2Options.generatedClass)) {
                select2DOM.val(value).trigger('change', "queryCheck");
            }

            else {
                var runUntilGenerateSelect2 = function (obj) {
                    if (!obj.element.hasClass(select2Options.generatedClass)) {
                        setTimeout(runUntilGenerateSelect2, 100, obj);
                        return false;
                    }

                    obj.element.val(obj.value).trigger('change', "queryCheck");

                }

                setTimeout(runUntilGenerateSelect2, 100, {
                    element: select2DOM,
                    value: value
                });
            }
        }

        for (const param of params) {
            const key = param[0];
            const value = param[1];

            if (iteratedList.includes(key)) continue;
            if (value == "" || value == ",") continue;



            const inputWrapper = $(`div[data-name=${key}`);
            const switchWrapper = $(filterOptions.switchWrapper);

            const select2DOM = inputWrapper.find('select.select2');

            if (!inputWrapper.length) continue;

            iteratedList.push(key);

            if (switchWrapper.length) {

                const activeSwitch = switchWrapper.find(`.active-filter[data-id="${key}"]`);

                if (activeSwitch.length) {
                    activeSwitch.prop("checked", true);
                    onSwitchFilter({
                        target: activeSwitch
                    });
                }

            }



            if (value.search(/,/gi) != -1) {
                const multiVal = value.split(",");
                const from = multiVal[0];
                const to = multiVal[1];
                const fromDOM = inputWrapper.find('input.from');
                const toDOM = inputWrapper.find('input.to');


                if (fromDOM.length && toDOM.length) {
                    fromDOM.val(from).trigger('input');
                    toDOM.val(to).trigger('input');
                } else if (select2DOM.length) {

                    select2SetValue(select2DOM, multiVal);

                    const select2ContentList = inputWrapper.find('.select2-content-list');
                    if (select2ContentList.length) {
                        select2ContentList.val(multiVal.join(","));
                    }
                }

            } else {
                inputWrapper.find(filterOptions.valueInput).val(value).trigger('input');

                if (select2DOM.length) {
                    select2SetValue(select2DOM, value);
                }
            }



        }

        if (iteratedList.length) {
            $(filterOptions.blockWrapper).removeClass('collapse').addClass('collapsed show')
        }

    }

    window.generateFilterForm = function (elements, filterWrapper, swtichWrapper, sortWrapper) {

        if (!filterWrapper.length) return false;

        const select2SortDOM = sortWrapper.find('select.select2');

        for (let element of elements) {
            element = $(element);
            const dataset = {
                type: null,
                options: null,
                values: null,
                name: null,
                title: null,
            }

            dataset['type'] = element.attr('data-input');
            dataset['options'] = element.attr('data-options') ? element.attr('data-options') : '';
            dataset['values'] = element.attr('data-values') ? JSON.parse(element.attr('data-values')) : [];
            dataset['name'] = element.attr('data-name');
            dataset['title'] = element.text();

            if (!dataset['type']) return false;

            const template = generateFilterInput(dataset['type']);
            if (!template) return false;


            // switch filter for appended element
            const templateSwitch = generateFilterInput('switch');
            let templateSwitchDynamic = templateSwitch.replace(/x-title/gi, dataset['title']).replace(/x-id/gi, dataset['name']);

            //templateSwitchDynamic = templateSwitchDynamic.replace(/x-checked/gi, 'checked')


            const tempateDynamic = template.replace(/x-wrapper/gi, dataset['name']).replace(/x-title/gi, dataset['title']).replace(/x-id/gi, dataset['name']).replace(/x-options-value/gi, dataset['values'].join("\n")).replace(/x-options/gi, dataset['options'])

            filterWrapper.append(tempateDynamic);
            swtichWrapper.append(templateSwitchDynamic);
        }

        const sortDOM = sortWrapper.find(filterOptions.valueInput);
        if (sortDOM.length) {
            if (sortDOM.val() == "") {
                sortDOM.val(select2SortDOM.val());
            }
        }

        const inputWrapper = filterWrapper.find(filterOptions.inputWrapper)
        const theValue = inputWrapper.find(filterOptions.valueInput);

        theValue.on('input seperatedvalue', function (e) {
            const queryList = [];
            for (let valDOM of theValue) {
                const res = filterInputOnInput({
                    target: valDOM
                });

                if (!res) continue;

                if (!queryList.includes(res))
                    queryList.push(res);
            }

            const query = "?" + queryList.join("&");

            const form = $(filterOptions.form);
            form.attr('action', form.attr('data-route') + query)

        });

    }

    window.onSwitchFilter = function (e) {
        const thisElement = $(e.target);
        const checkStatus = thisElement.prop('checked');

        const inputWrapper = $(filterOptions.inputWrapper + `[data-name=${thisElement.attr('data-id')}]`);
        const select2DOM = $(filterOptions.sortWrapper).find("select.select2");

        const dataset = {
            title: inputWrapper.find("center").text(),
            name: inputWrapper.attr("data-name")
        }

        const templateOption = generateFilterInput('option');

        if (checkStatus) {
            inputWrapper.addClass('active');
            const options = [];
            options.push(templateOption.replace(/x-title/gi, dataset['title'] + ": صعودی").replace(/x-value/gi, dataset['name'] + ":asc"));
            options.push(templateOption.replace(/x-title/gi, dataset['title'] + ": نزولی").replace(/x-value/gi, dataset['name'] + ":desc"));
            select2DOM.append(options.join("\n"));
            select2DOM.trigger("change");
        } else {
            inputWrapper.removeClass('active');
            const options = select2DOM.find(`option[value='${dataset['name'] + ":asc"}'],option[value='${dataset['name'] + ":desc"}']`)
            options.remove();
            select2DOM.trigger("clear");
        }

        const filterWrapper = inputWrapper.parents(filterOptions.wrapper);
        const firstInput = filterWrapper.find(filterOptions.valueInput).first();

        if (firstInput.length) {
            firstInput.trigger("input");
        }

    }

    /* ================> END Functions */


    /* ================> default Options */
    
    window.filterOptions = {
        wrapper: '#filter-wrapper',
        inputWrapper: '.input-wrapper',
        form: '#filter-form',
        switchWrapper: '.filter-checklist .dropright .dropdown-menu',
        sortWrapper: '.select2-wrapper',
        blockWrapper: '#block-wrapper-filter',
        clearFilter: '#clear-filter',
        valueInput: '.the-value'
    }

    window.sweetAlertOptions = {
        question: {
            title: "عنوان",
            text: "توضیح",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#34c38f",
            cancelButtonColor: "#f46a6a",
            confirmButtonText: "بله",
            cancelButtonText: 'انصراف'
        },
        info: {
            title: "عنوان",
            text: 'توضیح',
            type: 'warning',
            confirmButtonColor: '#3b5de7',
            confirmButtonText: 'باشه'
        }

    }

    window.shamsiDatePickerOptions = {
        format: 'X',
        timePicker: {
            enabled: true
        },
        initialValue: false,
        onSelect: function () {
            const thisElement = $(this.model.inputElement);

            if (this.format.toLowerCase() === "x" && !this.default_ts) {
                const timestamp = thisElement.val();
                const now = new persianDate(timestamp * 1000);
                const dateObj = now.startOf('day').ON;
                const date = dateObj.persian;
                let finalTimestamp = 0;
                let dateArray = [];

                if (thisElement.attr("id") == "from-date") {
                    dateArray = [date.year, date.month + 1, date.day, 0, 0, 0, 0];
                } else if (thisElement.attr("id") == "to-date") {
                    dateArray = [date.year, date.month + 1, date.day, 23, 59, 59, 0];
                }

                finalTimestamp = new persianDate(dateArray);
                finalTimestamp = finalTimestamp.unix();

                thisElement.val(finalTimestamp);
            }

            thisElement.trigger('input');

        }
    }

    window.ionRangeSliderOptions = {
        skin: "round",
        type: "double",
        grid: true,
        min: 0,
        max: 1000,
        from: 100,
        to: 990,
        step: 1,
        prettify_separator: ",",
        postfix: '',
        prefix: '',
        onStart: syncRangeSliderAndInput,
        onChange: function () { },
        onFinish: syncRangeSliderAndInput,
        onUpdate: function () { }
    }

    window.select2Options = {
        generatedClass : 'select2-hidden-accessible',
    }

    /* ================> END Options */


    /* ================> INIT */
    
    // generate element filter form
    generateFilterForm($('[data-filter]'), $(filterOptions.wrapper), $(filterOptions.switchWrapper), $(filterOptions.sortWrapper));


    /*

    window.filterOptions = {
        wrapper: '#filter-wrapper',
        inputWrapper: '.input-wrapper',
        form: '#filter-form',
        switchWrapper: '.filter-checklist .dropright .dropdown-menu',
        sortWrapper: '.select2-wrapper',
        blockWrapper: '#block-wrapper-filter',
        clearFilter: '#clear-filter',
        valueInput: '.the-value'
    }
    */


    // generate persian date picker
    $('input.date-picker-shamsi').each(function (index, element) {
        element = $(element);
        generatePersianDatepickerFeature(element, shamsiDatePickerOptions)
    });

    // generate number seperator input tag event
    $('input[data-seperator]').on("input", onInputNumberSeperator);

    // generate number seperator all element
    $('[data-seperator]').each(elementSeperator)

    // set old value filters
    checkQueryForFilters();


    /* ================> END INIT */
});


اسکریپت product.list.js برای آماده سازی کتابخانه ها و افزودن event listener

$(document).ready(function () {

    /* ================> Functions */

    

    function preventSwitchModalOff(e) {
        const thisElement = $(e.target);
        const thisElementParent = thisElement.parent('.dropright');

        if (thisElement.attr('aria-expanded') == "false") {
            setTimeout(function () {
                thisElementParent.removeClass('show');
            }, 10)
        } else {
            thisElementParent.addClass('show');
        }

    }

    function onClickClearFilter(e) {
        const Form = $(filterOptions.form);

        Form.attr("action", Form.attr("data-route"));
        Form.submit();
    }

    /* ================> END Functions */


    /* ================> EVENTS */

    $('.dropright button[data-toggle=dropdown]').on("click", preventSwitchModalOff)

    $(filterOptions.switchWrapper).find('.active-filter').on("change", onSwitchFilter)

    $(filterOptions.clearFilter).on("click", onClickClearFilter);

    /* ================> END EVENTS */

    /* ================> INIT */

    // generate range slider
    $(".ion-ranger").each(function (index, element) {
        element = $(element);
        generateIonRangeSliderFeature(element, ionRangeSliderOptions)
    });


    // enable Select2 All
    $('select.select2').each(function (index, element) {
        element = $(element);
        generateSelect2Feature(element, {}).on('change', onMultipleSelect2Change)
        element.trigger("change");
    });

    /* ================> END INIT */
});


دانلود سورس پروژه فیلتر محصولات

ارسال نظر

جهت استفاده از کد حتما از تگ pre استفاده نمایید .

لیست نظرات

  1. محمود رنجبر نورآبادی
    محمود رنجبر نورآبادی

    سلام استاد باقری گل روز بخیر دو تا سوال دارم یک من وقتی که کاربر لاگین هست عکس پروفایل رو در قسمت هدر سایت echo میکنم مشکلی که داره هنگام ارسال فرم ها در یک سری صفحات خطای Can not modify header information میده به خاطر دستور echo حالا چیکار کنم که هم این خطا نباشه و هم عکس echo بشه دو یک فرم داریم با ارسال عکس عکس رو آپلود میکنم مثلا عکس ۱ وقتی صفحه رو رفرش میکنم به طور خودکار فرم دوباره ارسال میشه در صورتی که دکمه submit رو نزدم و یه عکس خالی با همون نام جایگزین عکس قبلی میشه این در php طبیعیه یا کد مشکل داره ؟ با تشکر از راپید کد

    06 دی 1401 | 14:42:45
  • حسین باقری
    حسین باقری

    سوال 1 : این خطا زمانی به وجود میاد که شما خیلی جلوتر قبل از این که اطلاعات با تابع header در php تنظیم بشه echo کردید . باید echo بعد از header استفاده کنید تا رفع بشه سوال 2 : زمانی که آپلود انجام شد با استفاده از دستور

    header("Refresh: 1");
    صفحه رو رفرش می کنید تا داده های ارسال شده از حافظه موقت مرورگر خالی بشه
    06 دی 1401 | 15:09:56
  • محمود رنجبر نورآبادی
    محمود رنجبر نورآبادی

    استاد باقری عزیز از filter var url هم استفاده کردم کوکی کاربر هم از نوع secure و http only هست از xssهم جلوگیری شده ssl هم دارم خیالم راحت باشه اگه توسایتش کدهای مخرب باشه با کلیک رو اون سایت مشکلی پیش نمیاد ؟ با تشکر از راپید کد

    30 آذر 1401 | 14:16:51
    • حسین باقری
      حسین باقری

      دقیق نمی تونم تضمین کنم که 100% سایت مشکل امنیتی براش پیش نمیاد چون هیچ سورسی از وبسایت تون ندارم و اگر داشتم هم باید هفته ها وقت بذارم تا بررسی کنم که زمان ش رو ندارم . اما اگر نکات امنیتی که هر برنامه نویس باید بدونه رعایت کرده باشید مشکلی پیش نمیاد .

      30 آذر 1401 | 18:51:58
  • محمود رنجبر نورآبادی
    محمود رنجبر نورآبادی

    مهندس باقری من موارد ۲ و ۳ انجام دادم این اعتبار سنجی دامنه چطوری انجام بدم با تابع Checkdnsrr منظورتونه ؟ کدش چطوریه ؟

    29 آذر 1401 | 22:40:20
    • حسین باقری
      حسین باقری

      بخش اعتبار سنجی url در این آموزش

      30 آذر 1401 | 12:36:03
  • محمود رنجبر نورآبادی
    محمود رنجبر نورآبادی

    سلام خدمت استاد باقری عزیز استاد من میخوام در آگهی مربوط به کسب و کار ها اجازه بدم اگر کاربر وبسایت داره لینک وبسایتش رو قرار بده و مخاطبین وبسایت با کلیک بر روی اون به وبسایتش برن اینپوت مربوط به وبسایت رو هم فیلتر کنم با خود تابع php آیا این مشکل امنیتی برای وبسایت ایجاد میکنه؟ مثلا هکر وبسایتی قرار بده که کوکی ها رو سرقت کنه یا اطلاعات وبسایت رو بدست بیاره و سایت رو هک کنه ؟

    29 آذر 1401 | 21:23:55
    • حسین باقری
      حسین باقری

      درود ، در صورتی که در تگ a باشه و 1- دامنه اعتبار سنجی بشه که واقعا دامنه وارد شده 2- از تابع htmlentities جهت جلوگیری از حمله xss استفاده بشه 3- کوکی های مهم مثل سشن کاربر به صورت http only ذخیره شده باشه . خیر مشکلی پیش نمیاد .

      29 آذر 1401 | 21:29:48
  • محمود+رنجبر+نورآبادی
    محمود+رنجبر+نورآبادی

    مهندس باقری عزیز الان بحث رو اون تگ a هست که از صفحه ایندکس میره به صفحه car با id مثلا ۵ و title پژو 405 تا اینجا تو گوگل مینویسه پژو ۴۰۵ باید مدل های پژو هم به این تگ a اضافه بشه تا تو نتایج بیاد درسته ؟ یک تگ a برای پژو ۴۰۵ هم که بیشتر نیست چطوری مدل ها به این query string اضا فه بشه که در گوگل پژو ۴۰۵ مدل ۹۵ و سایر مدل ها تو نتایج بیاد و اینکه برای این همه برند و مدل خودرو تو سایت مپ فقط یک لینک باید قرار بدم یه نمونه کد قرار بدید بی زحمت استاد بزرگ البته ببخشید برای سوالات زیاد

    24 آذر 1401 | 21:13:42
    • حسین باقری
      حسین باقری

      یک روش دیگه ای که می تونید استفاده کنید و دردسر کم تری داره بعضی از فیلتر ها رو به صورت لینک با تگ a می تونید در بیارید که نیازی هم به sitemap نیست و گوگل به صورت خودکار اون رو ایندکس می کنه . یعنی برای مدل مثلا GLX میشه example.com/car/405/?model=glx .

      24 آذر 1401 | 22:55:42
  • محمود+رنجبر+نورآبادی
    محمود+رنجبر+نورآبادی

    سلام استاد باقری عزیز من در صفحه ایندکس سایت یک modal حاوی برند و مدل خودرو ها دارم و وقتی روی برند یا مدل خودرو کلیک میشه به صفحه ای میره که خودرو ها رو نشون میده و میشه فیلتر کرد سوالم در خصوص سئو هست وقتی مثلا پژو ۴۰۵ رو در گوگل سرچ میکنیم به صفحه موردنظر میره و خودرو ها رو نشون میده چون تو تگ لینک modal آی دی رو به همره نام خودرو قرار دادیم تو وبسایت دیوار وقتی در گوگل سرچ میکنیم پژو ۴۰۵ مدل ۹۵ میره به صفحه موردنظر و ۴۰۵ های مدل ۹۵ رو نشون میده و فیلتر مدل هم فعاله من چطوری تو لینک modal مدل رو هم اضافه کنم که در نتایج گوگل بیاد چون برای پژو ۴۰۵ ده ها مدل ثبت شده ممنون میشم راهنمایی بفرمایید

    24 آذر 1401 | 19:48:26
    • حسین باقری
      حسین باقری

      این سوالی که پرسیدین یکم طولانی هست بنابراین خلاصه ش می کنم ، ابتدا شما باید فیلتر ها تون رو به 2 دسته تقسیم 1- دسته هایی که قرار نیست تو گوگل ایندکس بشن 2- دسته هایی که قرار هست ایندکس بشن . بعد از اون باید یک سیستم sitemap داشته باشید و لینک فیلتر های قابل ایندکس ( مورد 2 ) رو بهش معرفی کنید که داخل خودش نشون بده اینطوری گوگل فیلتر های مورد نظر تون رو می شناسه و کاربر می تونه وارد بشه . البته باید فیلتر تون با Query String سازگاری خوبی داشته باشه و اطلاعاتش رو از url بگیره تا زمانی که کاربر به صورت مستقیم وارد شد ، واکنش از خودش نشون بده و مطابق با فیلتر ظاهرش رو تغییر بده .

      24 آذر 1401 | 20:09:27
  • محمود+رنجبر+نورآبادی
    محمود+رنجبر+نورآبادی

    سلام دوباره مهندس باقری عزیز من همونطور که گفتید مقدار value رو برای قیمت و کارکرد و ... از url قرار دادم و مشکل حل شد برای حذف کلی هم که شما فرمودید چیکار کنم اما برای حذف یکی یکی مثل سایت دیوار کنار هر فیلتر به فارسی یه دکمه X قرار دادم و با کلیک روی اون تابعی اجرا میشه و با استفاده از replace کردن اون پارامتر با هیچی کار تمام میشه سپاس از استاد عزیز فقط یه سوال امنیتی دارم حسین جان من در فرم های وبسایت مقدار name تگهای input رو همان مقدار فیلد دیتابیس قرار دادم این برای امنیت وبسایت مشکلی ایجاد میکنه ؟ البته ورودی ها رو فیلتر میکنم به نظر شما باید تغییر شون بدم و یکسان نباشن ؟

    19 آذر 1401 | 16:18:44
    • حسین باقری
      حسین باقری

      من در فرم های وبسایت مقدار name تگهای input رو همان مقدار فیلد دیتابیس قرار دادم این برای امنیت وبسایت مشکلی ایجاد میکنه ؟ درود ، خیر مشکلی ایجاد نمی کنه و در ضمن خوانایی بهتری براتون ایفا می کنه

      19 آذر 1401 | 17:51:28
  • محمود+رنجبر+نورآبادی
    محمود+رنجبر+نورآبادی

    سلام مهندس باقری عزیز خداقوت من برای فیلتر آگهی های خودرو یک فرم ایجاد کردم با متد get و بر اساس قیمت و کارکرد و ... با گرفتن اطلاعات از url فیلتر انجام میشه فقط یه مشکل کوچک دارم وقتی من بر اساس قیمت فیلتر میکنم و آگهی ها نشون داده میشه دوباره میخوام بر اساس کارکرد فیلتر کنم با ارسال فرم فیلتر قیمت از بین میره میخوام مثل سایت دیوار باشه هر وقت که فیلتری اضافه میکنم فیلتر قبلی باشه و با زدن دکمه حذف فیلتر از بین بره میشه راهنمایی کنید چیکار کنم

    18 آذر 1401 | 20:26:58
    • حسین باقری
      حسین باقری

      درود ، با یک مثال میگم ، مثلا شما 2 تا فیلتر دارید ، 1- قیمت _ price و 2- نوع ( نو / کارکرده ) _ type ، حالا شما میای و بار اول فقط فیلتر قیمت بین 2 تا 4 رو در نظر میگیری و فیلتر شماره 2 رو میذاری پیشفرض ( نو / کارکرده ) میذاری باشه . پس شکل url فیلتر میشه http://example.com/?price=2,4 و خبری از type در url نیست چون انتخاب نشده پیشفرض باقی می مونه حالا زمانی که فیلتر شد اطلاعات قیمت باید به صورت خودکار داخل فرم فیلتر قیمت بیاد که مشخصه از سوپر گلوبال GET استفاده می کنیم حالا اگر فیلتر 2 رو فقط کارکرده در نظر بگیرم آدرس url میشه http://example.com/?price=2,4&type=کارکرده . حالا اگر بخوایم فیلتر رو کامل پاک کنیم کافیه که با استفاده از جاوا اسکریپت با ادغام 2 پراپرتی origin و pathname کوئری استرینگ ها رو پاک کنیم که باعث پاک شدن فیلتر میشه .

      location.origin + location.pathname
      18 آذر 1401 | 23:45:02
    contact us