ساخت فیلتر محصولات با جاوا اسکرپیت و کوئری 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 */ });
ارسال نظر