# Slider Range Filter Control

This control is used to filter content according to the selected range values. The content to filter is defined with CSS selectors. Background colors, width, height and other styles can be easily customized with CSS too.

See the Pen jPList Slider Range Filter Control by 1rosehip (@1rosehip) on CodePen.

## HTML & CSS

Range slider control is defined by required `data-jplist-control="slider-range-filter"` data attribute. The `data-group` attribute defines group of elements that should be sorted. The full list of data attributes can be found here.

    <!-- jplist styles -->
    <link href="jplist.styles.css" rel="stylesheet" type="text/css" />

    <div
        data-jplist-control="slider-range-filter"
        data-path=".like"
        data-group="group1"
        data-name="my-like-range-filter-1"
        data-min="-100"
        data-from="50"
        data-to="100"
        data-max="800">

         <span data-type="min"></span> Min |
         <span data-type="value-1"></span> Likes |
         <div class="jplist-slider" data-type="slider"></div>
         <span data-type="value-2"></span> Likes |
         <span data-type="max"></span> Max

    </div>

    <!-- content to sort -->
    <div data-jplist-group="group1">

        <!-- item -->
        <div data-jplist-item>
            <div class="like">100</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">12</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">151</div>
            ....
        </div>

    </div>

    <!-- jplist library -->
    <script src="jplist.min.js"></script>
    <script>
        jplist.init();
    </script>

## Slider CSS

Slider styles are fully customizable, all background and foreground colors can be changed via CSS. The basic slider styles can be as following:

    /* the slider control container */
    [data-jplist-control="slider-range-filter"]{
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        font-size: 12px;
        -webkit-box-align: center;
        -ms-flex-align: center;
        align-items: center;
        width: 100%;
    }

    /* the slider control */
    .jplist-slider {
        width: calc(100% - 200px);
        height: 20px;
        background-color: #fff;
        margin-right: 15px;
        margin-left: 15px;
        border-radius: .25rem;
        position: relative;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
    }

    .jplist-slider::before {
        content: '';
        display: block;
        width: 100%;
        height: 3px;
        background: #fff;
        position: absolute;
        z-index: 100;
        left: 0;
        top: 50%;
        -webkit-transform: translate(0, -50%);
        -ms-transform: translate(0, -50%);
        transform: translate(0, -50%);
        opacity: 0;
    }

    /* the slider holders */
    .jplist-slider-holder-1,
    .jplist-slider-holder-2 {
        width: 20px;
        height: 100%;
        border-radius: .25rem;
        display: block;
        cursor: pointer;
        position: absolute;
        top: 0;
        left: 0;
        -webkit-transform: translate(-50%, 0);
        -ms-transform: translate(-50%, 0);
        transform: translate(-50%, 0);
        z-index: 200;
        -webkit-transition: 0.3s background-color;
        -o-transition: 0.3s background-color;
        transition: 0.3s background-color;
        padding: 0;
        margin: 0;
        font-size: 0;
        line-height: 0;
    }

    /* first holder custom styles */
    .jplist-slider-holder-1 {
        background: #000;
    }

    /* second holder custom styles */
    .jplist-slider-holder-2 {
        background: #106CD6;
    }

    .jplist-slider-holder-1:active,
    .jplist-slider-holder-2:active{
        background: #00448c;
        box-shadow: 0px 0px 10px #fff;
    }

    /* the space between holders */
    .jplist-slider-range {
        width: 0;
        height: 20px;
        background: #ccc;
        display: block;
        position: absolute;
        left: 0;
        top: 0;
        background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
        background-size: 1rem 1rem;
    }

    /* slider labels */
    .range-slider-value{
        width: 100px;
        box-sizing: border-box;
        padding: 0 5px;
    }

### Top and bottom panels

Slider control can be placed in both top and bottom panels for the better user experience. In this case `data-name` attribute with the same value should be added. All other data attributes should also have the same values. Inner elements could be different though.

    <!-- slider control in the top panel -->
    <div
        data-jplist-control="slider-range-filter"
        data-path=".like"
        data-group="group1"
        data-name="my-like-range-filter-1"
        data-min="-100"
        data-from="50"
        data-to="100"
        data-max="800">

         Min: <span data-type="min"></span>
         From Likes: <span data-type="value-1"></span>
         <div class="jplist-slider" data-type="slider"></div>
         To Likes: <span data-type="value-2"></span>
         Max: <span data-type="max"></span>

    </div>

    <!-- content to sort -->
    <div data-jplist-group="group1">

        <!-- item -->
        <div data-jplist-item>
            <div class="like">15</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">100</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">350</div>
            ....
        </div>

    </div>

    <!-- slider control in the bottom panel -->
    <div
        data-jplist-control="slider-range-filter"
        data-path=".like"
        data-group="group1"
        data-name="my-like-range-filter-1"
        data-min="-100"
        data-from="50"
        data-to="100"
        data-max="800">

         From: <span data-type="value-1"></span>
         <div class="jplist-slider" data-type="slider"></div>
         To: <span data-type="value-2"></span>

    </div>

## Show / Hide Slider

Slider control is not rendered properly if it's hidden on page load. To handle this issue jplist.resetControl API may be used:

    <!-- toogle button -->
    <button id="toggle-slider-btn">Toggle Slider</button>

    <!-- slider container, hidden on page load -->
    <div class="buttons hidden" id="slider-box">
     <div
    	id="range-slider-1"
    	data-jplist-control="slider-range-filter"
    	data-path=".like"
    	data-group="group1"
    	data-name="name1"
    	data-min="-100"
    	data-from="50"
    	data-to="100"
    	data-max="800"></div>
    </div>

    <!-- items group -->
    <div data-jplist-group="group1">

    	<div data-jplist-item>
    	   ...
    	</div>

    	<div data-jplist-item>
    	   ...
    	</div>

    	<div data-jplist-item>
    	   ...
    	</div>
    </div>

    <script src="//cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>
    <script src="jplist.min.js"></script>
    <script>
     jplist.init();

     const btn = document.getElementById('toggle-slider-btn');
     const box = document.getElementById('slider-box');
     let sliderUpdated = false;

     // call jplist.resetControl API on button click only once
     btn.addEventListener('click', () => {

    	 box.classList.toggle('hidden');

    	 if(!sliderUpdated) {
    		 sliderUpdated = true;

    		 const slider = document.getElementById('range-slider-1');
    		 jplist.resetControl(slider);
    	 }
     }, false);
    </script>

## Deep Linking

Deep links can be used to keep user selections and control states after the page refresh. To implement them `data-id` attribute should be added to HTML structure and deepLinking setting should be true in jPList parameters.

In the example below deep link may look like http://www.example.com/page#group=group1&range1=10_50 where group1 is taken from `data-jplist-group="group1"`, `range1` is data-id value, `10` is current from value and `50` is current to value.

    <!-- jplist styles -->
    <link href="jplist.styles.css" rel="stylesheet" type="text/css" />

    <div
        data-jplist-control="slider-range-filter"
        data-path=".like"
        data-group="group1"
        data-name="my-like-range-filter-1"
        data-id="range1"
        data-min="-100"
        data-from="50"
        data-to="100"
        data-max="800">

         <span data-type="min"></span> Min |
         <span data-type="value-1"></span> Likes |
         <div class="jplist-slider" data-type="slider"></div>
         <span data-type="value-2"></span> Likes |
         <span data-type="max"></span> Max

    </div>

    <!-- content to sort -->
    <div data-jplist-group="group1">

        <!-- item -->
        <div data-jplist-item>
            <div class="like">100</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">12</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">151</div>
            ....
        </div>

    </div>

    <!-- jplist library -->
    <script src="jplist.min.js"></script>
    <script>
        jplist.init({
            deepLinking: true
        });
    </script>

## Storage

Local storage, session storage or cookies can be used to keep user selections and control states after the page refresh. To implement them `data-id` attribute should be added to HTML structure and storage setting should be passed to jPList constructor.

    <!-- jplist styles -->
    <link href="jplist.styles.css" rel="stylesheet" type="text/css" />

    <div
        data-jplist-control="slider-range-filter"
        data-path=".like"
        data-group="group1"
        data-name="my-like-range-filter-1"
        data-id="range1"
        data-min="-100"
        data-from="50"
        data-to="100"
        data-max="800">

         Min: <span data-type="min"></span>
         From: <span data-type="value-1"></span>
         <div class="jplist-slider" data-type="slider"></div>
         To: <span data-type="value-2"></span>
         Max: <span data-type="max"></span>

    </div>

    <!-- content to sort -->
    <div data-jplist-group="group1">

        <!-- item -->
        <div data-jplist-item>
            <div class="like">100</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">12</div>
            ....
        </div>

        <!-- item -->
        <div data-jplist-item>
            <div class="like">151</div>
            ....
        </div>

    </div>

    <!-- jplist library -->
    <script src="jplist.min.js"></script>
    <script>
        jplist.init({
            storage: 'localStorage', //'localStorage', 'sessionStorage' or 'cookies'
            storageName: 'jplist'
        });
    </script>

## Data Attributes

The full list of control data attributes.

Name | Description | Values
--- | --- | ---
`data-jplist-control` | Defines range slider filter control. | "slider-range-filter"
`data-group` | Defines group of items that should be filtered. For example, if a control has data-group="group1" then items group should have data-jplist-group="group1" data attribute. | any text value
`data-name` | The data-name attribute is used to identify the same controls in different panels. Different controls should have different data-name attributes. By default, data-name attribute has default value. | any text value
`data-path` | CSS selector that defines the HTML element that should be filtered | "default" keyword for the initial value or any CSS selector
`data-from` | Initial range values [data-from, data-to] | numeric value
`data-to` | Initial range values [data-from, data-to] | numeric value
`data-min` | The minimal possible value | numeric value
`data-max` | The maximal possible value | numeric value
`data-jump` | This data attribute can be used to scroll page to the specified location when user changes control values. data-jump="top" scrolls page to the top. Any CSS selector can be used instead of top keyword. | top keyword or any CSS selector
`data-id` | This attribute is used for deep linking. | any text value that may contain letters, digits, underscores or dashes
`data-or` | Defines a group of controls that should be filtered though the "OR" logic | any text value, for example data-or="bags"

### Inner elements

Data attributes of inner elements.

Name | Description | Values
--- | --- | ---
`data-type="min"` | Defines a label that contains minimal possible value text. | "min"
`data-type="max"` | Defines a label that contains maximal possible value text. | "max"
`data-type="value-1"` | Defines a label that contains first current value text. | "value-1"
`data-type="value-2"` | Defines a label that contains second current value text. | "value-2"
`data-type="slider"` | Defines a slider container element. | "slider"