├── .editorconfig ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── question.md ├── .gitignore ├── .npmignore ├── CONTRIBUTING.md ├── License.md ├── _tmp ├── ion-range-slider.png └── logo-ion-range-slider.png ├── bower.json ├── css ├── ion.rangeSlider.css └── ion.rangeSlider.min.css ├── history.md ├── js ├── ion.rangeSlider.js └── ion.rangeSlider.min.js ├── less ├── _base.less ├── _mixins.less ├── irs.less └── skins │ ├── big.less │ ├── flat.less │ ├── modern.less │ ├── round.less │ ├── sharp.less │ └── square.less ├── package.json └── readme.md /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{js,css,less,html}] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: IonDen 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Did you try to ask your question in Discussions? 4 | title: '' 5 | labels: Help wanted 6 | assignees: IonDen 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .github 3 | _tmp 4 | PSD 5 | bower.json 6 | .npmignore 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Ion.RangeSlider project 2 | 3 | ### Code style 4 | 5 | 1. Project is using 4 space indentation 6 | 2. Function and method names should be written in camelCase 7 | 3. Variables name should be written in lower_case 8 | 4. New methods should have JSDoc descriptions 9 | 10 | ### Guide for Pull Requests with bug fixes 11 | 12 | 1. Only 1 bugfix per Pull Request 13 | 2. Should have bug description 14 | 3. Should have bug screenshots (if possible) 15 | 4. Should have working demo. Use JSFIDDLE: https://jsfiddle.net/IonDen/b79q0vnm/ 16 | 17 | ### Guide for Pull Requests with new features 18 | 19 | 1. Only 1 feature per Pull Request 20 | 2. Should have statement, why feature is important and should be included into plugin 21 | 3. Should have feature description 22 | 4. Should have feature screenshots (if possible) 23 | 5. Should have working demo. Use JSFIDDLE: https://jsfiddle.net/IonDen/b79q0vnm/ 24 | 25 | ### Guide for Pull Requests with grammar fixes 26 | 27 | 1. Just create a pull request :) 28 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | ## The MIT License 2 | 3 | Copyright © 2021 by Denis Ineshin (http://ionden.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /_tmp/ion-range-slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonDen/ion.rangeSlider/b4c444389304652bfc7bf2fe3aa86ed84453cb35/_tmp/ion-range-slider.png -------------------------------------------------------------------------------- /_tmp/logo-ion-range-slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IonDen/ion.rangeSlider/b4c444389304652bfc7bf2fe3aa86ed84453cb35/_tmp/logo-ion-range-slider.png -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ion-rangeslider", 3 | "version": "2.3.1", 4 | "homepage": "https://github.com/IonDen/ion.rangeSlider", 5 | "authors": [ 6 | { 7 | "name": "IonDen", 8 | "email": "denis.ineshin@gmail.com", 9 | "homepage": "http://ionden.com" 10 | } 11 | ], 12 | "description": "Powerful range slider with skin support", 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/IonDen/ion.rangeSlider.git" 16 | }, 17 | "main": [ 18 | "js/ion.rangeSlider.js", 19 | "css/ion.rangeSlider.css", 20 | "css/ion.rangeSlider.skinFlat.css", 21 | "img/sprite-skin-flat.png" 22 | ], 23 | "dependencies": { 24 | "jquery": ">=1.8" 25 | }, 26 | "moduleType": [ 27 | "globals" 28 | ], 29 | "keywords": [ 30 | "jquery-plugin", 31 | "diapason", 32 | "ion", 33 | "range", 34 | "slider" 35 | ], 36 | "license": "MIT", 37 | "ignore": [ 38 | "PSD", 39 | "ion-rangeSlider.jquery.json" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /css/ion.rangeSlider.css: -------------------------------------------------------------------------------- 1 | /** 2 | Ion.RangeSlider, 2.3.1 3 | © Denis Ineshin, 2010 - 2019, IonDen.com 4 | Build date: 2019-12-19 16:51:02 5 | */ 6 | .irs { 7 | position: relative; 8 | display: block; 9 | -webkit-touch-callout: none; 10 | -webkit-user-select: none; 11 | -khtml-user-select: none; 12 | -moz-user-select: none; 13 | -ms-user-select: none; 14 | user-select: none; 15 | font-size: 12px; 16 | font-family: Arial, sans-serif; 17 | } 18 | .irs-line { 19 | position: relative; 20 | display: block; 21 | overflow: hidden; 22 | outline: none !important; 23 | } 24 | .irs-bar { 25 | position: absolute; 26 | display: block; 27 | left: 0; 28 | width: 0; 29 | } 30 | .irs-shadow { 31 | position: absolute; 32 | display: none; 33 | left: 0; 34 | width: 0; 35 | } 36 | .irs-handle { 37 | position: absolute; 38 | display: block; 39 | box-sizing: border-box; 40 | cursor: default; 41 | z-index: 1; 42 | } 43 | .irs-handle.type_last { 44 | z-index: 2; 45 | } 46 | .irs-min, 47 | .irs-max { 48 | position: absolute; 49 | display: block; 50 | cursor: default; 51 | } 52 | .irs-min { 53 | left: 0; 54 | } 55 | .irs-max { 56 | right: 0; 57 | } 58 | .irs-from, 59 | .irs-to, 60 | .irs-single { 61 | position: absolute; 62 | display: block; 63 | top: 0; 64 | left: 0; 65 | cursor: default; 66 | white-space: nowrap; 67 | } 68 | .irs-grid { 69 | position: absolute; 70 | display: none; 71 | bottom: 0; 72 | left: 0; 73 | width: 100%; 74 | height: 20px; 75 | } 76 | .irs-with-grid .irs-grid { 77 | display: block; 78 | } 79 | .irs-grid-pol { 80 | position: absolute; 81 | top: 0; 82 | left: 0; 83 | width: 1px; 84 | height: 8px; 85 | background: #000; 86 | } 87 | .irs-grid-pol.small { 88 | height: 4px; 89 | } 90 | .irs-grid-text { 91 | position: absolute; 92 | bottom: 0; 93 | left: 0; 94 | white-space: nowrap; 95 | text-align: center; 96 | font-size: 9px; 97 | line-height: 9px; 98 | padding: 0 3px; 99 | color: #000; 100 | } 101 | .irs-disable-mask { 102 | position: absolute; 103 | display: block; 104 | top: 0; 105 | left: -1%; 106 | width: 102%; 107 | height: 100%; 108 | cursor: default; 109 | background: rgba(0, 0, 0, 0); 110 | z-index: 2; 111 | } 112 | .lt-ie9 .irs-disable-mask { 113 | background: #000; 114 | filter: alpha(opacity=0); 115 | cursor: not-allowed; 116 | } 117 | .irs-disabled { 118 | opacity: 0.4; 119 | } 120 | .irs-hidden-input { 121 | position: absolute !important; 122 | display: block !important; 123 | top: 0 !important; 124 | left: 0 !important; 125 | width: 0 !important; 126 | height: 0 !important; 127 | font-size: 0 !important; 128 | line-height: 0 !important; 129 | padding: 0 !important; 130 | margin: 0 !important; 131 | overflow: hidden; 132 | outline: none !important; 133 | z-index: -9999 !important; 134 | background: none !important; 135 | border-style: solid !important; 136 | border-color: transparent !important; 137 | } 138 | .irs--flat { 139 | height: 40px; 140 | } 141 | .irs--flat.irs-with-grid { 142 | height: 60px; 143 | } 144 | .irs--flat .irs-line { 145 | top: 25px; 146 | height: 12px; 147 | background-color: #e1e4e9; 148 | border-radius: 4px; 149 | } 150 | .irs--flat .irs-bar { 151 | top: 25px; 152 | height: 12px; 153 | background-color: #ed5565; 154 | } 155 | .irs--flat .irs-bar--single { 156 | border-radius: 4px 0 0 4px; 157 | } 158 | .irs--flat .irs-shadow { 159 | height: 1px; 160 | bottom: 16px; 161 | background-color: #e1e4e9; 162 | } 163 | .irs--flat .irs-handle { 164 | top: 22px; 165 | width: 16px; 166 | height: 18px; 167 | background-color: transparent; 168 | } 169 | .irs--flat .irs-handle > i:first-child { 170 | position: absolute; 171 | display: block; 172 | top: 0; 173 | left: 50%; 174 | width: 2px; 175 | height: 100%; 176 | margin-left: -1px; 177 | background-color: #da4453; 178 | } 179 | .irs--flat .irs-handle.state_hover > i:first-child, 180 | .irs--flat .irs-handle:hover > i:first-child { 181 | background-color: #a43540; 182 | } 183 | .irs--flat .irs-min, 184 | .irs--flat .irs-max { 185 | top: 0; 186 | padding: 1px 3px; 187 | color: #999; 188 | font-size: 10px; 189 | line-height: 1.333; 190 | text-shadow: none; 191 | background-color: #e1e4e9; 192 | border-radius: 4px; 193 | } 194 | .irs--flat .irs-from, 195 | .irs--flat .irs-to, 196 | .irs--flat .irs-single { 197 | color: white; 198 | font-size: 10px; 199 | line-height: 1.333; 200 | text-shadow: none; 201 | padding: 1px 5px; 202 | background-color: #ed5565; 203 | border-radius: 4px; 204 | } 205 | .irs--flat .irs-from:before, 206 | .irs--flat .irs-to:before, 207 | .irs--flat .irs-single:before { 208 | position: absolute; 209 | display: block; 210 | content: ""; 211 | bottom: -6px; 212 | left: 50%; 213 | width: 0; 214 | height: 0; 215 | margin-left: -3px; 216 | overflow: hidden; 217 | border: 3px solid transparent; 218 | border-top-color: #ed5565; 219 | } 220 | .irs--flat .irs-grid-pol { 221 | background-color: #e1e4e9; 222 | } 223 | .irs--flat .irs-grid-text { 224 | color: #999; 225 | } 226 | .irs--big { 227 | height: 55px; 228 | } 229 | .irs--big.irs-with-grid { 230 | height: 70px; 231 | } 232 | .irs--big .irs-line { 233 | top: 33px; 234 | height: 12px; 235 | background-color: white; 236 | background: linear-gradient(to bottom, #ddd -50%, white 150%); 237 | border: 1px solid #ccc; 238 | border-radius: 12px; 239 | } 240 | .irs--big .irs-bar { 241 | top: 33px; 242 | height: 12px; 243 | background-color: #92bce0; 244 | border: 1px solid #428bca; 245 | background: linear-gradient(to bottom, #ffffff 0%, #428bca 30%, #b9d4ec 100%); 246 | box-shadow: inset 0 0 1px 1px rgba(255, 255, 255, 0.5); 247 | } 248 | .irs--big .irs-bar--single { 249 | border-radius: 12px 0 0 12px; 250 | } 251 | .irs--big .irs-shadow { 252 | height: 1px; 253 | bottom: 16px; 254 | background-color: rgba(66, 139, 202, 0.5); 255 | } 256 | .irs--big .irs-handle { 257 | top: 25px; 258 | width: 30px; 259 | height: 30px; 260 | border: 1px solid rgba(0, 0, 0, 0.3); 261 | background-color: #cbcfd5; 262 | background: linear-gradient(to bottom, white 0%, #B4B9BE 30%, white 100%); 263 | box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2), inset 0 0 3px 1px white; 264 | border-radius: 30px; 265 | } 266 | .irs--big .irs-handle.state_hover, 267 | .irs--big .irs-handle:hover { 268 | border-color: rgba(0, 0, 0, 0.45); 269 | background-color: #939ba7; 270 | background: linear-gradient(to bottom, white 0%, #919BA5 30%, white 100%); 271 | } 272 | .irs--big .irs-min, 273 | .irs--big .irs-max { 274 | top: 0; 275 | padding: 1px 5px; 276 | color: white; 277 | text-shadow: none; 278 | background-color: #9f9f9f; 279 | border-radius: 3px; 280 | } 281 | .irs--big .irs-from, 282 | .irs--big .irs-to, 283 | .irs--big .irs-single { 284 | color: white; 285 | text-shadow: none; 286 | padding: 1px 5px; 287 | background-color: #428bca; 288 | background: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); 289 | border-radius: 3px; 290 | } 291 | .irs--big .irs-grid-pol { 292 | background-color: #428bca; 293 | } 294 | .irs--big .irs-grid-text { 295 | color: #428bca; 296 | } 297 | .irs--modern { 298 | height: 55px; 299 | } 300 | .irs--modern.irs-with-grid { 301 | height: 55px; 302 | } 303 | .irs--modern .irs-line { 304 | top: 25px; 305 | height: 5px; 306 | background-color: #d1d6e0; 307 | background: linear-gradient(to bottom, #e0e4ea 0%, #d1d6e0 100%); 308 | border: 1px solid #a3adc1; 309 | border-bottom-width: 0; 310 | border-radius: 5px; 311 | } 312 | .irs--modern .irs-bar { 313 | top: 25px; 314 | height: 5px; 315 | background: #20b426; 316 | background: linear-gradient(to bottom, #20b426 0%, #18891d 100%); 317 | } 318 | .irs--modern .irs-bar--single { 319 | border-radius: 5px 0 0 5px; 320 | } 321 | .irs--modern .irs-shadow { 322 | height: 1px; 323 | bottom: 21px; 324 | background-color: rgba(209, 214, 224, 0.5); 325 | } 326 | .irs--modern .irs-handle { 327 | top: 37px; 328 | width: 12px; 329 | height: 13px; 330 | border: 1px solid #a3adc1; 331 | border-top-width: 0; 332 | box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); 333 | border-radius: 0 0 3px 3px; 334 | } 335 | .irs--modern .irs-handle > i:nth-child(1) { 336 | position: absolute; 337 | display: block; 338 | top: -4px; 339 | left: 1px; 340 | width: 6px; 341 | height: 6px; 342 | border: 1px solid #a3adc1; 343 | background: white; 344 | transform: rotate(45deg); 345 | } 346 | .irs--modern .irs-handle > i:nth-child(2) { 347 | position: absolute; 348 | display: block; 349 | box-sizing: border-box; 350 | top: 0; 351 | left: 0; 352 | width: 10px; 353 | height: 12px; 354 | background: #e9e6e6; 355 | background: linear-gradient(to bottom, white 0%, #e9e6e6 100%); 356 | border-radius: 0 0 3px 3px; 357 | } 358 | .irs--modern .irs-handle > i:nth-child(3) { 359 | position: absolute; 360 | display: block; 361 | box-sizing: border-box; 362 | top: 3px; 363 | left: 3px; 364 | width: 4px; 365 | height: 5px; 366 | border-left: 1px solid #a3adc1; 367 | border-right: 1px solid #a3adc1; 368 | } 369 | .irs--modern .irs-handle.state_hover, 370 | .irs--modern .irs-handle:hover { 371 | border-color: #7685a2; 372 | background: #c3c7cd; 373 | background: linear-gradient(to bottom, #ffffff 0%, #919ba5 30%, #ffffff 100%); 374 | } 375 | .irs--modern .irs-handle.state_hover > i:nth-child(1), 376 | .irs--modern .irs-handle:hover > i:nth-child(1) { 377 | border-color: #7685a2; 378 | } 379 | .irs--modern .irs-handle.state_hover > i:nth-child(3), 380 | .irs--modern .irs-handle:hover > i:nth-child(3) { 381 | border-color: #48536a; 382 | } 383 | .irs--modern .irs-min, 384 | .irs--modern .irs-max { 385 | top: 0; 386 | font-size: 10px; 387 | line-height: 1.333; 388 | text-shadow: none; 389 | padding: 1px 5px; 390 | color: white; 391 | background-color: #d1d6e0; 392 | border-radius: 5px; 393 | } 394 | .irs--modern .irs-from, 395 | .irs--modern .irs-to, 396 | .irs--modern .irs-single { 397 | font-size: 10px; 398 | line-height: 1.333; 399 | text-shadow: none; 400 | padding: 1px 5px; 401 | background-color: #20b426; 402 | color: white; 403 | border-radius: 5px; 404 | } 405 | .irs--modern .irs-from:before, 406 | .irs--modern .irs-to:before, 407 | .irs--modern .irs-single:before { 408 | position: absolute; 409 | display: block; 410 | content: ""; 411 | bottom: -6px; 412 | left: 50%; 413 | width: 0; 414 | height: 0; 415 | margin-left: -3px; 416 | overflow: hidden; 417 | border: 3px solid transparent; 418 | border-top-color: #20b426; 419 | } 420 | .irs--modern .irs-grid { 421 | height: 25px; 422 | } 423 | .irs--modern .irs-grid-pol { 424 | background-color: #dedede; 425 | } 426 | .irs--modern .irs-grid-text { 427 | color: silver; 428 | font-size: 13px; 429 | } 430 | .irs--sharp { 431 | height: 50px; 432 | font-size: 12px; 433 | line-height: 1; 434 | } 435 | .irs--sharp.irs-with-grid { 436 | height: 57px; 437 | } 438 | .irs--sharp .irs-line { 439 | top: 30px; 440 | height: 2px; 441 | background-color: black; 442 | border-radius: 2px; 443 | } 444 | .irs--sharp .irs-bar { 445 | top: 30px; 446 | height: 2px; 447 | background-color: #ee22fa; 448 | } 449 | .irs--sharp .irs-bar--single { 450 | border-radius: 2px 0 0 2px; 451 | } 452 | .irs--sharp .irs-shadow { 453 | height: 1px; 454 | bottom: 21px; 455 | background-color: rgba(0, 0, 0, 0.5); 456 | } 457 | .irs--sharp .irs-handle { 458 | top: 25px; 459 | width: 10px; 460 | height: 10px; 461 | background-color: #a804b2; 462 | } 463 | .irs--sharp .irs-handle > i:first-child { 464 | position: absolute; 465 | display: block; 466 | top: 100%; 467 | left: 0; 468 | width: 0; 469 | height: 0; 470 | border: 5px solid transparent; 471 | border-top-color: #a804b2; 472 | } 473 | .irs--sharp .irs-handle.state_hover, 474 | .irs--sharp .irs-handle:hover { 475 | background-color: black; 476 | } 477 | .irs--sharp .irs-handle.state_hover > i:first-child, 478 | .irs--sharp .irs-handle:hover > i:first-child { 479 | border-top-color: black; 480 | } 481 | .irs--sharp .irs-min, 482 | .irs--sharp .irs-max { 483 | color: white; 484 | font-size: 14px; 485 | line-height: 1; 486 | top: 0; 487 | padding: 3px 4px; 488 | opacity: 0.4; 489 | background-color: #a804b2; 490 | border-radius: 2px; 491 | } 492 | .irs--sharp .irs-from, 493 | .irs--sharp .irs-to, 494 | .irs--sharp .irs-single { 495 | font-size: 14px; 496 | line-height: 1; 497 | text-shadow: none; 498 | padding: 3px 4px; 499 | background-color: #a804b2; 500 | color: white; 501 | border-radius: 2px; 502 | } 503 | .irs--sharp .irs-from:before, 504 | .irs--sharp .irs-to:before, 505 | .irs--sharp .irs-single:before { 506 | position: absolute; 507 | display: block; 508 | content: ""; 509 | bottom: -6px; 510 | left: 50%; 511 | width: 0; 512 | height: 0; 513 | margin-left: -3px; 514 | overflow: hidden; 515 | border: 3px solid transparent; 516 | border-top-color: #a804b2; 517 | } 518 | .irs--sharp .irs-grid { 519 | height: 25px; 520 | } 521 | .irs--sharp .irs-grid-pol { 522 | background-color: #dedede; 523 | } 524 | .irs--sharp .irs-grid-text { 525 | color: silver; 526 | font-size: 13px; 527 | } 528 | .irs--round { 529 | height: 50px; 530 | } 531 | .irs--round.irs-with-grid { 532 | height: 65px; 533 | } 534 | .irs--round .irs-line { 535 | top: 36px; 536 | height: 4px; 537 | background-color: #dee4ec; 538 | border-radius: 4px; 539 | } 540 | .irs--round .irs-bar { 541 | top: 36px; 542 | height: 4px; 543 | background-color: #006cfa; 544 | } 545 | .irs--round .irs-bar--single { 546 | border-radius: 4px 0 0 4px; 547 | } 548 | .irs--round .irs-shadow { 549 | height: 4px; 550 | bottom: 21px; 551 | background-color: rgba(222, 228, 236, 0.5); 552 | } 553 | .irs--round .irs-handle { 554 | top: 26px; 555 | width: 24px; 556 | height: 24px; 557 | border: 4px solid #006cfa; 558 | background-color: white; 559 | border-radius: 24px; 560 | box-shadow: 0 1px 3px rgba(0, 0, 255, 0.3); 561 | } 562 | .irs--round .irs-handle.state_hover, 563 | .irs--round .irs-handle:hover { 564 | background-color: #f0f6ff; 565 | } 566 | .irs--round .irs-min, 567 | .irs--round .irs-max { 568 | color: #333; 569 | font-size: 14px; 570 | line-height: 1; 571 | top: 0; 572 | padding: 3px 5px; 573 | background-color: rgba(0, 0, 0, 0.1); 574 | border-radius: 4px; 575 | } 576 | .irs--round .irs-from, 577 | .irs--round .irs-to, 578 | .irs--round .irs-single { 579 | font-size: 14px; 580 | line-height: 1; 581 | text-shadow: none; 582 | padding: 3px 5px; 583 | background-color: #006cfa; 584 | color: white; 585 | border-radius: 4px; 586 | } 587 | .irs--round .irs-from:before, 588 | .irs--round .irs-to:before, 589 | .irs--round .irs-single:before { 590 | position: absolute; 591 | display: block; 592 | content: ""; 593 | bottom: -6px; 594 | left: 50%; 595 | width: 0; 596 | height: 0; 597 | margin-left: -3px; 598 | overflow: hidden; 599 | border: 3px solid transparent; 600 | border-top-color: #006cfa; 601 | } 602 | .irs--round .irs-grid { 603 | height: 25px; 604 | } 605 | .irs--round .irs-grid-pol { 606 | background-color: #dedede; 607 | } 608 | .irs--round .irs-grid-text { 609 | color: silver; 610 | font-size: 13px; 611 | } 612 | .irs--square { 613 | height: 50px; 614 | } 615 | .irs--square.irs-with-grid { 616 | height: 60px; 617 | } 618 | .irs--square .irs-line { 619 | top: 31px; 620 | height: 4px; 621 | background-color: #dedede; 622 | } 623 | .irs--square .irs-bar { 624 | top: 31px; 625 | height: 4px; 626 | background-color: black; 627 | } 628 | .irs--square .irs-shadow { 629 | height: 2px; 630 | bottom: 21px; 631 | background-color: #dedede; 632 | } 633 | .irs--square .irs-handle { 634 | top: 25px; 635 | width: 16px; 636 | height: 16px; 637 | border: 3px solid black; 638 | background-color: white; 639 | -webkit-transform: rotate(45deg); 640 | -ms-transform: rotate(45deg); 641 | transform: rotate(45deg); 642 | } 643 | .irs--square .irs-handle.state_hover, 644 | .irs--square .irs-handle:hover { 645 | background-color: #f0f6ff; 646 | } 647 | .irs--square .irs-min, 648 | .irs--square .irs-max { 649 | color: #333; 650 | font-size: 14px; 651 | line-height: 1; 652 | top: 0; 653 | padding: 3px 5px; 654 | background-color: rgba(0, 0, 0, 0.1); 655 | } 656 | .irs--square .irs-from, 657 | .irs--square .irs-to, 658 | .irs--square .irs-single { 659 | font-size: 14px; 660 | line-height: 1; 661 | text-shadow: none; 662 | padding: 3px 5px; 663 | background-color: black; 664 | color: white; 665 | } 666 | .irs--square .irs-grid { 667 | height: 25px; 668 | } 669 | .irs--square .irs-grid-pol { 670 | background-color: #dedede; 671 | } 672 | .irs--square .irs-grid-text { 673 | color: silver; 674 | font-size: 11px; 675 | } 676 | -------------------------------------------------------------------------------- /css/ion.rangeSlider.min.css: -------------------------------------------------------------------------------- 1 | /*!Ion.RangeSlider, 2.3.1, © Denis Ineshin, 2010 - 2019, IonDen.com, Build date: 2019-12-19 16:51:02*/.irs{position:relative;display:block;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:12px;font-family:Arial,sans-serif}.irs-line{position:relative;display:block;overflow:hidden;outline:none !important}.irs-bar{position:absolute;display:block;left:0;width:0}.irs-shadow{position:absolute;display:none;left:0;width:0}.irs-handle{position:absolute;display:block;box-sizing:border-box;cursor:default;z-index:1}.irs-handle.type_last{z-index:2}.irs-min,.irs-max{position:absolute;display:block;cursor:default}.irs-min{left:0}.irs-max{right:0}.irs-from,.irs-to,.irs-single{position:absolute;display:block;top:0;left:0;cursor:default;white-space:nowrap}.irs-grid{position:absolute;display:none;bottom:0;left:0;width:100%;height:20px}.irs-with-grid .irs-grid{display:block}.irs-grid-pol{position:absolute;top:0;left:0;width:1px;height:8px;background:#000}.irs-grid-pol.small{height:4px}.irs-grid-text{position:absolute;bottom:0;left:0;white-space:nowrap;text-align:center;font-size:9px;line-height:9px;padding:0 3px;color:#000}.irs-disable-mask{position:absolute;display:block;top:0;left:-1%;width:102%;height:100%;cursor:default;background:rgba(0,0,0,0);z-index:2}.lt-ie9 .irs-disable-mask{background:#000;filter:alpha(opacity=0);cursor:not-allowed}.irs-disabled{opacity:.4}.irs-hidden-input{position:absolute !important;display:block !important;top:0 !important;left:0 !important;width:0 !important;height:0 !important;font-size:0 !important;line-height:0 !important;padding:0 !important;margin:0 !important;overflow:hidden;outline:none !important;z-index:-9999 !important;background:none !important;border-style:solid !important;border-color:transparent !important}.irs--flat{height:40px}.irs--flat.irs-with-grid{height:60px}.irs--flat .irs-line{top:25px;height:12px;background-color:#e1e4e9;border-radius:4px}.irs--flat .irs-bar{top:25px;height:12px;background-color:#ed5565}.irs--flat .irs-bar--single{border-radius:4px 0 0 4px}.irs--flat .irs-shadow{height:1px;bottom:16px;background-color:#e1e4e9}.irs--flat .irs-handle{top:22px;width:16px;height:18px;background-color:transparent}.irs--flat .irs-handle>i:first-child{position:absolute;display:block;top:0;left:50%;width:2px;height:100%;margin-left:-1px;background-color:#da4453}.irs--flat .irs-handle.state_hover>i:first-child,.irs--flat .irs-handle:hover>i:first-child{background-color:#a43540}.irs--flat .irs-min,.irs--flat .irs-max{top:0;padding:1px 3px;color:#999;font-size:10px;line-height:1.333;text-shadow:none;background-color:#e1e4e9;border-radius:4px}.irs--flat .irs-from,.irs--flat .irs-to,.irs--flat .irs-single{color:white;font-size:10px;line-height:1.333;text-shadow:none;padding:1px 5px;background-color:#ed5565;border-radius:4px}.irs--flat .irs-from:before,.irs--flat .irs-to:before,.irs--flat .irs-single:before{position:absolute;display:block;content:"";bottom:-6px;left:50%;width:0;height:0;margin-left:-3px;overflow:hidden;border:3px solid transparent;border-top-color:#ed5565}.irs--flat .irs-grid-pol{background-color:#e1e4e9}.irs--flat .irs-grid-text{color:#999}.irs--big{height:55px}.irs--big.irs-with-grid{height:70px}.irs--big .irs-line{top:33px;height:12px;background-color:white;background:linear-gradient(to bottom, #ddd -50%, white 150%);border:1px solid #ccc;border-radius:12px}.irs--big .irs-bar{top:33px;height:12px;background-color:#92bce0;border:1px solid #428bca;background:linear-gradient(to bottom, #ffffff 0%, #428bca 30%, #b9d4ec 100%);box-shadow:inset 0 0 1px 1px rgba(255,255,255,0.5)}.irs--big .irs-bar--single{border-radius:12px 0 0 12px}.irs--big .irs-shadow{height:1px;bottom:16px;background-color:rgba(66,139,202,0.5)}.irs--big .irs-handle{top:25px;width:30px;height:30px;border:1px solid rgba(0,0,0,0.3);background-color:#cbcfd5;background:linear-gradient(to bottom, white 0%, #B4B9BE 30%, white 100%);box-shadow:1px 1px 2px rgba(0,0,0,0.2),inset 0 0 3px 1px white;border-radius:30px}.irs--big .irs-handle.state_hover,.irs--big .irs-handle:hover{border-color:rgba(0,0,0,0.45);background-color:#939ba7;background:linear-gradient(to bottom, white 0%, #919BA5 30%, white 100%)}.irs--big .irs-min,.irs--big .irs-max{top:0;padding:1px 5px;color:white;text-shadow:none;background-color:#9f9f9f;border-radius:3px}.irs--big .irs-from,.irs--big .irs-to,.irs--big .irs-single{color:white;text-shadow:none;padding:1px 5px;background-color:#428bca;background:linear-gradient(to bottom, #428bca 0%, #3071a9 100%);border-radius:3px}.irs--big .irs-grid-pol{background-color:#428bca}.irs--big .irs-grid-text{color:#428bca}.irs--modern{height:55px}.irs--modern.irs-with-grid{height:55px}.irs--modern .irs-line{top:25px;height:5px;background-color:#d1d6e0;background:linear-gradient(to bottom, #e0e4ea 0%, #d1d6e0 100%);border:1px solid #a3adc1;border-bottom-width:0;border-radius:5px}.irs--modern .irs-bar{top:25px;height:5px;background:#20b426;background:linear-gradient(to bottom, #20b426 0%, #18891d 100%)}.irs--modern .irs-bar--single{border-radius:5px 0 0 5px}.irs--modern .irs-shadow{height:1px;bottom:21px;background-color:rgba(209,214,224,0.5)}.irs--modern .irs-handle{top:37px;width:12px;height:13px;border:1px solid #a3adc1;border-top-width:0;box-shadow:1px 1px 1px rgba(0,0,0,0.1);border-radius:0 0 3px 3px}.irs--modern .irs-handle>i:nth-child(1){position:absolute;display:block;top:-4px;left:1px;width:6px;height:6px;border:1px solid #a3adc1;background:white;transform:rotate(45deg)}.irs--modern .irs-handle>i:nth-child(2){position:absolute;display:block;box-sizing:border-box;top:0;left:0;width:10px;height:12px;background:#e9e6e6;background:linear-gradient(to bottom, white 0%, #e9e6e6 100%);border-radius:0 0 3px 3px}.irs--modern .irs-handle>i:nth-child(3){position:absolute;display:block;box-sizing:border-box;top:3px;left:3px;width:4px;height:5px;border-left:1px solid #a3adc1;border-right:1px solid #a3adc1}.irs--modern .irs-handle.state_hover,.irs--modern .irs-handle:hover{border-color:#7685a2;background:#c3c7cd;background:linear-gradient(to bottom, #ffffff 0%, #919ba5 30%, #ffffff 100%)}.irs--modern .irs-handle.state_hover>i:nth-child(1),.irs--modern .irs-handle:hover>i:nth-child(1){border-color:#7685a2}.irs--modern .irs-handle.state_hover>i:nth-child(3),.irs--modern .irs-handle:hover>i:nth-child(3){border-color:#48536a}.irs--modern .irs-min,.irs--modern .irs-max{top:0;font-size:10px;line-height:1.333;text-shadow:none;padding:1px 5px;color:white;background-color:#d1d6e0;border-radius:5px}.irs--modern .irs-from,.irs--modern .irs-to,.irs--modern .irs-single{font-size:10px;line-height:1.333;text-shadow:none;padding:1px 5px;background-color:#20b426;color:white;border-radius:5px}.irs--modern .irs-from:before,.irs--modern .irs-to:before,.irs--modern .irs-single:before{position:absolute;display:block;content:"";bottom:-6px;left:50%;width:0;height:0;margin-left:-3px;overflow:hidden;border:3px solid transparent;border-top-color:#20b426}.irs--modern .irs-grid{height:25px}.irs--modern .irs-grid-pol{background-color:#dedede}.irs--modern .irs-grid-text{color:silver;font-size:13px}.irs--sharp{height:50px;font-size:12px;line-height:1}.irs--sharp.irs-with-grid{height:57px}.irs--sharp .irs-line{top:30px;height:2px;background-color:black;border-radius:2px}.irs--sharp .irs-bar{top:30px;height:2px;background-color:#ee22fa}.irs--sharp .irs-bar--single{border-radius:2px 0 0 2px}.irs--sharp .irs-shadow{height:1px;bottom:21px;background-color:rgba(0,0,0,0.5)}.irs--sharp .irs-handle{top:25px;width:10px;height:10px;background-color:#a804b2}.irs--sharp .irs-handle>i:first-child{position:absolute;display:block;top:100%;left:0;width:0;height:0;border:5px solid transparent;border-top-color:#a804b2}.irs--sharp .irs-handle.state_hover,.irs--sharp .irs-handle:hover{background-color:black}.irs--sharp .irs-handle.state_hover>i:first-child,.irs--sharp .irs-handle:hover>i:first-child{border-top-color:black}.irs--sharp .irs-min,.irs--sharp .irs-max{color:white;font-size:14px;line-height:1;top:0;padding:3px 4px;opacity:.4;background-color:#a804b2;border-radius:2px}.irs--sharp .irs-from,.irs--sharp .irs-to,.irs--sharp .irs-single{font-size:14px;line-height:1;text-shadow:none;padding:3px 4px;background-color:#a804b2;color:white;border-radius:2px}.irs--sharp .irs-from:before,.irs--sharp .irs-to:before,.irs--sharp .irs-single:before{position:absolute;display:block;content:"";bottom:-6px;left:50%;width:0;height:0;margin-left:-3px;overflow:hidden;border:3px solid transparent;border-top-color:#a804b2}.irs--sharp .irs-grid{height:25px}.irs--sharp .irs-grid-pol{background-color:#dedede}.irs--sharp .irs-grid-text{color:silver;font-size:13px}.irs--round{height:50px}.irs--round.irs-with-grid{height:65px}.irs--round .irs-line{top:36px;height:4px;background-color:#dee4ec;border-radius:4px}.irs--round .irs-bar{top:36px;height:4px;background-color:#006cfa}.irs--round .irs-bar--single{border-radius:4px 0 0 4px}.irs--round .irs-shadow{height:4px;bottom:21px;background-color:rgba(222,228,236,0.5)}.irs--round .irs-handle{top:26px;width:24px;height:24px;border:4px solid #006cfa;background-color:white;border-radius:24px;box-shadow:0 1px 3px rgba(0,0,255,0.3)}.irs--round .irs-handle.state_hover,.irs--round .irs-handle:hover{background-color:#f0f6ff}.irs--round .irs-min,.irs--round .irs-max{color:#333;font-size:14px;line-height:1;top:0;padding:3px 5px;background-color:rgba(0,0,0,0.1);border-radius:4px}.irs--round .irs-from,.irs--round .irs-to,.irs--round .irs-single{font-size:14px;line-height:1;text-shadow:none;padding:3px 5px;background-color:#006cfa;color:white;border-radius:4px}.irs--round .irs-from:before,.irs--round .irs-to:before,.irs--round .irs-single:before{position:absolute;display:block;content:"";bottom:-6px;left:50%;width:0;height:0;margin-left:-3px;overflow:hidden;border:3px solid transparent;border-top-color:#006cfa}.irs--round .irs-grid{height:25px}.irs--round .irs-grid-pol{background-color:#dedede}.irs--round .irs-grid-text{color:silver;font-size:13px}.irs--square{height:50px}.irs--square.irs-with-grid{height:60px}.irs--square .irs-line{top:31px;height:4px;background-color:#dedede}.irs--square .irs-bar{top:31px;height:4px;background-color:black}.irs--square .irs-shadow{height:2px;bottom:21px;background-color:#dedede}.irs--square .irs-handle{top:25px;width:16px;height:16px;border:3px solid black;background-color:white;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.irs--square .irs-handle.state_hover,.irs--square .irs-handle:hover{background-color:#f0f6ff}.irs--square .irs-min,.irs--square .irs-max{color:#333;font-size:14px;line-height:1;top:0;padding:3px 5px;background-color:rgba(0,0,0,0.1)}.irs--square .irs-from,.irs--square .irs-to,.irs--square .irs-single{font-size:14px;line-height:1;text-shadow:none;padding:3px 5px;background-color:black;color:white}.irs--square .irs-grid{height:25px}.irs--square .irs-grid-pol{background-color:#dedede}.irs--square .irs-grid-text{color:silver;font-size:11px} -------------------------------------------------------------------------------- /history.md: -------------------------------------------------------------------------------- 1 | ![ion.rangeSlider](_tmp/logo-ion-range-slider.png) 2 | 3 | [Support the plugin on GitHub sponsors](https://github.com/sponsors/IonDen) 4 | 5 | # Update History 6 | 7 | ### Version 2.3.1. December 19, 2019 8 | * Website update 9 | * Minor bugfixes 10 | 11 | ### Version 2.3.0. December 11, 2018 12 | * Website update 13 | * Big skins update 14 | * Minor bugfixes 15 | 16 | ### Version 2.2.0. June 21, 2017 17 | * Slider has `TabIndex` support now. Issue #321 18 | * `keyboard_step` option removed as confusing. 19 | * `keyboard` controls are enabled by default now 20 | * `keyboard` movement is bind to step now 21 | * Traverse extra class names to container. Issue #318 22 | * Prettified values added to `result object`. Issue #356 23 | * It is possible to pass `scope` for callbacks now. Issue #402 24 | * New option `block`. Light version of `disabled` but sliders value can be send with form. Issue #242 25 | 26 | ### Version 2.1.8. June 19, 2017 27 | * Issues resolved: #420, #423, #441, #464, #479 28 | 29 | ### Version 2.1.7. March 26, 2017 30 | * Issues: #438 31 | * Reverted: #390 32 | 33 | ### Version 2.1.6. December 27, 2016 34 | * Issues: #393, #406, #429, #431, #432 35 | 36 | ### Version 2.1.5. December 12, 2016 37 | * Issues: #331, #332, #333, #337, #338, #343, #358, #374, #380, #389, #390, #394, #411, #412, #413 38 | 39 | ### Version 2.1.4. April 27, 2016 40 | * Issues: #330, #369 41 | 42 | ### Version 2.1.3. April 10, 2016 43 | * Issues: #342, #350 44 | 45 | ### Version 2.1.2. October 13, 2015 46 | * Fixed bugs. Issues: #310, #312, #313, #316 47 | 48 | ### Version 2.1.1. September 21, 2015 49 | * Fixed bugs. Issues: #305 50 | * New features. Requests: #282 51 | 52 | ### Version 2.1.0. September 20, 2015 53 | * Fixed bugs. Issues: #288 54 | * New features. Requests: #281, #284, #286, #289 55 | * Some code refactoring 56 | * Code documentation updated 57 | 58 | ### Version 2.0.13. July 25, 2015 59 | * Fixed bugs. Issues: #208, #270, #273 60 | * New features. Requests: #233 61 | 62 | ### Version 2.0.12. July 10, 2015 63 | * Fixed more bugs. Issues: #247, #263, #265, #269 64 | 65 | ### Version 2.0.11. July 02, 2015 66 | * Fixed more bugs. Issues: #247, #253 67 | 68 | ### Version 2.0.10. June 06, 2015 69 | * Fixed rounding bug. Issue #247 70 | 71 | ### Version 2.0.9. May 30, 2015 72 | * Fixed critical bug. Issue #246 73 | 74 | ### Version 2.0.8. May 30, 2015 75 | * Fixed some bugs. Issues: #219, #228, #230, #245 76 | 77 | ### Version 2.0.7. May 26, 2015 78 | * Fixed memory issue: #220 79 | * Fixed CPU issue: #186 80 | * Merged PRs: #209, #226, #235 81 | 82 | ### Version 2.0.6. February 17, 2015 83 | * Issues done: #197 84 | * Fixed bug with broken From and To 85 | 86 | ### Version 2.0.5. February 13, 2015 87 | * Issues done: #193, #195, #201 88 | 89 | ### Version 2.0.4. February 12, 2015 90 | * Issues done: #174, #184 91 | * NPM support added 92 | * Readme files optimisations 93 | 94 | ### Version 2.0.3. December 29, 2014 95 | * Issues done: #160, #165, #166, #168, #170 96 | 97 | ### Version 2.0.2: December 02, 2014 98 | * Issues done: #143, #148, #153, #155, #159 99 | * API update. 100 | 101 | ### Version 2.0.1: November 15, 2014 102 | * Some bugs fixed 103 | * Some new methods 104 | 105 | ### Version 2.0.0: November 08, 2014 106 | * New Core 107 | * New API 108 | * Lot's of bug fixes 109 | * Many improvements 110 | * SPM support added 111 | 112 | ### Version 1.9.3: August 06, 2014 113 | * Bower support added 114 | 115 | ### Version 1.9.2: August 04, 2014 116 | * New param gridMargin 117 | * Issues done: #89, #94, #96, #97, #98, #103 118 | 119 | ### Version 1.9.1: April 15, 2014 120 | * Issues done: #81, #82, #85 121 | 122 | ### Version 1.9.0: March 16, 2014 123 | * Issues done: #65, #68, #70, #77, #78 124 | * New plugin description 125 | * New demos design 126 | * Some new slider params 127 | 128 | ### Version 1.8.5: January 12, 2014 129 | * Issues done: #12, #30, #33, #43, #47, #52, #58 130 | * Bug fixes 131 | * New param "disable" 132 | * Link to input and slider in all callbacks 133 | * Click on slider to move it 134 | 135 | ### Version 1.8.2: October 31, 2013 136 | * Issues done: #13, #31, #35, #37, #40 137 | * Some code optimisations 138 | 139 | ### Version 1.8.1: October 10, 2013 140 | * Issues done: #25 141 | * New Flat UI Skin 142 | * Some skin optimisations 143 | 144 | ### Version 1.8.0: October 08, 2013 145 | * Issues done: #20, #21, #23, #24, #26 146 | * Removed hideText option 147 | * New method and options 148 | * Improved code style 149 | * Minor optimisations 150 | 151 | ### Version 1.7.2: September 11, 2013 152 | * Issues done: #15, #16 153 | * Fixed bug on Android-devices 154 | * Added support for negative and fractional values 155 | 156 | ### Version 1.7.0: August 23, 2013 157 | * Issues done: #7, #8, #9, #10 158 | * Some enhancements 159 | 160 | ### Version 1.6.3: July 29, 2013 161 | * Issues done: #2 162 | * Moved to Semantic Versioning 163 | 164 | ### December, 2012 165 | * Plugin release 166 | 167 | *** 168 | 169 | [Support the plugin on GitHub sponsors](https://github.com/sponsors/IonDen) 170 | -------------------------------------------------------------------------------- /js/ion.rangeSlider.js: -------------------------------------------------------------------------------- 1 | // Ion.RangeSlider 2 | // version 2.3.1 Build: 382 3 | // © Denis Ineshin, 2019 4 | // https://github.com/IonDen 5 | // 6 | // Project page: http://ionden.com/a/plugins/ion.rangeSlider/en.html 7 | // GitHub page: https://github.com/IonDen/ion.rangeSlider 8 | // 9 | // Released under MIT licence: 10 | // http://ionden.com/a/plugins/licence-en.html 11 | // ===================================================================================================================== 12 | 13 | ;(function(factory) { 14 | if ((typeof jQuery === 'undefined' || !jQuery) && typeof define === "function" && define.amd) { 15 | define(["jquery"], function (jQuery) { 16 | return factory(jQuery, document, window, navigator); 17 | }); 18 | } else if ((typeof jQuery === 'undefined' || !jQuery) && typeof exports === "object") { 19 | factory(require("jquery"), document, window, navigator); 20 | } else { 21 | factory(jQuery, document, window, navigator); 22 | } 23 | } (function ($, document, window, navigator, undefined) { 24 | "use strict"; 25 | 26 | // ================================================================================================================= 27 | // Service 28 | 29 | var plugin_count = 0; 30 | 31 | // IE8 fix 32 | var is_old_ie = (function () { 33 | var n = navigator.userAgent, 34 | r = /msie\s\d+/i, 35 | v; 36 | if (n.search(r) > 0) { 37 | v = r.exec(n).toString(); 38 | v = v.split(" ")[1]; 39 | if (v < 9) { 40 | $("html").addClass("lt-ie9"); 41 | return true; 42 | } 43 | } 44 | return false; 45 | } ()); 46 | if (!Function.prototype.bind) { 47 | Function.prototype.bind = function bind(that) { 48 | 49 | var target = this; 50 | var slice = [].slice; 51 | 52 | if (typeof target != "function") { 53 | throw new TypeError(); 54 | } 55 | 56 | var args = slice.call(arguments, 1), 57 | bound = function () { 58 | 59 | if (this instanceof bound) { 60 | 61 | var F = function(){}; 62 | F.prototype = target.prototype; 63 | var self = new F(); 64 | 65 | var result = target.apply( 66 | self, 67 | args.concat(slice.call(arguments)) 68 | ); 69 | if (Object(result) === result) { 70 | return result; 71 | } 72 | return self; 73 | 74 | } else { 75 | 76 | return target.apply( 77 | that, 78 | args.concat(slice.call(arguments)) 79 | ); 80 | 81 | } 82 | 83 | }; 84 | 85 | return bound; 86 | }; 87 | } 88 | if (!Array.prototype.indexOf) { 89 | Array.prototype.indexOf = function(searchElement, fromIndex) { 90 | var k; 91 | if (this == null) { 92 | throw new TypeError('"this" is null or not defined'); 93 | } 94 | var O = Object(this); 95 | var len = O.length >>> 0; 96 | if (len === 0) { 97 | return -1; 98 | } 99 | var n = +fromIndex || 0; 100 | if (Math.abs(n) === Infinity) { 101 | n = 0; 102 | } 103 | if (n >= len) { 104 | return -1; 105 | } 106 | k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); 107 | while (k < len) { 108 | if (k in O && O[k] === searchElement) { 109 | return k; 110 | } 111 | k++; 112 | } 113 | return -1; 114 | }; 115 | } 116 | 117 | 118 | 119 | // ================================================================================================================= 120 | // Template 121 | 122 | var base_html = 123 | '' + 124 | '' + 125 | '01' + 126 | '000' + 127 | '' + 128 | ''; 129 | 130 | var single_html = 131 | '' + 132 | '' + 133 | ''; 134 | 135 | var double_html = 136 | '' + 137 | '' + 138 | '' + 139 | '' + 140 | ''; 141 | 142 | var disable_html = 143 | ''; 144 | 145 | 146 | 147 | // ================================================================================================================= 148 | // Core 149 | 150 | /** 151 | * Main plugin constructor 152 | * 153 | * @param input {Object} link to base input element 154 | * @param options {Object} slider config 155 | * @param plugin_count {Number} 156 | * @constructor 157 | */ 158 | var IonRangeSlider = function (input, options, plugin_count) { 159 | this.VERSION = "2.3.1"; 160 | this.input = input; 161 | this.plugin_count = plugin_count; 162 | this.current_plugin = 0; 163 | this.calc_count = 0; 164 | this.update_tm = 0; 165 | this.old_from = 0; 166 | this.old_to = 0; 167 | this.old_min_interval = null; 168 | this.raf_id = null; 169 | this.dragging = false; 170 | this.force_redraw = false; 171 | this.no_diapason = false; 172 | this.has_tab_index = true; 173 | this.is_key = false; 174 | this.is_update = false; 175 | this.is_start = true; 176 | this.is_finish = false; 177 | this.is_active = false; 178 | this.is_resize = false; 179 | this.is_click = false; 180 | 181 | options = options || {}; 182 | 183 | // cache for links to all DOM elements 184 | this.$cache = { 185 | win: $(window), 186 | body: $(document.body), 187 | input: $(input), 188 | cont: null, 189 | rs: null, 190 | min: null, 191 | max: null, 192 | from: null, 193 | to: null, 194 | single: null, 195 | bar: null, 196 | line: null, 197 | s_single: null, 198 | s_from: null, 199 | s_to: null, 200 | shad_single: null, 201 | shad_from: null, 202 | shad_to: null, 203 | edge: null, 204 | grid: null, 205 | grid_labels: [] 206 | }; 207 | 208 | // storage for measure variables 209 | this.coords = { 210 | // left 211 | x_gap: 0, 212 | x_pointer: 0, 213 | 214 | // width 215 | w_rs: 0, 216 | w_rs_old: 0, 217 | w_handle: 0, 218 | 219 | // percents 220 | p_gap: 0, 221 | p_gap_left: 0, 222 | p_gap_right: 0, 223 | p_step: 0, 224 | p_pointer: 0, 225 | p_handle: 0, 226 | p_single_fake: 0, 227 | p_single_real: 0, 228 | p_from_fake: 0, 229 | p_from_real: 0, 230 | p_to_fake: 0, 231 | p_to_real: 0, 232 | p_bar_x: 0, 233 | p_bar_w: 0, 234 | 235 | // grid 236 | grid_gap: 0, 237 | big_num: 0, 238 | big: [], 239 | big_w: [], 240 | big_p: [], 241 | big_x: [] 242 | }; 243 | 244 | // storage for labels measure variables 245 | this.labels = { 246 | // width 247 | w_min: 0, 248 | w_max: 0, 249 | w_from: 0, 250 | w_to: 0, 251 | w_single: 0, 252 | 253 | // percents 254 | p_min: 0, 255 | p_max: 0, 256 | p_from_fake: 0, 257 | p_from_left: 0, 258 | p_to_fake: 0, 259 | p_to_left: 0, 260 | p_single_fake: 0, 261 | p_single_left: 0 262 | }; 263 | 264 | 265 | 266 | /** 267 | * get and validate config 268 | */ 269 | var $inp = this.$cache.input, 270 | val = $inp.prop("value"), 271 | config, config_from_data, prop; 272 | 273 | // default config 274 | config = { 275 | skin: "flat", 276 | type: "single", 277 | 278 | min: 10, 279 | max: 100, 280 | from: null, 281 | to: null, 282 | step: 1, 283 | 284 | min_interval: 0, 285 | max_interval: 0, 286 | drag_interval: false, 287 | 288 | values: [], 289 | p_values: [], 290 | 291 | from_fixed: false, 292 | from_min: null, 293 | from_max: null, 294 | from_shadow: false, 295 | 296 | to_fixed: false, 297 | to_min: null, 298 | to_max: null, 299 | to_shadow: false, 300 | 301 | prettify_enabled: true, 302 | prettify_separator: " ", 303 | prettify: null, 304 | 305 | force_edges: false, 306 | 307 | keyboard: true, 308 | 309 | grid: false, 310 | grid_margin: true, 311 | grid_num: 4, 312 | grid_snap: false, 313 | 314 | hide_min_max: false, 315 | hide_from_to: false, 316 | 317 | prefix: "", 318 | postfix: "", 319 | max_postfix: "", 320 | decorate_both: true, 321 | values_separator: " — ", 322 | 323 | input_values_separator: ";", 324 | 325 | disable: false, 326 | block: false, 327 | 328 | extra_classes: "", 329 | 330 | scope: null, 331 | onStart: null, 332 | onChange: null, 333 | onFinish: null, 334 | onUpdate: null 335 | }; 336 | 337 | 338 | // check if base element is input 339 | if ($inp[0].nodeName !== "INPUT") { 340 | console && console.warn && console.warn("Base element should be !", $inp[0]); 341 | } 342 | 343 | 344 | // config from data-attributes extends js config 345 | config_from_data = { 346 | skin: $inp.data("skin"), 347 | type: $inp.data("type"), 348 | 349 | min: $inp.data("min"), 350 | max: $inp.data("max"), 351 | from: $inp.data("from"), 352 | to: $inp.data("to"), 353 | step: $inp.data("step"), 354 | 355 | min_interval: $inp.data("minInterval"), 356 | max_interval: $inp.data("maxInterval"), 357 | drag_interval: $inp.data("dragInterval"), 358 | 359 | values: $inp.data("values"), 360 | 361 | from_fixed: $inp.data("fromFixed"), 362 | from_min: $inp.data("fromMin"), 363 | from_max: $inp.data("fromMax"), 364 | from_shadow: $inp.data("fromShadow"), 365 | 366 | to_fixed: $inp.data("toFixed"), 367 | to_min: $inp.data("toMin"), 368 | to_max: $inp.data("toMax"), 369 | to_shadow: $inp.data("toShadow"), 370 | 371 | prettify_enabled: $inp.data("prettifyEnabled"), 372 | prettify_separator: $inp.data("prettifySeparator"), 373 | 374 | force_edges: $inp.data("forceEdges"), 375 | 376 | keyboard: $inp.data("keyboard"), 377 | 378 | grid: $inp.data("grid"), 379 | grid_margin: $inp.data("gridMargin"), 380 | grid_num: $inp.data("gridNum"), 381 | grid_snap: $inp.data("gridSnap"), 382 | 383 | hide_min_max: $inp.data("hideMinMax"), 384 | hide_from_to: $inp.data("hideFromTo"), 385 | 386 | prefix: $inp.data("prefix"), 387 | postfix: $inp.data("postfix"), 388 | max_postfix: $inp.data("maxPostfix"), 389 | decorate_both: $inp.data("decorateBoth"), 390 | values_separator: $inp.data("valuesSeparator"), 391 | 392 | input_values_separator: $inp.data("inputValuesSeparator"), 393 | 394 | disable: $inp.data("disable"), 395 | block: $inp.data("block"), 396 | 397 | extra_classes: $inp.data("extraClasses"), 398 | }; 399 | config_from_data.values = config_from_data.values && config_from_data.values.split(","); 400 | 401 | for (prop in config_from_data) { 402 | if (config_from_data.hasOwnProperty(prop)) { 403 | if (config_from_data[prop] === undefined || config_from_data[prop] === "") { 404 | delete config_from_data[prop]; 405 | } 406 | } 407 | } 408 | 409 | 410 | // input value extends default config 411 | if (val !== undefined && val !== "") { 412 | val = val.split(config_from_data.input_values_separator || options.input_values_separator || ";"); 413 | 414 | if (val[0] && val[0] == +val[0]) { 415 | val[0] = +val[0]; 416 | } 417 | if (val[1] && val[1] == +val[1]) { 418 | val[1] = +val[1]; 419 | } 420 | 421 | if (options && options.values && options.values.length) { 422 | config.from = val[0] && options.values.indexOf(val[0]); 423 | config.to = val[1] && options.values.indexOf(val[1]); 424 | } else { 425 | config.from = val[0] && +val[0]; 426 | config.to = val[1] && +val[1]; 427 | } 428 | } 429 | 430 | 431 | 432 | // js config extends default config 433 | $.extend(config, options); 434 | 435 | 436 | // data config extends config 437 | $.extend(config, config_from_data); 438 | this.options = config; 439 | 440 | 441 | 442 | // validate config, to be sure that all data types are correct 443 | this.update_check = {}; 444 | this.validate(); 445 | 446 | 447 | 448 | // default result object, returned to callbacks 449 | this.result = { 450 | input: this.$cache.input, 451 | slider: null, 452 | 453 | min: this.options.min, 454 | max: this.options.max, 455 | 456 | from: this.options.from, 457 | from_percent: 0, 458 | from_value: null, 459 | 460 | to: this.options.to, 461 | to_percent: 0, 462 | to_value: null 463 | }; 464 | 465 | 466 | 467 | this.init(); 468 | }; 469 | 470 | IonRangeSlider.prototype = { 471 | 472 | /** 473 | * Starts or updates the plugin instance 474 | * 475 | * @param [is_update] {boolean} 476 | */ 477 | init: function (is_update) { 478 | this.no_diapason = false; 479 | this.coords.p_step = this.convertToPercent(this.options.step, true); 480 | 481 | this.target = "base"; 482 | 483 | this.toggleInput(); 484 | this.append(); 485 | this.setMinMax(); 486 | 487 | if (is_update) { 488 | this.force_redraw = true; 489 | this.calc(true); 490 | 491 | // callbacks called 492 | this.callOnUpdate(); 493 | } else { 494 | this.force_redraw = true; 495 | this.calc(true); 496 | 497 | // callbacks called 498 | this.callOnStart(); 499 | } 500 | 501 | this.updateScene(); 502 | }, 503 | 504 | /** 505 | * Appends slider template to a DOM 506 | */ 507 | append: function () { 508 | var container_html = ''; 509 | this.$cache.input.before(container_html); 510 | this.$cache.input.prop("readonly", true); 511 | this.$cache.cont = this.$cache.input.prev(); 512 | this.result.slider = this.$cache.cont; 513 | 514 | this.$cache.cont.html(base_html); 515 | this.$cache.rs = this.$cache.cont.find(".irs"); 516 | this.$cache.min = this.$cache.cont.find(".irs-min"); 517 | this.$cache.max = this.$cache.cont.find(".irs-max"); 518 | this.$cache.from = this.$cache.cont.find(".irs-from"); 519 | this.$cache.to = this.$cache.cont.find(".irs-to"); 520 | this.$cache.single = this.$cache.cont.find(".irs-single"); 521 | this.$cache.line = this.$cache.cont.find(".irs-line"); 522 | this.$cache.grid = this.$cache.cont.find(".irs-grid"); 523 | 524 | if (this.options.type === "single") { 525 | this.$cache.cont.append(single_html); 526 | this.$cache.bar = this.$cache.cont.find(".irs-bar"); 527 | this.$cache.edge = this.$cache.cont.find(".irs-bar-edge"); 528 | this.$cache.s_single = this.$cache.cont.find(".single"); 529 | this.$cache.from[0].style.visibility = "hidden"; 530 | this.$cache.to[0].style.visibility = "hidden"; 531 | this.$cache.shad_single = this.$cache.cont.find(".shadow-single"); 532 | } else { 533 | this.$cache.cont.append(double_html); 534 | this.$cache.bar = this.$cache.cont.find(".irs-bar"); 535 | this.$cache.s_from = this.$cache.cont.find(".from"); 536 | this.$cache.s_to = this.$cache.cont.find(".to"); 537 | this.$cache.shad_from = this.$cache.cont.find(".shadow-from"); 538 | this.$cache.shad_to = this.$cache.cont.find(".shadow-to"); 539 | 540 | this.setTopHandler(); 541 | } 542 | 543 | if (this.options.hide_from_to) { 544 | this.$cache.from[0].style.display = "none"; 545 | this.$cache.to[0].style.display = "none"; 546 | this.$cache.single[0].style.display = "none"; 547 | } 548 | 549 | this.appendGrid(); 550 | 551 | if (this.options.disable) { 552 | this.appendDisableMask(); 553 | this.$cache.input[0].disabled = true; 554 | } else { 555 | this.$cache.input[0].disabled = false; 556 | this.removeDisableMask(); 557 | this.bindEvents(); 558 | } 559 | 560 | // block only if not disabled 561 | if (!this.options.disable) { 562 | if (this.options.block) { 563 | this.appendDisableMask(); 564 | } else { 565 | this.removeDisableMask(); 566 | } 567 | } 568 | 569 | if (this.options.drag_interval) { 570 | this.$cache.bar[0].style.cursor = "ew-resize"; 571 | } 572 | }, 573 | 574 | /** 575 | * Determine which handler has a priority 576 | * works only for double slider type 577 | */ 578 | setTopHandler: function () { 579 | var min = this.options.min, 580 | max = this.options.max, 581 | from = this.options.from, 582 | to = this.options.to; 583 | 584 | if (from > min && to === max) { 585 | this.$cache.s_from.addClass("type_last"); 586 | } else if (to < max) { 587 | this.$cache.s_to.addClass("type_last"); 588 | } 589 | }, 590 | 591 | /** 592 | * Determine which handles was clicked last 593 | * and which handler should have hover effect 594 | * 595 | * @param target {String} 596 | */ 597 | changeLevel: function (target) { 598 | switch (target) { 599 | case "single": 600 | this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_single_fake); 601 | this.$cache.s_single.addClass("state_hover"); 602 | break; 603 | case "from": 604 | this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake); 605 | this.$cache.s_from.addClass("state_hover"); 606 | this.$cache.s_from.addClass("type_last"); 607 | this.$cache.s_to.removeClass("type_last"); 608 | break; 609 | case "to": 610 | this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_to_fake); 611 | this.$cache.s_to.addClass("state_hover"); 612 | this.$cache.s_to.addClass("type_last"); 613 | this.$cache.s_from.removeClass("type_last"); 614 | break; 615 | case "both": 616 | this.coords.p_gap_left = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake); 617 | this.coords.p_gap_right = this.toFixed(this.coords.p_to_fake - this.coords.p_pointer); 618 | this.$cache.s_to.removeClass("type_last"); 619 | this.$cache.s_from.removeClass("type_last"); 620 | break; 621 | } 622 | }, 623 | 624 | /** 625 | * Then slider is disabled 626 | * appends extra layer with opacity 627 | */ 628 | appendDisableMask: function () { 629 | this.$cache.cont.append(disable_html); 630 | this.$cache.cont.addClass("irs-disabled"); 631 | }, 632 | 633 | /** 634 | * Then slider is not disabled 635 | * remove disable mask 636 | */ 637 | removeDisableMask: function () { 638 | this.$cache.cont.remove(".irs-disable-mask"); 639 | this.$cache.cont.removeClass("irs-disabled"); 640 | }, 641 | 642 | /** 643 | * Remove slider instance 644 | * and unbind all events 645 | */ 646 | remove: function () { 647 | this.$cache.cont.remove(); 648 | this.$cache.cont = null; 649 | 650 | this.$cache.line.off("keydown.irs_" + this.plugin_count); 651 | 652 | this.$cache.body.off("touchmove.irs_" + this.plugin_count); 653 | this.$cache.body.off("mousemove.irs_" + this.plugin_count); 654 | 655 | this.$cache.win.off("touchend.irs_" + this.plugin_count); 656 | this.$cache.win.off("mouseup.irs_" + this.plugin_count); 657 | 658 | if (is_old_ie) { 659 | this.$cache.body.off("mouseup.irs_" + this.plugin_count); 660 | this.$cache.body.off("mouseleave.irs_" + this.plugin_count); 661 | } 662 | 663 | this.$cache.grid_labels = []; 664 | this.coords.big = []; 665 | this.coords.big_w = []; 666 | this.coords.big_p = []; 667 | this.coords.big_x = []; 668 | 669 | cancelAnimationFrame(this.raf_id); 670 | }, 671 | 672 | /** 673 | * bind all slider events 674 | */ 675 | bindEvents: function () { 676 | if (this.no_diapason) { 677 | return; 678 | } 679 | 680 | this.$cache.body.on("touchmove.irs_" + this.plugin_count, this.pointerMove.bind(this)); 681 | this.$cache.body.on("mousemove.irs_" + this.plugin_count, this.pointerMove.bind(this)); 682 | 683 | this.$cache.win.on("touchend.irs_" + this.plugin_count, this.pointerUp.bind(this)); 684 | this.$cache.win.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this)); 685 | 686 | this.$cache.line.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 687 | this.$cache.line.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 688 | 689 | this.$cache.line.on("focus.irs_" + this.plugin_count, this.pointerFocus.bind(this)); 690 | 691 | if (this.options.drag_interval && this.options.type === "double") { 692 | this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "both")); 693 | this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "both")); 694 | } else { 695 | this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 696 | this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 697 | } 698 | 699 | if (this.options.type === "single") { 700 | this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single")); 701 | this.$cache.s_single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single")); 702 | this.$cache.shad_single.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 703 | 704 | this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single")); 705 | this.$cache.s_single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single")); 706 | this.$cache.edge.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 707 | this.$cache.shad_single.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 708 | } else { 709 | this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, null)); 710 | this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, null)); 711 | 712 | this.$cache.from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from")); 713 | this.$cache.s_from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from")); 714 | this.$cache.to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to")); 715 | this.$cache.s_to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to")); 716 | this.$cache.shad_from.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 717 | this.$cache.shad_to.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 718 | 719 | this.$cache.from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from")); 720 | this.$cache.s_from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from")); 721 | this.$cache.to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to")); 722 | this.$cache.s_to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to")); 723 | this.$cache.shad_from.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 724 | this.$cache.shad_to.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click")); 725 | } 726 | 727 | if (this.options.keyboard) { 728 | this.$cache.line.on("keydown.irs_" + this.plugin_count, this.key.bind(this, "keyboard")); 729 | } 730 | 731 | if (is_old_ie) { 732 | this.$cache.body.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this)); 733 | this.$cache.body.on("mouseleave.irs_" + this.plugin_count, this.pointerUp.bind(this)); 734 | } 735 | }, 736 | 737 | /** 738 | * Focus with tabIndex 739 | * 740 | * @param e {Object} event object 741 | */ 742 | pointerFocus: function (e) { 743 | if (!this.target) { 744 | var x; 745 | var $handle; 746 | 747 | if (this.options.type === "single") { 748 | $handle = this.$cache.single; 749 | } else { 750 | $handle = this.$cache.from; 751 | } 752 | 753 | x = $handle.offset().left; 754 | x += ($handle.width() / 2) - 1; 755 | 756 | this.pointerClick("single", {preventDefault: function () {}, pageX: x}); 757 | } 758 | }, 759 | 760 | /** 761 | * Mousemove or touchmove 762 | * only for handlers 763 | * 764 | * @param e {Object} event object 765 | */ 766 | pointerMove: function (e) { 767 | if (!this.dragging) { 768 | return; 769 | } 770 | 771 | var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX; 772 | this.coords.x_pointer = x - this.coords.x_gap; 773 | 774 | this.calc(); 775 | }, 776 | 777 | /** 778 | * Mouseup or touchend 779 | * only for handlers 780 | * 781 | * @param e {Object} event object 782 | */ 783 | pointerUp: function (e) { 784 | if (this.current_plugin !== this.plugin_count) { 785 | return; 786 | } 787 | 788 | if (this.is_active) { 789 | this.is_active = false; 790 | } else { 791 | return; 792 | } 793 | 794 | this.$cache.cont.find(".state_hover").removeClass("state_hover"); 795 | 796 | this.force_redraw = true; 797 | 798 | if (is_old_ie) { 799 | $("*").prop("unselectable", false); 800 | } 801 | 802 | this.updateScene(); 803 | this.restoreOriginalMinInterval(); 804 | 805 | // callbacks call 806 | if ($.contains(this.$cache.cont[0], e.target) || this.dragging) { 807 | this.callOnFinish(); 808 | } 809 | 810 | this.dragging = false; 811 | }, 812 | 813 | /** 814 | * Mousedown or touchstart 815 | * only for handlers 816 | * 817 | * @param target {String|null} 818 | * @param e {Object} event object 819 | */ 820 | pointerDown: function (target, e) { 821 | e.preventDefault(); 822 | var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX; 823 | if (e.button === 2) { 824 | return; 825 | } 826 | 827 | if (target === "both") { 828 | this.setTempMinInterval(); 829 | } 830 | 831 | if (!target) { 832 | target = this.target || "from"; 833 | } 834 | 835 | this.current_plugin = this.plugin_count; 836 | this.target = target; 837 | 838 | this.is_active = true; 839 | this.dragging = true; 840 | 841 | this.coords.x_gap = this.$cache.rs.offset().left; 842 | this.coords.x_pointer = x - this.coords.x_gap; 843 | 844 | this.calcPointerPercent(); 845 | this.changeLevel(target); 846 | 847 | if (is_old_ie) { 848 | $("*").prop("unselectable", true); 849 | } 850 | 851 | this.$cache.line.trigger("focus"); 852 | 853 | this.updateScene(); 854 | }, 855 | 856 | /** 857 | * Mousedown or touchstart 858 | * for other slider elements, like diapason line 859 | * 860 | * @param target {String} 861 | * @param e {Object} event object 862 | */ 863 | pointerClick: function (target, e) { 864 | e.preventDefault(); 865 | var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX; 866 | if (e.button === 2) { 867 | return; 868 | } 869 | 870 | this.current_plugin = this.plugin_count; 871 | this.target = target; 872 | 873 | this.is_click = true; 874 | this.coords.x_gap = this.$cache.rs.offset().left; 875 | this.coords.x_pointer = +(x - this.coords.x_gap).toFixed(); 876 | 877 | this.force_redraw = true; 878 | this.calc(); 879 | 880 | this.$cache.line.trigger("focus"); 881 | }, 882 | 883 | /** 884 | * Keyborard controls for focused slider 885 | * 886 | * @param target {String} 887 | * @param e {Object} event object 888 | * @returns {boolean|undefined} 889 | */ 890 | key: function (target, e) { 891 | if (this.current_plugin !== this.plugin_count || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { 892 | return; 893 | } 894 | 895 | switch (e.which) { 896 | case 83: // W 897 | case 65: // A 898 | case 40: // DOWN 899 | case 37: // LEFT 900 | e.preventDefault(); 901 | this.moveByKey(false); 902 | break; 903 | 904 | case 87: // S 905 | case 68: // D 906 | case 38: // UP 907 | case 39: // RIGHT 908 | e.preventDefault(); 909 | this.moveByKey(true); 910 | break; 911 | } 912 | 913 | return true; 914 | }, 915 | 916 | /** 917 | * Move by key 918 | * 919 | * @param right {boolean} direction to move 920 | */ 921 | moveByKey: function (right) { 922 | var p = this.coords.p_pointer; 923 | var p_step = (this.options.max - this.options.min) / 100; 924 | p_step = this.options.step / p_step; 925 | 926 | if (right) { 927 | p += p_step; 928 | } else { 929 | p -= p_step; 930 | } 931 | 932 | this.coords.x_pointer = this.toFixed(this.coords.w_rs / 100 * p); 933 | this.is_key = true; 934 | this.calc(); 935 | }, 936 | 937 | /** 938 | * Set visibility and content 939 | * of Min and Max labels 940 | */ 941 | setMinMax: function () { 942 | if (!this.options) { 943 | return; 944 | } 945 | 946 | if (this.options.hide_min_max) { 947 | this.$cache.min[0].style.display = "none"; 948 | this.$cache.max[0].style.display = "none"; 949 | return; 950 | } 951 | 952 | if (this.options.values.length) { 953 | this.$cache.min.html(this.decorate(this.options.p_values[this.options.min])); 954 | this.$cache.max.html(this.decorate(this.options.p_values[this.options.max])); 955 | } else { 956 | var min_pretty = this._prettify(this.options.min); 957 | var max_pretty = this._prettify(this.options.max); 958 | 959 | this.result.min_pretty = min_pretty; 960 | this.result.max_pretty = max_pretty; 961 | 962 | this.$cache.min.html(this.decorate(min_pretty, this.options.min)); 963 | this.$cache.max.html(this.decorate(max_pretty, this.options.max)); 964 | } 965 | 966 | this.labels.w_min = this.$cache.min.outerWidth(false); 967 | this.labels.w_max = this.$cache.max.outerWidth(false); 968 | }, 969 | 970 | /** 971 | * Then dragging interval, prevent interval collapsing 972 | * using min_interval option 973 | */ 974 | setTempMinInterval: function () { 975 | var interval = this.result.to - this.result.from; 976 | 977 | if (this.old_min_interval === null) { 978 | this.old_min_interval = this.options.min_interval; 979 | } 980 | 981 | this.options.min_interval = interval; 982 | }, 983 | 984 | /** 985 | * Restore min_interval option to original 986 | */ 987 | restoreOriginalMinInterval: function () { 988 | if (this.old_min_interval !== null) { 989 | this.options.min_interval = this.old_min_interval; 990 | this.old_min_interval = null; 991 | } 992 | }, 993 | 994 | 995 | 996 | // ============================================================================================================= 997 | // Calculations 998 | 999 | /** 1000 | * All calculations and measures start here 1001 | * 1002 | * @param update {boolean=} 1003 | */ 1004 | calc: function (update) { 1005 | if (!this.options) { 1006 | return; 1007 | } 1008 | 1009 | this.calc_count++; 1010 | 1011 | if (this.calc_count === 10 || update) { 1012 | this.calc_count = 0; 1013 | this.coords.w_rs = this.$cache.rs.outerWidth(false); 1014 | 1015 | this.calcHandlePercent(); 1016 | } 1017 | 1018 | if (!this.coords.w_rs) { 1019 | return; 1020 | } 1021 | 1022 | this.calcPointerPercent(); 1023 | var handle_x = this.getHandleX(); 1024 | 1025 | 1026 | if (this.target === "both") { 1027 | this.coords.p_gap = 0; 1028 | handle_x = this.getHandleX(); 1029 | } 1030 | 1031 | if (this.target === "click") { 1032 | this.coords.p_gap = this.coords.p_handle / 2; 1033 | handle_x = this.getHandleX(); 1034 | 1035 | if (this.options.drag_interval) { 1036 | this.target = "both_one"; 1037 | } else { 1038 | this.target = this.chooseHandle(handle_x); 1039 | } 1040 | } 1041 | 1042 | switch (this.target) { 1043 | case "base": 1044 | var w = (this.options.max - this.options.min) / 100, 1045 | f = (this.result.from - this.options.min) / w, 1046 | t = (this.result.to - this.options.min) / w; 1047 | 1048 | this.coords.p_single_real = this.toFixed(f); 1049 | this.coords.p_from_real = this.toFixed(f); 1050 | this.coords.p_to_real = this.toFixed(t); 1051 | 1052 | this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max); 1053 | this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max); 1054 | this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max); 1055 | 1056 | this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real); 1057 | this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real); 1058 | this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real); 1059 | 1060 | this.target = null; 1061 | 1062 | break; 1063 | 1064 | case "single": 1065 | if (this.options.from_fixed) { 1066 | break; 1067 | } 1068 | 1069 | this.coords.p_single_real = this.convertToRealPercent(handle_x); 1070 | this.coords.p_single_real = this.calcWithStep(this.coords.p_single_real); 1071 | this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max); 1072 | 1073 | this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real); 1074 | 1075 | break; 1076 | 1077 | case "from": 1078 | if (this.options.from_fixed) { 1079 | break; 1080 | } 1081 | 1082 | this.coords.p_from_real = this.convertToRealPercent(handle_x); 1083 | this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real); 1084 | if (this.coords.p_from_real > this.coords.p_to_real) { 1085 | this.coords.p_from_real = this.coords.p_to_real; 1086 | } 1087 | this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max); 1088 | this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from"); 1089 | this.coords.p_from_real = this.checkMaxInterval(this.coords.p_from_real, this.coords.p_to_real, "from"); 1090 | 1091 | this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real); 1092 | 1093 | break; 1094 | 1095 | case "to": 1096 | if (this.options.to_fixed) { 1097 | break; 1098 | } 1099 | 1100 | this.coords.p_to_real = this.convertToRealPercent(handle_x); 1101 | this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real); 1102 | if (this.coords.p_to_real < this.coords.p_from_real) { 1103 | this.coords.p_to_real = this.coords.p_from_real; 1104 | } 1105 | this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max); 1106 | this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to"); 1107 | this.coords.p_to_real = this.checkMaxInterval(this.coords.p_to_real, this.coords.p_from_real, "to"); 1108 | 1109 | this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real); 1110 | 1111 | break; 1112 | 1113 | case "both": 1114 | if (this.options.from_fixed || this.options.to_fixed) { 1115 | break; 1116 | } 1117 | 1118 | handle_x = this.toFixed(handle_x + (this.coords.p_handle * 0.001)); 1119 | 1120 | this.coords.p_from_real = this.convertToRealPercent(handle_x) - this.coords.p_gap_left; 1121 | this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real); 1122 | this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max); 1123 | this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from"); 1124 | this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real); 1125 | 1126 | this.coords.p_to_real = this.convertToRealPercent(handle_x) + this.coords.p_gap_right; 1127 | this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real); 1128 | this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max); 1129 | this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to"); 1130 | this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real); 1131 | 1132 | break; 1133 | 1134 | case "both_one": 1135 | if (this.options.from_fixed || this.options.to_fixed) { 1136 | break; 1137 | } 1138 | 1139 | var real_x = this.convertToRealPercent(handle_x), 1140 | from = this.result.from_percent, 1141 | to = this.result.to_percent, 1142 | full = to - from, 1143 | half = full / 2, 1144 | new_from = real_x - half, 1145 | new_to = real_x + half; 1146 | 1147 | if (new_from < 0) { 1148 | new_from = 0; 1149 | new_to = new_from + full; 1150 | } 1151 | 1152 | if (new_to > 100) { 1153 | new_to = 100; 1154 | new_from = new_to - full; 1155 | } 1156 | 1157 | this.coords.p_from_real = this.calcWithStep(new_from); 1158 | this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max); 1159 | this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real); 1160 | 1161 | this.coords.p_to_real = this.calcWithStep(new_to); 1162 | this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max); 1163 | this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real); 1164 | 1165 | break; 1166 | } 1167 | 1168 | if (this.options.type === "single") { 1169 | this.coords.p_bar_x = (this.coords.p_handle / 2); 1170 | this.coords.p_bar_w = this.coords.p_single_fake; 1171 | 1172 | this.result.from_percent = this.coords.p_single_real; 1173 | this.result.from = this.convertToValue(this.coords.p_single_real); 1174 | this.result.from_pretty = this._prettify(this.result.from); 1175 | 1176 | if (this.options.values.length) { 1177 | this.result.from_value = this.options.values[this.result.from]; 1178 | } 1179 | } else { 1180 | this.coords.p_bar_x = this.toFixed(this.coords.p_from_fake + (this.coords.p_handle / 2)); 1181 | this.coords.p_bar_w = this.toFixed(this.coords.p_to_fake - this.coords.p_from_fake); 1182 | 1183 | this.result.from_percent = this.coords.p_from_real; 1184 | this.result.from = this.convertToValue(this.coords.p_from_real); 1185 | this.result.from_pretty = this._prettify(this.result.from); 1186 | this.result.to_percent = this.coords.p_to_real; 1187 | this.result.to = this.convertToValue(this.coords.p_to_real); 1188 | this.result.to_pretty = this._prettify(this.result.to); 1189 | 1190 | if (this.options.values.length) { 1191 | this.result.from_value = this.options.values[this.result.from]; 1192 | this.result.to_value = this.options.values[this.result.to]; 1193 | } 1194 | } 1195 | 1196 | this.calcMinMax(); 1197 | this.calcLabels(); 1198 | }, 1199 | 1200 | 1201 | /** 1202 | * calculates pointer X in percent 1203 | */ 1204 | calcPointerPercent: function () { 1205 | if (!this.coords.w_rs) { 1206 | this.coords.p_pointer = 0; 1207 | return; 1208 | } 1209 | 1210 | if (this.coords.x_pointer < 0 || isNaN(this.coords.x_pointer) ) { 1211 | this.coords.x_pointer = 0; 1212 | } else if (this.coords.x_pointer > this.coords.w_rs) { 1213 | this.coords.x_pointer = this.coords.w_rs; 1214 | } 1215 | 1216 | this.coords.p_pointer = this.toFixed(this.coords.x_pointer / this.coords.w_rs * 100); 1217 | }, 1218 | 1219 | convertToRealPercent: function (fake) { 1220 | var full = 100 - this.coords.p_handle; 1221 | return fake / full * 100; 1222 | }, 1223 | 1224 | convertToFakePercent: function (real) { 1225 | var full = 100 - this.coords.p_handle; 1226 | return real / 100 * full; 1227 | }, 1228 | 1229 | getHandleX: function () { 1230 | var max = 100 - this.coords.p_handle, 1231 | x = this.toFixed(this.coords.p_pointer - this.coords.p_gap); 1232 | 1233 | if (x < 0) { 1234 | x = 0; 1235 | } else if (x > max) { 1236 | x = max; 1237 | } 1238 | 1239 | return x; 1240 | }, 1241 | 1242 | calcHandlePercent: function () { 1243 | if (this.options.type === "single") { 1244 | this.coords.w_handle = this.$cache.s_single.outerWidth(false); 1245 | } else { 1246 | this.coords.w_handle = this.$cache.s_from.outerWidth(false); 1247 | } 1248 | 1249 | this.coords.p_handle = this.toFixed(this.coords.w_handle / this.coords.w_rs * 100); 1250 | }, 1251 | 1252 | /** 1253 | * Find closest handle to pointer click 1254 | * 1255 | * @param real_x {Number} 1256 | * @returns {String} 1257 | */ 1258 | chooseHandle: function (real_x) { 1259 | if (this.options.type === "single") { 1260 | return "single"; 1261 | } else { 1262 | var m_point = this.coords.p_from_real + ((this.coords.p_to_real - this.coords.p_from_real) / 2); 1263 | if (real_x >= m_point) { 1264 | return this.options.to_fixed ? "from" : "to"; 1265 | } else { 1266 | return this.options.from_fixed ? "to" : "from"; 1267 | } 1268 | } 1269 | }, 1270 | 1271 | /** 1272 | * Measure Min and Max labels width in percent 1273 | */ 1274 | calcMinMax: function () { 1275 | if (!this.coords.w_rs) { 1276 | return; 1277 | } 1278 | 1279 | this.labels.p_min = this.labels.w_min / this.coords.w_rs * 100; 1280 | this.labels.p_max = this.labels.w_max / this.coords.w_rs * 100; 1281 | }, 1282 | 1283 | /** 1284 | * Measure labels width and X in percent 1285 | */ 1286 | calcLabels: function () { 1287 | if (!this.coords.w_rs || this.options.hide_from_to) { 1288 | return; 1289 | } 1290 | 1291 | if (this.options.type === "single") { 1292 | 1293 | this.labels.w_single = this.$cache.single.outerWidth(false); 1294 | this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100; 1295 | this.labels.p_single_left = this.coords.p_single_fake + (this.coords.p_handle / 2) - (this.labels.p_single_fake / 2); 1296 | this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake); 1297 | 1298 | } else { 1299 | 1300 | this.labels.w_from = this.$cache.from.outerWidth(false); 1301 | this.labels.p_from_fake = this.labels.w_from / this.coords.w_rs * 100; 1302 | this.labels.p_from_left = this.coords.p_from_fake + (this.coords.p_handle / 2) - (this.labels.p_from_fake / 2); 1303 | this.labels.p_from_left = this.toFixed(this.labels.p_from_left); 1304 | this.labels.p_from_left = this.checkEdges(this.labels.p_from_left, this.labels.p_from_fake); 1305 | 1306 | this.labels.w_to = this.$cache.to.outerWidth(false); 1307 | this.labels.p_to_fake = this.labels.w_to / this.coords.w_rs * 100; 1308 | this.labels.p_to_left = this.coords.p_to_fake + (this.coords.p_handle / 2) - (this.labels.p_to_fake / 2); 1309 | this.labels.p_to_left = this.toFixed(this.labels.p_to_left); 1310 | this.labels.p_to_left = this.checkEdges(this.labels.p_to_left, this.labels.p_to_fake); 1311 | 1312 | this.labels.w_single = this.$cache.single.outerWidth(false); 1313 | this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100; 1314 | this.labels.p_single_left = ((this.labels.p_from_left + this.labels.p_to_left + this.labels.p_to_fake) / 2) - (this.labels.p_single_fake / 2); 1315 | this.labels.p_single_left = this.toFixed(this.labels.p_single_left); 1316 | this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake); 1317 | 1318 | } 1319 | }, 1320 | 1321 | 1322 | 1323 | // ============================================================================================================= 1324 | // Drawings 1325 | 1326 | /** 1327 | * Main function called in request animation frame 1328 | * to update everything 1329 | */ 1330 | updateScene: function () { 1331 | if (this.raf_id) { 1332 | cancelAnimationFrame(this.raf_id); 1333 | this.raf_id = null; 1334 | } 1335 | 1336 | clearTimeout(this.update_tm); 1337 | this.update_tm = null; 1338 | 1339 | if (!this.options) { 1340 | return; 1341 | } 1342 | 1343 | this.drawHandles(); 1344 | 1345 | if (this.is_active) { 1346 | this.raf_id = requestAnimationFrame(this.updateScene.bind(this)); 1347 | } else { 1348 | this.update_tm = setTimeout(this.updateScene.bind(this), 300); 1349 | } 1350 | }, 1351 | 1352 | /** 1353 | * Draw handles 1354 | */ 1355 | drawHandles: function () { 1356 | this.coords.w_rs = this.$cache.rs.outerWidth(false); 1357 | 1358 | if (!this.coords.w_rs) { 1359 | return; 1360 | } 1361 | 1362 | if (this.coords.w_rs !== this.coords.w_rs_old) { 1363 | this.target = "base"; 1364 | this.is_resize = true; 1365 | } 1366 | 1367 | if (this.coords.w_rs !== this.coords.w_rs_old || this.force_redraw) { 1368 | this.setMinMax(); 1369 | this.calc(true); 1370 | this.drawLabels(); 1371 | if (this.options.grid) { 1372 | this.calcGridMargin(); 1373 | this.calcGridLabels(); 1374 | } 1375 | this.force_redraw = true; 1376 | this.coords.w_rs_old = this.coords.w_rs; 1377 | this.drawShadow(); 1378 | } 1379 | 1380 | if (!this.coords.w_rs) { 1381 | return; 1382 | } 1383 | 1384 | if (!this.dragging && !this.force_redraw && !this.is_key) { 1385 | return; 1386 | } 1387 | 1388 | if (this.old_from !== this.result.from || this.old_to !== this.result.to || this.force_redraw || this.is_key) { 1389 | 1390 | this.drawLabels(); 1391 | 1392 | this.$cache.bar[0].style.left = this.coords.p_bar_x + "%"; 1393 | this.$cache.bar[0].style.width = this.coords.p_bar_w + "%"; 1394 | 1395 | if (this.options.type === "single") { 1396 | this.$cache.bar[0].style.left = 0; 1397 | this.$cache.bar[0].style.width = this.coords.p_bar_w + this.coords.p_bar_x + "%"; 1398 | 1399 | this.$cache.s_single[0].style.left = this.coords.p_single_fake + "%"; 1400 | 1401 | this.$cache.single[0].style.left = this.labels.p_single_left + "%"; 1402 | } else { 1403 | this.$cache.s_from[0].style.left = this.coords.p_from_fake + "%"; 1404 | this.$cache.s_to[0].style.left = this.coords.p_to_fake + "%"; 1405 | 1406 | if (this.old_from !== this.result.from || this.force_redraw) { 1407 | this.$cache.from[0].style.left = this.labels.p_from_left + "%"; 1408 | } 1409 | if (this.old_to !== this.result.to || this.force_redraw) { 1410 | this.$cache.to[0].style.left = this.labels.p_to_left + "%"; 1411 | } 1412 | 1413 | this.$cache.single[0].style.left = this.labels.p_single_left + "%"; 1414 | } 1415 | 1416 | this.writeToInput(); 1417 | 1418 | if ((this.old_from !== this.result.from || this.old_to !== this.result.to) && !this.is_start) { 1419 | this.$cache.input.trigger("change"); 1420 | this.$cache.input.trigger("input"); 1421 | } 1422 | 1423 | this.old_from = this.result.from; 1424 | this.old_to = this.result.to; 1425 | 1426 | // callbacks call 1427 | if (!this.is_resize && !this.is_update && !this.is_start && !this.is_finish) { 1428 | this.callOnChange(); 1429 | } 1430 | if (this.is_key || this.is_click) { 1431 | this.is_key = false; 1432 | this.is_click = false; 1433 | this.callOnFinish(); 1434 | } 1435 | 1436 | this.is_update = false; 1437 | this.is_resize = false; 1438 | this.is_finish = false; 1439 | } 1440 | 1441 | this.is_start = false; 1442 | this.is_key = false; 1443 | this.is_click = false; 1444 | this.force_redraw = false; 1445 | }, 1446 | 1447 | /** 1448 | * Draw labels 1449 | * measure labels collisions 1450 | * collapse close labels 1451 | */ 1452 | drawLabels: function () { 1453 | if (!this.options) { 1454 | return; 1455 | } 1456 | 1457 | var values_num = this.options.values.length; 1458 | var p_values = this.options.p_values; 1459 | var text_single; 1460 | var text_from; 1461 | var text_to; 1462 | var from_pretty; 1463 | var to_pretty; 1464 | 1465 | if (this.options.hide_from_to) { 1466 | return; 1467 | } 1468 | 1469 | if (this.options.type === "single") { 1470 | 1471 | if (values_num) { 1472 | text_single = this.decorate(p_values[this.result.from]); 1473 | this.$cache.single.html(text_single); 1474 | } else { 1475 | from_pretty = this._prettify(this.result.from); 1476 | 1477 | text_single = this.decorate(from_pretty, this.result.from); 1478 | this.$cache.single.html(text_single); 1479 | } 1480 | 1481 | this.calcLabels(); 1482 | 1483 | if (this.labels.p_single_left < this.labels.p_min + 1) { 1484 | this.$cache.min[0].style.visibility = "hidden"; 1485 | } else { 1486 | this.$cache.min[0].style.visibility = "visible"; 1487 | } 1488 | 1489 | if (this.labels.p_single_left + this.labels.p_single_fake > 100 - this.labels.p_max - 1) { 1490 | this.$cache.max[0].style.visibility = "hidden"; 1491 | } else { 1492 | this.$cache.max[0].style.visibility = "visible"; 1493 | } 1494 | 1495 | } else { 1496 | 1497 | if (values_num) { 1498 | 1499 | if (this.options.decorate_both) { 1500 | text_single = this.decorate(p_values[this.result.from]); 1501 | text_single += this.options.values_separator; 1502 | text_single += this.decorate(p_values[this.result.to]); 1503 | } else { 1504 | text_single = this.decorate(p_values[this.result.from] + this.options.values_separator + p_values[this.result.to]); 1505 | } 1506 | text_from = this.decorate(p_values[this.result.from]); 1507 | text_to = this.decorate(p_values[this.result.to]); 1508 | 1509 | this.$cache.single.html(text_single); 1510 | this.$cache.from.html(text_from); 1511 | this.$cache.to.html(text_to); 1512 | 1513 | } else { 1514 | from_pretty = this._prettify(this.result.from); 1515 | to_pretty = this._prettify(this.result.to); 1516 | 1517 | if (this.options.decorate_both) { 1518 | text_single = this.decorate(from_pretty, this.result.from); 1519 | text_single += this.options.values_separator; 1520 | text_single += this.decorate(to_pretty, this.result.to); 1521 | } else { 1522 | text_single = this.decorate(from_pretty + this.options.values_separator + to_pretty, this.result.to); 1523 | } 1524 | text_from = this.decorate(from_pretty, this.result.from); 1525 | text_to = this.decorate(to_pretty, this.result.to); 1526 | 1527 | this.$cache.single.html(text_single); 1528 | this.$cache.from.html(text_from); 1529 | this.$cache.to.html(text_to); 1530 | 1531 | } 1532 | 1533 | this.calcLabels(); 1534 | 1535 | var min = Math.min(this.labels.p_single_left, this.labels.p_from_left), 1536 | single_left = this.labels.p_single_left + this.labels.p_single_fake, 1537 | to_left = this.labels.p_to_left + this.labels.p_to_fake, 1538 | max = Math.max(single_left, to_left); 1539 | 1540 | if (this.labels.p_from_left + this.labels.p_from_fake >= this.labels.p_to_left) { 1541 | this.$cache.from[0].style.visibility = "hidden"; 1542 | this.$cache.to[0].style.visibility = "hidden"; 1543 | this.$cache.single[0].style.visibility = "visible"; 1544 | 1545 | if (this.result.from === this.result.to) { 1546 | if (this.target === "from") { 1547 | this.$cache.from[0].style.visibility = "visible"; 1548 | } else if (this.target === "to") { 1549 | this.$cache.to[0].style.visibility = "visible"; 1550 | } else if (!this.target) { 1551 | this.$cache.from[0].style.visibility = "visible"; 1552 | } 1553 | this.$cache.single[0].style.visibility = "hidden"; 1554 | max = to_left; 1555 | } else { 1556 | this.$cache.from[0].style.visibility = "hidden"; 1557 | this.$cache.to[0].style.visibility = "hidden"; 1558 | this.$cache.single[0].style.visibility = "visible"; 1559 | max = Math.max(single_left, to_left); 1560 | } 1561 | } else { 1562 | this.$cache.from[0].style.visibility = "visible"; 1563 | this.$cache.to[0].style.visibility = "visible"; 1564 | this.$cache.single[0].style.visibility = "hidden"; 1565 | } 1566 | 1567 | if (min < this.labels.p_min + 1) { 1568 | this.$cache.min[0].style.visibility = "hidden"; 1569 | } else { 1570 | this.$cache.min[0].style.visibility = "visible"; 1571 | } 1572 | 1573 | if (max > 100 - this.labels.p_max - 1) { 1574 | this.$cache.max[0].style.visibility = "hidden"; 1575 | } else { 1576 | this.$cache.max[0].style.visibility = "visible"; 1577 | } 1578 | 1579 | } 1580 | }, 1581 | 1582 | /** 1583 | * Draw shadow intervals 1584 | */ 1585 | drawShadow: function () { 1586 | var o = this.options, 1587 | c = this.$cache, 1588 | 1589 | is_from_min = typeof o.from_min === "number" && !isNaN(o.from_min), 1590 | is_from_max = typeof o.from_max === "number" && !isNaN(o.from_max), 1591 | is_to_min = typeof o.to_min === "number" && !isNaN(o.to_min), 1592 | is_to_max = typeof o.to_max === "number" && !isNaN(o.to_max), 1593 | 1594 | from_min, 1595 | from_max, 1596 | to_min, 1597 | to_max; 1598 | 1599 | if (o.type === "single") { 1600 | if (o.from_shadow && (is_from_min || is_from_max)) { 1601 | from_min = this.convertToPercent(is_from_min ? o.from_min : o.min); 1602 | from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min; 1603 | from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min)); 1604 | from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max)); 1605 | from_min = from_min + (this.coords.p_handle / 2); 1606 | 1607 | c.shad_single[0].style.display = "block"; 1608 | c.shad_single[0].style.left = from_min + "%"; 1609 | c.shad_single[0].style.width = from_max + "%"; 1610 | } else { 1611 | c.shad_single[0].style.display = "none"; 1612 | } 1613 | } else { 1614 | if (o.from_shadow && (is_from_min || is_from_max)) { 1615 | from_min = this.convertToPercent(is_from_min ? o.from_min : o.min); 1616 | from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min; 1617 | from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min)); 1618 | from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max)); 1619 | from_min = from_min + (this.coords.p_handle / 2); 1620 | 1621 | c.shad_from[0].style.display = "block"; 1622 | c.shad_from[0].style.left = from_min + "%"; 1623 | c.shad_from[0].style.width = from_max + "%"; 1624 | } else { 1625 | c.shad_from[0].style.display = "none"; 1626 | } 1627 | 1628 | if (o.to_shadow && (is_to_min || is_to_max)) { 1629 | to_min = this.convertToPercent(is_to_min ? o.to_min : o.min); 1630 | to_max = this.convertToPercent(is_to_max ? o.to_max : o.max) - to_min; 1631 | to_min = this.toFixed(to_min - (this.coords.p_handle / 100 * to_min)); 1632 | to_max = this.toFixed(to_max - (this.coords.p_handle / 100 * to_max)); 1633 | to_min = to_min + (this.coords.p_handle / 2); 1634 | 1635 | c.shad_to[0].style.display = "block"; 1636 | c.shad_to[0].style.left = to_min + "%"; 1637 | c.shad_to[0].style.width = to_max + "%"; 1638 | } else { 1639 | c.shad_to[0].style.display = "none"; 1640 | } 1641 | } 1642 | }, 1643 | 1644 | 1645 | 1646 | /** 1647 | * Write values to input element 1648 | */ 1649 | writeToInput: function () { 1650 | if (this.options.type === "single") { 1651 | if (this.options.values.length) { 1652 | this.$cache.input.prop("value", this.result.from_value); 1653 | } else { 1654 | this.$cache.input.prop("value", this.result.from); 1655 | } 1656 | this.$cache.input.data("from", this.result.from); 1657 | } else { 1658 | if (this.options.values.length) { 1659 | this.$cache.input.prop("value", this.result.from_value + this.options.input_values_separator + this.result.to_value); 1660 | } else { 1661 | this.$cache.input.prop("value", this.result.from + this.options.input_values_separator + this.result.to); 1662 | } 1663 | this.$cache.input.data("from", this.result.from); 1664 | this.$cache.input.data("to", this.result.to); 1665 | } 1666 | }, 1667 | 1668 | 1669 | 1670 | // ============================================================================================================= 1671 | // Callbacks 1672 | 1673 | callOnStart: function () { 1674 | this.writeToInput(); 1675 | 1676 | if (this.options.onStart && typeof this.options.onStart === "function") { 1677 | if (this.options.scope) { 1678 | this.options.onStart.call(this.options.scope, this.result); 1679 | } else { 1680 | this.options.onStart(this.result); 1681 | } 1682 | } 1683 | }, 1684 | callOnChange: function () { 1685 | this.writeToInput(); 1686 | 1687 | if (this.options.onChange && typeof this.options.onChange === "function") { 1688 | if (this.options.scope) { 1689 | this.options.onChange.call(this.options.scope, this.result); 1690 | } else { 1691 | this.options.onChange(this.result); 1692 | } 1693 | } 1694 | }, 1695 | callOnFinish: function () { 1696 | this.writeToInput(); 1697 | 1698 | if (this.options.onFinish && typeof this.options.onFinish === "function") { 1699 | if (this.options.scope) { 1700 | this.options.onFinish.call(this.options.scope, this.result); 1701 | } else { 1702 | this.options.onFinish(this.result); 1703 | } 1704 | } 1705 | }, 1706 | callOnUpdate: function () { 1707 | this.writeToInput(); 1708 | 1709 | if (this.options.onUpdate && typeof this.options.onUpdate === "function") { 1710 | if (this.options.scope) { 1711 | this.options.onUpdate.call(this.options.scope, this.result); 1712 | } else { 1713 | this.options.onUpdate(this.result); 1714 | } 1715 | } 1716 | }, 1717 | 1718 | 1719 | 1720 | 1721 | // ============================================================================================================= 1722 | // Service methods 1723 | 1724 | toggleInput: function () { 1725 | this.$cache.input.toggleClass("irs-hidden-input"); 1726 | 1727 | if (this.has_tab_index) { 1728 | this.$cache.input.prop("tabindex", -1); 1729 | } else { 1730 | this.$cache.input.removeProp("tabindex"); 1731 | } 1732 | 1733 | this.has_tab_index = !this.has_tab_index; 1734 | }, 1735 | 1736 | /** 1737 | * Convert real value to percent 1738 | * 1739 | * @param value {Number} X in real 1740 | * @param no_min {boolean=} don't use min value 1741 | * @returns {Number} X in percent 1742 | */ 1743 | convertToPercent: function (value, no_min) { 1744 | var diapason = this.options.max - this.options.min, 1745 | one_percent = diapason / 100, 1746 | val, percent; 1747 | 1748 | if (!diapason) { 1749 | this.no_diapason = true; 1750 | return 0; 1751 | } 1752 | 1753 | if (no_min) { 1754 | val = value; 1755 | } else { 1756 | val = value - this.options.min; 1757 | } 1758 | 1759 | percent = val / one_percent; 1760 | 1761 | return this.toFixed(percent); 1762 | }, 1763 | 1764 | /** 1765 | * Convert percent to real values 1766 | * 1767 | * @param percent {Number} X in percent 1768 | * @returns {Number} X in real 1769 | */ 1770 | convertToValue: function (percent) { 1771 | var min = this.options.min, 1772 | max = this.options.max, 1773 | min_decimals = min.toString().split(".")[1], 1774 | max_decimals = max.toString().split(".")[1], 1775 | min_length, max_length, 1776 | avg_decimals = 0, 1777 | abs = 0; 1778 | 1779 | if (percent === 0) { 1780 | return this.options.min; 1781 | } 1782 | if (percent === 100) { 1783 | return this.options.max; 1784 | } 1785 | 1786 | 1787 | if (min_decimals) { 1788 | min_length = min_decimals.length; 1789 | avg_decimals = min_length; 1790 | } 1791 | if (max_decimals) { 1792 | max_length = max_decimals.length; 1793 | avg_decimals = max_length; 1794 | } 1795 | if (min_length && max_length) { 1796 | avg_decimals = (min_length >= max_length) ? min_length : max_length; 1797 | } 1798 | 1799 | if (min < 0) { 1800 | abs = Math.abs(min); 1801 | min = +(min + abs).toFixed(avg_decimals); 1802 | max = +(max + abs).toFixed(avg_decimals); 1803 | } 1804 | 1805 | var number = ((max - min) / 100 * percent) + min, 1806 | string = this.options.step.toString().split(".")[1], 1807 | result; 1808 | 1809 | if (string) { 1810 | number = +number.toFixed(string.length); 1811 | } else { 1812 | number = number / this.options.step; 1813 | number = number * this.options.step; 1814 | 1815 | number = +number.toFixed(0); 1816 | } 1817 | 1818 | if (abs) { 1819 | number -= abs; 1820 | } 1821 | 1822 | if (string) { 1823 | result = +number.toFixed(string.length); 1824 | } else { 1825 | result = this.toFixed(number); 1826 | } 1827 | 1828 | if (result < this.options.min) { 1829 | result = this.options.min; 1830 | } else if (result > this.options.max) { 1831 | result = this.options.max; 1832 | } 1833 | 1834 | return result; 1835 | }, 1836 | 1837 | /** 1838 | * Round percent value with step 1839 | * 1840 | * @param percent {Number} 1841 | * @returns percent {Number} rounded 1842 | */ 1843 | calcWithStep: function (percent) { 1844 | var rounded = Math.round(percent / this.coords.p_step) * this.coords.p_step; 1845 | 1846 | if (rounded > 100) { 1847 | rounded = 100; 1848 | } 1849 | if (percent === 100) { 1850 | rounded = 100; 1851 | } 1852 | 1853 | return this.toFixed(rounded); 1854 | }, 1855 | 1856 | checkMinInterval: function (p_current, p_next, type) { 1857 | var o = this.options, 1858 | current, 1859 | next; 1860 | 1861 | if (!o.min_interval) { 1862 | return p_current; 1863 | } 1864 | 1865 | current = this.convertToValue(p_current); 1866 | next = this.convertToValue(p_next); 1867 | 1868 | if (type === "from") { 1869 | 1870 | if (next - current < o.min_interval) { 1871 | current = next - o.min_interval; 1872 | } 1873 | 1874 | } else { 1875 | 1876 | if (current - next < o.min_interval) { 1877 | current = next + o.min_interval; 1878 | } 1879 | 1880 | } 1881 | 1882 | return this.convertToPercent(current); 1883 | }, 1884 | 1885 | checkMaxInterval: function (p_current, p_next, type) { 1886 | var o = this.options, 1887 | current, 1888 | next; 1889 | 1890 | if (!o.max_interval) { 1891 | return p_current; 1892 | } 1893 | 1894 | current = this.convertToValue(p_current); 1895 | next = this.convertToValue(p_next); 1896 | 1897 | if (type === "from") { 1898 | 1899 | if (next - current > o.max_interval) { 1900 | current = next - o.max_interval; 1901 | } 1902 | 1903 | } else { 1904 | 1905 | if (current - next > o.max_interval) { 1906 | current = next + o.max_interval; 1907 | } 1908 | 1909 | } 1910 | 1911 | return this.convertToPercent(current); 1912 | }, 1913 | 1914 | checkDiapason: function (p_num, min, max) { 1915 | var num = this.convertToValue(p_num), 1916 | o = this.options; 1917 | 1918 | if (typeof min !== "number") { 1919 | min = o.min; 1920 | } 1921 | 1922 | if (typeof max !== "number") { 1923 | max = o.max; 1924 | } 1925 | 1926 | if (num < min) { 1927 | num = min; 1928 | } 1929 | 1930 | if (num > max) { 1931 | num = max; 1932 | } 1933 | 1934 | return this.convertToPercent(num); 1935 | }, 1936 | 1937 | toFixed: function (num) { 1938 | num = num.toFixed(20); 1939 | return +num; 1940 | }, 1941 | 1942 | _prettify: function (num) { 1943 | if (!this.options.prettify_enabled) { 1944 | return num; 1945 | } 1946 | 1947 | if (this.options.prettify && typeof this.options.prettify === "function") { 1948 | return this.options.prettify(num); 1949 | } else { 1950 | return this.prettify(num); 1951 | } 1952 | }, 1953 | 1954 | prettify: function (num) { 1955 | var n = num.toString(); 1956 | return n.replace(/(\d{1,3}(?=(?:\d\d\d)+(?!\d)))/g, "$1" + this.options.prettify_separator); 1957 | }, 1958 | 1959 | checkEdges: function (left, width) { 1960 | if (!this.options.force_edges) { 1961 | return this.toFixed(left); 1962 | } 1963 | 1964 | if (left < 0) { 1965 | left = 0; 1966 | } else if (left > 100 - width) { 1967 | left = 100 - width; 1968 | } 1969 | 1970 | return this.toFixed(left); 1971 | }, 1972 | 1973 | validate: function () { 1974 | var o = this.options, 1975 | r = this.result, 1976 | v = o.values, 1977 | vl = v.length, 1978 | value, 1979 | i; 1980 | 1981 | if (typeof o.min === "string") o.min = +o.min; 1982 | if (typeof o.max === "string") o.max = +o.max; 1983 | if (typeof o.from === "string") o.from = +o.from; 1984 | if (typeof o.to === "string") o.to = +o.to; 1985 | if (typeof o.step === "string") o.step = +o.step; 1986 | 1987 | if (typeof o.from_min === "string") o.from_min = +o.from_min; 1988 | if (typeof o.from_max === "string") o.from_max = +o.from_max; 1989 | if (typeof o.to_min === "string") o.to_min = +o.to_min; 1990 | if (typeof o.to_max === "string") o.to_max = +o.to_max; 1991 | 1992 | if (typeof o.grid_num === "string") o.grid_num = +o.grid_num; 1993 | 1994 | if (o.max < o.min) { 1995 | o.max = o.min; 1996 | } 1997 | 1998 | if (vl) { 1999 | o.p_values = []; 2000 | o.min = 0; 2001 | o.max = vl - 1; 2002 | o.step = 1; 2003 | o.grid_num = o.max; 2004 | o.grid_snap = true; 2005 | 2006 | for (i = 0; i < vl; i++) { 2007 | value = +v[i]; 2008 | 2009 | if (!isNaN(value)) { 2010 | v[i] = value; 2011 | value = this._prettify(value); 2012 | } else { 2013 | value = v[i]; 2014 | } 2015 | 2016 | o.p_values.push(value); 2017 | } 2018 | } 2019 | 2020 | if (typeof o.from !== "number" || isNaN(o.from)) { 2021 | o.from = o.min; 2022 | } 2023 | 2024 | if (typeof o.to !== "number" || isNaN(o.to)) { 2025 | o.to = o.max; 2026 | } 2027 | 2028 | if (o.type === "single") { 2029 | 2030 | if (o.from < o.min) o.from = o.min; 2031 | if (o.from > o.max) o.from = o.max; 2032 | 2033 | } else { 2034 | 2035 | if (o.from < o.min) o.from = o.min; 2036 | if (o.from > o.max) o.from = o.max; 2037 | 2038 | if (o.to < o.min) o.to = o.min; 2039 | if (o.to > o.max) o.to = o.max; 2040 | 2041 | if (this.update_check.from) { 2042 | 2043 | if (this.update_check.from !== o.from) { 2044 | if (o.from > o.to) o.from = o.to; 2045 | } 2046 | if (this.update_check.to !== o.to) { 2047 | if (o.to < o.from) o.to = o.from; 2048 | } 2049 | 2050 | } 2051 | 2052 | if (o.from > o.to) o.from = o.to; 2053 | if (o.to < o.from) o.to = o.from; 2054 | 2055 | } 2056 | 2057 | if (typeof o.step !== "number" || isNaN(o.step) || !o.step || o.step < 0) { 2058 | o.step = 1; 2059 | } 2060 | 2061 | if (typeof o.from_min === "number" && o.from < o.from_min) { 2062 | o.from = o.from_min; 2063 | } 2064 | 2065 | if (typeof o.from_max === "number" && o.from > o.from_max) { 2066 | o.from = o.from_max; 2067 | } 2068 | 2069 | if (typeof o.to_min === "number" && o.to < o.to_min) { 2070 | o.to = o.to_min; 2071 | } 2072 | 2073 | if (typeof o.to_max === "number" && o.from > o.to_max) { 2074 | o.to = o.to_max; 2075 | } 2076 | 2077 | if (r) { 2078 | if (r.min !== o.min) { 2079 | r.min = o.min; 2080 | } 2081 | 2082 | if (r.max !== o.max) { 2083 | r.max = o.max; 2084 | } 2085 | 2086 | if (r.from < r.min || r.from > r.max) { 2087 | r.from = o.from; 2088 | } 2089 | 2090 | if (r.to < r.min || r.to > r.max) { 2091 | r.to = o.to; 2092 | } 2093 | } 2094 | 2095 | if (typeof o.min_interval !== "number" || isNaN(o.min_interval) || !o.min_interval || o.min_interval < 0) { 2096 | o.min_interval = 0; 2097 | } 2098 | 2099 | if (typeof o.max_interval !== "number" || isNaN(o.max_interval) || !o.max_interval || o.max_interval < 0) { 2100 | o.max_interval = 0; 2101 | } 2102 | 2103 | if (o.min_interval && o.min_interval > o.max - o.min) { 2104 | o.min_interval = o.max - o.min; 2105 | } 2106 | 2107 | if (o.max_interval && o.max_interval > o.max - o.min) { 2108 | o.max_interval = o.max - o.min; 2109 | } 2110 | }, 2111 | 2112 | decorate: function (num, original) { 2113 | var decorated = "", 2114 | o = this.options; 2115 | 2116 | if (o.prefix) { 2117 | decorated += o.prefix; 2118 | } 2119 | 2120 | decorated += num; 2121 | 2122 | if (o.max_postfix) { 2123 | if (o.values.length && num === o.p_values[o.max]) { 2124 | decorated += o.max_postfix; 2125 | if (o.postfix) { 2126 | decorated += " "; 2127 | } 2128 | } else if (original === o.max) { 2129 | decorated += o.max_postfix; 2130 | if (o.postfix) { 2131 | decorated += " "; 2132 | } 2133 | } 2134 | } 2135 | 2136 | if (o.postfix) { 2137 | decorated += o.postfix; 2138 | } 2139 | 2140 | return decorated; 2141 | }, 2142 | 2143 | updateFrom: function () { 2144 | this.result.from = this.options.from; 2145 | this.result.from_percent = this.convertToPercent(this.result.from); 2146 | this.result.from_pretty = this._prettify(this.result.from); 2147 | if (this.options.values) { 2148 | this.result.from_value = this.options.values[this.result.from]; 2149 | } 2150 | }, 2151 | 2152 | updateTo: function () { 2153 | this.result.to = this.options.to; 2154 | this.result.to_percent = this.convertToPercent(this.result.to); 2155 | this.result.to_pretty = this._prettify(this.result.to); 2156 | if (this.options.values) { 2157 | this.result.to_value = this.options.values[this.result.to]; 2158 | } 2159 | }, 2160 | 2161 | updateResult: function () { 2162 | this.result.min = this.options.min; 2163 | this.result.max = this.options.max; 2164 | this.updateFrom(); 2165 | this.updateTo(); 2166 | }, 2167 | 2168 | 2169 | // ============================================================================================================= 2170 | // Grid 2171 | 2172 | appendGrid: function () { 2173 | if (!this.options.grid) { 2174 | return; 2175 | } 2176 | 2177 | var o = this.options, 2178 | i, z, 2179 | 2180 | total = o.max - o.min, 2181 | big_num = o.grid_num, 2182 | big_p = 0, 2183 | big_w = 0, 2184 | 2185 | small_max = 4, 2186 | local_small_max, 2187 | small_p, 2188 | small_w = 0, 2189 | 2190 | result, 2191 | html = ''; 2192 | 2193 | 2194 | 2195 | this.calcGridMargin(); 2196 | 2197 | if (o.grid_snap) { 2198 | big_num = total / o.step; 2199 | } 2200 | 2201 | if (big_num > 50) big_num = 50; 2202 | big_p = this.toFixed(100 / big_num); 2203 | 2204 | if (big_num > 4) { 2205 | small_max = 3; 2206 | } 2207 | if (big_num > 7) { 2208 | small_max = 2; 2209 | } 2210 | if (big_num > 14) { 2211 | small_max = 1; 2212 | } 2213 | if (big_num > 28) { 2214 | small_max = 0; 2215 | } 2216 | 2217 | for (i = 0; i < big_num + 1; i++) { 2218 | local_small_max = small_max; 2219 | 2220 | big_w = this.toFixed(big_p * i); 2221 | 2222 | if (big_w > 100) { 2223 | big_w = 100; 2224 | } 2225 | this.coords.big[i] = big_w; 2226 | 2227 | small_p = (big_w - (big_p * (i - 1))) / (local_small_max + 1); 2228 | 2229 | for (z = 1; z <= local_small_max; z++) { 2230 | if (big_w === 0) { 2231 | break; 2232 | } 2233 | 2234 | small_w = this.toFixed(big_w - (small_p * z)); 2235 | 2236 | html += ''; 2237 | } 2238 | 2239 | html += ''; 2240 | 2241 | result = this.convertToValue(big_w); 2242 | if (o.values.length) { 2243 | result = o.p_values[result]; 2244 | } else { 2245 | result = this._prettify(result); 2246 | } 2247 | 2248 | html += '' + result + ''; 2249 | } 2250 | this.coords.big_num = Math.ceil(big_num + 1); 2251 | 2252 | 2253 | 2254 | this.$cache.cont.addClass("irs-with-grid"); 2255 | this.$cache.grid.html(html); 2256 | this.cacheGridLabels(); 2257 | }, 2258 | 2259 | cacheGridLabels: function () { 2260 | var $label, i, 2261 | num = this.coords.big_num; 2262 | 2263 | for (i = 0; i < num; i++) { 2264 | $label = this.$cache.grid.find(".js-grid-text-" + i); 2265 | this.$cache.grid_labels.push($label); 2266 | } 2267 | 2268 | this.calcGridLabels(); 2269 | }, 2270 | 2271 | calcGridLabels: function () { 2272 | var i, label, start = [], finish = [], 2273 | num = this.coords.big_num; 2274 | 2275 | for (i = 0; i < num; i++) { 2276 | this.coords.big_w[i] = this.$cache.grid_labels[i].outerWidth(false); 2277 | this.coords.big_p[i] = this.toFixed(this.coords.big_w[i] / this.coords.w_rs * 100); 2278 | this.coords.big_x[i] = this.toFixed(this.coords.big_p[i] / 2); 2279 | 2280 | start[i] = this.toFixed(this.coords.big[i] - this.coords.big_x[i]); 2281 | finish[i] = this.toFixed(start[i] + this.coords.big_p[i]); 2282 | } 2283 | 2284 | if (this.options.force_edges) { 2285 | if (start[0] < -this.coords.grid_gap) { 2286 | start[0] = -this.coords.grid_gap; 2287 | finish[0] = this.toFixed(start[0] + this.coords.big_p[0]); 2288 | 2289 | this.coords.big_x[0] = this.coords.grid_gap; 2290 | } 2291 | 2292 | if (finish[num - 1] > 100 + this.coords.grid_gap) { 2293 | finish[num - 1] = 100 + this.coords.grid_gap; 2294 | start[num - 1] = this.toFixed(finish[num - 1] - this.coords.big_p[num - 1]); 2295 | 2296 | this.coords.big_x[num - 1] = this.toFixed(this.coords.big_p[num - 1] - this.coords.grid_gap); 2297 | } 2298 | } 2299 | 2300 | this.calcGridCollision(2, start, finish); 2301 | this.calcGridCollision(4, start, finish); 2302 | 2303 | for (i = 0; i < num; i++) { 2304 | label = this.$cache.grid_labels[i][0]; 2305 | 2306 | if (this.coords.big_x[i] !== Number.POSITIVE_INFINITY) { 2307 | label.style.marginLeft = -this.coords.big_x[i] + "%"; 2308 | } 2309 | } 2310 | }, 2311 | 2312 | // Collisions Calc Beta 2313 | // TODO: Refactor then have plenty of time 2314 | calcGridCollision: function (step, start, finish) { 2315 | var i, next_i, label, 2316 | num = this.coords.big_num; 2317 | 2318 | for (i = 0; i < num; i += step) { 2319 | next_i = i + (step / 2); 2320 | if (next_i >= num) { 2321 | break; 2322 | } 2323 | 2324 | label = this.$cache.grid_labels[next_i][0]; 2325 | 2326 | if (finish[i] <= start[next_i]) { 2327 | label.style.visibility = "visible"; 2328 | } else { 2329 | label.style.visibility = "hidden"; 2330 | } 2331 | } 2332 | }, 2333 | 2334 | calcGridMargin: function () { 2335 | if (!this.options.grid_margin) { 2336 | return; 2337 | } 2338 | 2339 | this.coords.w_rs = this.$cache.rs.outerWidth(false); 2340 | if (!this.coords.w_rs) { 2341 | return; 2342 | } 2343 | 2344 | if (this.options.type === "single") { 2345 | this.coords.w_handle = this.$cache.s_single.outerWidth(false); 2346 | } else { 2347 | this.coords.w_handle = this.$cache.s_from.outerWidth(false); 2348 | } 2349 | this.coords.p_handle = this.toFixed(this.coords.w_handle / this.coords.w_rs * 100); 2350 | this.coords.grid_gap = this.toFixed((this.coords.p_handle / 2) - 0.1); 2351 | 2352 | this.$cache.grid[0].style.width = this.toFixed(100 - this.coords.p_handle) + "%"; 2353 | this.$cache.grid[0].style.left = this.coords.grid_gap + "%"; 2354 | }, 2355 | 2356 | 2357 | 2358 | // ============================================================================================================= 2359 | // Public methods 2360 | 2361 | update: function (options) { 2362 | if (!this.input) { 2363 | return; 2364 | } 2365 | 2366 | this.is_update = true; 2367 | 2368 | this.options.from = this.result.from; 2369 | this.options.to = this.result.to; 2370 | this.update_check.from = this.result.from; 2371 | this.update_check.to = this.result.to; 2372 | 2373 | this.options = $.extend(this.options, options); 2374 | this.validate(); 2375 | this.updateResult(options); 2376 | 2377 | this.toggleInput(); 2378 | this.remove(); 2379 | this.init(true); 2380 | }, 2381 | 2382 | reset: function () { 2383 | if (!this.input) { 2384 | return; 2385 | } 2386 | 2387 | this.updateResult(); 2388 | this.update(); 2389 | }, 2390 | 2391 | destroy: function () { 2392 | if (!this.input) { 2393 | return; 2394 | } 2395 | 2396 | this.toggleInput(); 2397 | this.$cache.input.prop("readonly", false); 2398 | $.data(this.input, "ionRangeSlider", null); 2399 | 2400 | this.remove(); 2401 | this.input = null; 2402 | this.options = null; 2403 | } 2404 | }; 2405 | 2406 | $.fn.ionRangeSlider = function (options) { 2407 | return this.each(function() { 2408 | if (!$.data(this, "ionRangeSlider")) { 2409 | $.data(this, "ionRangeSlider", new IonRangeSlider(this, options, plugin_count++)); 2410 | } 2411 | }); 2412 | }; 2413 | 2414 | 2415 | 2416 | // ================================================================================================================= 2417 | // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 2418 | // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating 2419 | 2420 | // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel 2421 | 2422 | // MIT license 2423 | 2424 | (function() { 2425 | var lastTime = 0; 2426 | var vendors = ['ms', 'moz', 'webkit', 'o']; 2427 | for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 2428 | window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 2429 | window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 2430 | || window[vendors[x]+'CancelRequestAnimationFrame']; 2431 | } 2432 | 2433 | if (!window.requestAnimationFrame) 2434 | window.requestAnimationFrame = function(callback, element) { 2435 | var currTime = new Date().getTime(); 2436 | var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 2437 | var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 2438 | timeToCall); 2439 | lastTime = currTime + timeToCall; 2440 | return id; 2441 | }; 2442 | 2443 | if (!window.cancelAnimationFrame) 2444 | window.cancelAnimationFrame = function(id) { 2445 | clearTimeout(id); 2446 | }; 2447 | }()); 2448 | 2449 | })); 2450 | -------------------------------------------------------------------------------- /js/ion.rangeSlider.min.js: -------------------------------------------------------------------------------- 1 | // Ion.RangeSlider, 2.3.1, © Denis Ineshin, 2010 - 2019, IonDen.com, Build date: 2019-12-19 16:56:44 2 | !function(i){"undefined"!=typeof jQuery&&jQuery||"function"!=typeof define||!define.amd?"undefined"!=typeof jQuery&&jQuery||"object"!=typeof exports?i(jQuery,document,window,navigator):i(require("jquery"),document,window,navigator):define(["jquery"],function(t){return i(t,document,window,navigator)})}(function(a,c,l,t,_){"use strict";var i,s,o=0,e=(i=t.userAgent,s=/msie\s\d+/i,0>>0;if(0==e)return-1;var h=+i||0;if(Math.abs(h)===1/0&&(h=0),e<=h)return-1;for(s=Math.max(0<=h?h:e-Math.abs(h),0);s!",r[0]),(e={skin:r.data("skin"),type:r.data("type"),min:r.data("min"),max:r.data("max"),from:r.data("from"),to:r.data("to"),step:r.data("step"),min_interval:r.data("minInterval"),max_interval:r.data("maxInterval"),drag_interval:r.data("dragInterval"),values:r.data("values"),from_fixed:r.data("fromFixed"),from_min:r.data("fromMin"),from_max:r.data("fromMax"),from_shadow:r.data("fromShadow"),to_fixed:r.data("toFixed"),to_min:r.data("toMin"),to_max:r.data("toMax"),to_shadow:r.data("toShadow"),prettify_enabled:r.data("prettifyEnabled"),prettify_separator:r.data("prettifySeparator"),force_edges:r.data("forceEdges"),keyboard:r.data("keyboard"),grid:r.data("grid"),grid_margin:r.data("gridMargin"),grid_num:r.data("gridNum"),grid_snap:r.data("gridSnap"),hide_min_max:r.data("hideMinMax"),hide_from_to:r.data("hideFromTo"),prefix:r.data("prefix"),postfix:r.data("postfix"),max_postfix:r.data("maxPostfix"),decorate_both:r.data("decorateBoth"),values_separator:r.data("valuesSeparator"),input_values_separator:r.data("inputValuesSeparator"),disable:r.data("disable"),block:r.data("block"),extra_classes:r.data("extraClasses")}).values=e.values&&e.values.split(","),e)e.hasOwnProperty(h)&&(e[h]!==_&&""!==e[h]||delete e[h]);n!==_&&""!==n&&((n=n.split(e.input_values_separator||i.input_values_separator||";"))[0]&&n[0]==+n[0]&&(n[0]=+n[0]),n[1]&&n[1]==+n[1]&&(n[1]=+n[1]),i&&i.values&&i.values.length?(o.from=n[0]&&i.values.indexOf(n[0]),o.to=n[1]&&i.values.indexOf(n[1])):(o.from=n[0]&&+n[0],o.to=n[1]&&+n[1])),a.extend(o,i),a.extend(o,e),this.options=o,this.update_check={},this.validate(),this.result={input:this.$cache.input,slider:null,min:this.options.min,max:this.options.max,from:this.options.from,from_percent:0,from_value:null,to:this.options.to,to_percent:0,to_value:null},this.init()}h.prototype={init:function(t){this.no_diapason=!1,this.coords.p_step=this.convertToPercent(this.options.step,!0),this.target="base",this.toggleInput(),this.append(),this.setMinMax(),t?(this.force_redraw=!0,this.calc(!0),this.callOnUpdate()):(this.force_redraw=!0,this.calc(!0),this.callOnStart()),this.updateScene()},append:function(){var t='';this.$cache.input.before(t),this.$cache.input.prop("readonly",!0),this.$cache.cont=this.$cache.input.prev(),this.result.slider=this.$cache.cont,this.$cache.cont.html('01000'),this.$cache.rs=this.$cache.cont.find(".irs"),this.$cache.min=this.$cache.cont.find(".irs-min"),this.$cache.max=this.$cache.cont.find(".irs-max"),this.$cache.from=this.$cache.cont.find(".irs-from"),this.$cache.to=this.$cache.cont.find(".irs-to"),this.$cache.single=this.$cache.cont.find(".irs-single"),this.$cache.line=this.$cache.cont.find(".irs-line"),this.$cache.grid=this.$cache.cont.find(".irs-grid"),"single"===this.options.type?(this.$cache.cont.append(''),this.$cache.bar=this.$cache.cont.find(".irs-bar"),this.$cache.edge=this.$cache.cont.find(".irs-bar-edge"),this.$cache.s_single=this.$cache.cont.find(".single"),this.$cache.from[0].style.visibility="hidden",this.$cache.to[0].style.visibility="hidden",this.$cache.shad_single=this.$cache.cont.find(".shadow-single")):(this.$cache.cont.append(''),this.$cache.bar=this.$cache.cont.find(".irs-bar"),this.$cache.s_from=this.$cache.cont.find(".from"),this.$cache.s_to=this.$cache.cont.find(".to"),this.$cache.shad_from=this.$cache.cont.find(".shadow-from"),this.$cache.shad_to=this.$cache.cont.find(".shadow-to"),this.setTopHandler()),this.options.hide_from_to&&(this.$cache.from[0].style.display="none",this.$cache.to[0].style.display="none",this.$cache.single[0].style.display="none"),this.appendGrid(),this.options.disable?(this.appendDisableMask(),this.$cache.input[0].disabled=!0):(this.$cache.input[0].disabled=!1,this.removeDisableMask(),this.bindEvents()),this.options.disable||(this.options.block?this.appendDisableMask():this.removeDisableMask()),this.options.drag_interval&&(this.$cache.bar[0].style.cursor="ew-resize")},setTopHandler:function(){var t=this.options.min,i=this.options.max,s=this.options.from,o=this.options.to;t'),this.$cache.cont.addClass("irs-disabled")},removeDisableMask:function(){this.$cache.cont.remove(".irs-disable-mask"),this.$cache.cont.removeClass("irs-disabled")},remove:function(){this.$cache.cont.remove(),this.$cache.cont=null,this.$cache.line.off("keydown.irs_"+this.plugin_count),this.$cache.body.off("touchmove.irs_"+this.plugin_count),this.$cache.body.off("mousemove.irs_"+this.plugin_count),this.$cache.win.off("touchend.irs_"+this.plugin_count),this.$cache.win.off("mouseup.irs_"+this.plugin_count),e&&(this.$cache.body.off("mouseup.irs_"+this.plugin_count),this.$cache.body.off("mouseleave.irs_"+this.plugin_count)),this.$cache.grid_labels=[],this.coords.big=[],this.coords.big_w=[],this.coords.big_p=[],this.coords.big_x=[],cancelAnimationFrame(this.raf_id)},bindEvents:function(){this.no_diapason||(this.$cache.body.on("touchmove.irs_"+this.plugin_count,this.pointerMove.bind(this)),this.$cache.body.on("mousemove.irs_"+this.plugin_count,this.pointerMove.bind(this)),this.$cache.win.on("touchend.irs_"+this.plugin_count,this.pointerUp.bind(this)),this.$cache.win.on("mouseup.irs_"+this.plugin_count,this.pointerUp.bind(this)),this.$cache.line.on("touchstart.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.line.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.line.on("focus.irs_"+this.plugin_count,this.pointerFocus.bind(this)),this.options.drag_interval&&"double"===this.options.type?(this.$cache.bar.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"both")),this.$cache.bar.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"both"))):(this.$cache.bar.on("touchstart.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.bar.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click"))),"single"===this.options.type?(this.$cache.single.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"single")),this.$cache.s_single.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"single")),this.$cache.shad_single.on("touchstart.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.single.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"single")),this.$cache.s_single.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"single")),this.$cache.edge.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.shad_single.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click"))):(this.$cache.single.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.single.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.from.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"from")),this.$cache.s_from.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"from")),this.$cache.to.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"to")),this.$cache.s_to.on("touchstart.irs_"+this.plugin_count,this.pointerDown.bind(this,"to")),this.$cache.shad_from.on("touchstart.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.shad_to.on("touchstart.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.from.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"from")),this.$cache.s_from.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"from")),this.$cache.to.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"to")),this.$cache.s_to.on("mousedown.irs_"+this.plugin_count,this.pointerDown.bind(this,"to")),this.$cache.shad_from.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click")),this.$cache.shad_to.on("mousedown.irs_"+this.plugin_count,this.pointerClick.bind(this,"click"))),this.options.keyboard&&this.$cache.line.on("keydown.irs_"+this.plugin_count,this.key.bind(this,"keyboard")),e&&(this.$cache.body.on("mouseup.irs_"+this.plugin_count,this.pointerUp.bind(this)),this.$cache.body.on("mouseleave.irs_"+this.plugin_count,this.pointerUp.bind(this))))},pointerFocus:function(t){var i,s;this.target||(i=(s="single"===this.options.type?this.$cache.single:this.$cache.from).offset().left,i+=s.width()/2-1,this.pointerClick("single",{preventDefault:function(){},pageX:i}))},pointerMove:function(t){if(this.dragging){var i=t.pageX||t.originalEvent.touches&&t.originalEvent.touches[0].pageX;this.coords.x_pointer=i-this.coords.x_gap,this.calc()}},pointerUp:function(t){this.current_plugin===this.plugin_count&&this.is_active&&(this.is_active=!1,this.$cache.cont.find(".state_hover").removeClass("state_hover"),this.force_redraw=!0,e&&a("*").prop("unselectable",!1),this.updateScene(),this.restoreOriginalMinInterval(),(a.contains(this.$cache.cont[0],t.target)||this.dragging)&&this.callOnFinish(),this.dragging=!1)},pointerDown:function(t,i){i.preventDefault();var s=i.pageX||i.originalEvent.touches&&i.originalEvent.touches[0].pageX;2!==i.button&&("both"===t&&this.setTempMinInterval(),t=t||(this.target||"from"),this.current_plugin=this.plugin_count,this.target=t,this.is_active=!0,this.dragging=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=s-this.coords.x_gap,this.calcPointerPercent(),this.changeLevel(t),e&&a("*").prop("unselectable",!0),this.$cache.line.trigger("focus"),this.updateScene())},pointerClick:function(t,i){i.preventDefault();var s=i.pageX||i.originalEvent.touches&&i.originalEvent.touches[0].pageX;2!==i.button&&(this.current_plugin=this.plugin_count,this.target=t,this.is_click=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=+(s-this.coords.x_gap).toFixed(),this.force_redraw=!0,this.calc(),this.$cache.line.trigger("focus"))},key:function(t,i){if(!(this.current_plugin!==this.plugin_count||i.altKey||i.ctrlKey||i.shiftKey||i.metaKey)){switch(i.which){case 83:case 65:case 40:case 37:i.preventDefault(),this.moveByKey(!1);break;case 87:case 68:case 38:case 39:i.preventDefault(),this.moveByKey(!0)}return!0}},moveByKey:function(t){var i=this.coords.p_pointer,s=(this.options.max-this.options.min)/100;s=this.options.step/s,t?i+=s:i-=s,this.coords.x_pointer=this.toFixed(this.coords.w_rs/100*i),this.is_key=!0,this.calc()},setMinMax:function(){if(this.options){if(this.options.hide_min_max)return this.$cache.min[0].style.display="none",void(this.$cache.max[0].style.display="none");if(this.options.values.length)this.$cache.min.html(this.decorate(this.options.p_values[this.options.min])),this.$cache.max.html(this.decorate(this.options.p_values[this.options.max]));else{var t=this._prettify(this.options.min),i=this._prettify(this.options.max);this.result.min_pretty=t,this.result.max_pretty=i,this.$cache.min.html(this.decorate(t,this.options.min)),this.$cache.max.html(this.decorate(i,this.options.max))}this.labels.w_min=this.$cache.min.outerWidth(!1),this.labels.w_max=this.$cache.max.outerWidth(!1)}},setTempMinInterval:function(){var t=this.result.to-this.result.from;null===this.old_min_interval&&(this.old_min_interval=this.options.min_interval),this.options.min_interval=t},restoreOriginalMinInterval:function(){null!==this.old_min_interval&&(this.options.min_interval=this.old_min_interval,this.old_min_interval=null)},calc:function(t){if(this.options&&(this.calc_count++,10!==this.calc_count&&!t||(this.calc_count=0,this.coords.w_rs=this.$cache.rs.outerWidth(!1),this.calcHandlePercent()),this.coords.w_rs)){this.calcPointerPercent();var i=this.getHandleX();switch("both"===this.target&&(this.coords.p_gap=0,i=this.getHandleX()),"click"===this.target&&(this.coords.p_gap=this.coords.p_handle/2,i=this.getHandleX(),this.options.drag_interval?this.target="both_one":this.target=this.chooseHandle(i)),this.target){case"base":var s=(this.options.max-this.options.min)/100,o=(this.result.from-this.options.min)/s,e=(this.result.to-this.options.min)/s;this.coords.p_single_real=this.toFixed(o),this.coords.p_from_real=this.toFixed(o),this.coords.p_to_real=this.toFixed(e),this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max),this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max),this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max),this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real),this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real),this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real),this.target=null;break;case"single":if(this.options.from_fixed)break;this.coords.p_single_real=this.convertToRealPercent(i),this.coords.p_single_real=this.calcWithStep(this.coords.p_single_real),this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max),this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real);break;case"from":if(this.options.from_fixed)break;this.coords.p_from_real=this.convertToRealPercent(i),this.coords.p_from_real=this.calcWithStep(this.coords.p_from_real),this.coords.p_from_real>this.coords.p_to_real&&(this.coords.p_from_real=this.coords.p_to_real),this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max),this.coords.p_from_real=this.checkMinInterval(this.coords.p_from_real,this.coords.p_to_real,"from"),this.coords.p_from_real=this.checkMaxInterval(this.coords.p_from_real,this.coords.p_to_real,"from"),this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);break;case"to":if(this.options.to_fixed)break;this.coords.p_to_real=this.convertToRealPercent(i),this.coords.p_to_real=this.calcWithStep(this.coords.p_to_real),this.coords.p_to_realthis.coords.w_rs&&(this.coords.x_pointer=this.coords.w_rs),this.coords.p_pointer=this.toFixed(this.coords.x_pointer/this.coords.w_rs*100)):this.coords.p_pointer=0},convertToRealPercent:function(t){return t/(100-this.coords.p_handle)*100},convertToFakePercent:function(t){return t/100*(100-this.coords.p_handle)},getHandleX:function(){var t=100-this.coords.p_handle,i=this.toFixed(this.coords.p_pointer-this.coords.p_gap);return i<0?i=0:t100-this.labels.p_max-1?this.$cache.max[0].style.visibility="hidden":this.$cache.max[0].style.visibility="visible";else{s=h?(this.options.decorate_both?(t=this.decorate(r[this.result.from]),t+=this.options.values_separator,t+=this.decorate(r[this.result.to])):t=this.decorate(r[this.result.from]+this.options.values_separator+r[this.result.to]),i=this.decorate(r[this.result.from]),this.decorate(r[this.result.to])):(o=this._prettify(this.result.from),e=this._prettify(this.result.to),this.options.decorate_both?(t=this.decorate(o,this.result.from),t+=this.options.values_separator,t+=this.decorate(e,this.result.to)):t=this.decorate(o+this.options.values_separator+e,this.result.to),i=this.decorate(o,this.result.from),this.decorate(e,this.result.to)),this.$cache.single.html(t),this.$cache.from.html(i),this.$cache.to.html(s),this.calcLabels();var n=Math.min(this.labels.p_single_left,this.labels.p_from_left),a=this.labels.p_single_left+this.labels.p_single_fake,c=this.labels.p_to_left+this.labels.p_to_fake,l=Math.max(a,c);this.labels.p_from_left+this.labels.p_from_fake>=this.labels.p_to_left?(this.$cache.from[0].style.visibility="hidden",this.$cache.to[0].style.visibility="hidden",this.$cache.single[0].style.visibility="visible",l=this.result.from===this.result.to?("from"===this.target?this.$cache.from[0].style.visibility="visible":"to"===this.target?this.$cache.to[0].style.visibility="visible":this.target||(this.$cache.from[0].style.visibility="visible"),this.$cache.single[0].style.visibility="hidden",c):(this.$cache.from[0].style.visibility="hidden",this.$cache.to[0].style.visibility="hidden",this.$cache.single[0].style.visibility="visible",Math.max(a,c))):(this.$cache.from[0].style.visibility="visible",this.$cache.to[0].style.visibility="visible",this.$cache.single[0].style.visibility="hidden"),n100-this.labels.p_max-1?this.$cache.max[0].style.visibility="hidden":this.$cache.max[0].style.visibility="visible"}}},drawShadow:function(){var t,i,s,o,e=this.options,h=this.$cache,r="number"==typeof e.from_min&&!isNaN(e.from_min),n="number"==typeof e.from_max&&!isNaN(e.from_max),a="number"==typeof e.to_min&&!isNaN(e.to_min),c="number"==typeof e.to_max&&!isNaN(e.to_max);"single"===e.type?e.from_shadow&&(r||n)?(t=this.convertToPercent(r?e.from_min:e.min),i=this.convertToPercent(n?e.from_max:e.max)-t,t=this.toFixed(t-this.coords.p_handle/100*t),i=this.toFixed(i-this.coords.p_handle/100*i),t+=this.coords.p_handle/2,h.shad_single[0].style.display="block",h.shad_single[0].style.left=t+"%",h.shad_single[0].style.width=i+"%"):h.shad_single[0].style.display="none":(e.from_shadow&&(r||n)?(t=this.convertToPercent(r?e.from_min:e.min),i=this.convertToPercent(n?e.from_max:e.max)-t,t=this.toFixed(t-this.coords.p_handle/100*t),i=this.toFixed(i-this.coords.p_handle/100*i),t+=this.coords.p_handle/2,h.shad_from[0].style.display="block",h.shad_from[0].style.left=t+"%",h.shad_from[0].style.width=i+"%"):h.shad_from[0].style.display="none",e.to_shadow&&(a||c)?(s=this.convertToPercent(a?e.to_min:e.min),o=this.convertToPercent(c?e.to_max:e.max)-s,s=this.toFixed(s-this.coords.p_handle/100*s),o=this.toFixed(o-this.coords.p_handle/100*o),s+=this.coords.p_handle/2,h.shad_to[0].style.display="block",h.shad_to[0].style.left=s+"%",h.shad_to[0].style.width=o+"%"):h.shad_to[0].style.display="none")},writeToInput:function(){"single"===this.options.type?(this.options.values.length?this.$cache.input.prop("value",this.result.from_value):this.$cache.input.prop("value",this.result.from),this.$cache.input.data("from",this.result.from)):(this.options.values.length?this.$cache.input.prop("value",this.result.from_value+this.options.input_values_separator+this.result.to_value):this.$cache.input.prop("value",this.result.from+this.options.input_values_separator+this.result.to),this.$cache.input.data("from",this.result.from),this.$cache.input.data("to",this.result.to))},callOnStart:function(){this.writeToInput(),this.options.onStart&&"function"==typeof this.options.onStart&&(this.options.scope?this.options.onStart.call(this.options.scope,this.result):this.options.onStart(this.result))},callOnChange:function(){this.writeToInput(),this.options.onChange&&"function"==typeof this.options.onChange&&(this.options.scope?this.options.onChange.call(this.options.scope,this.result):this.options.onChange(this.result))},callOnFinish:function(){this.writeToInput(),this.options.onFinish&&"function"==typeof this.options.onFinish&&(this.options.scope?this.options.onFinish.call(this.options.scope,this.result):this.options.onFinish(this.result))},callOnUpdate:function(){this.writeToInput(),this.options.onUpdate&&"function"==typeof this.options.onUpdate&&(this.options.scope?this.options.onUpdate.call(this.options.scope,this.result):this.options.onUpdate(this.result))},toggleInput:function(){this.$cache.input.toggleClass("irs-hidden-input"),this.has_tab_index?this.$cache.input.prop("tabindex",-1):this.$cache.input.removeProp("tabindex"),this.has_tab_index=!this.has_tab_index},convertToPercent:function(t,i){var s,o=this.options.max-this.options.min,e=o/100;return o?(s=(i?t:t-this.options.min)/e,this.toFixed(s)):(this.no_diapason=!0,0)},convertToValue:function(t){var i,s,o=this.options.min,e=this.options.max,h=o.toString().split(".")[1],r=e.toString().split(".")[1],n=0,a=0;if(0===t)return this.options.min;if(100===t)return this.options.max;h&&(n=i=h.length),r&&(n=s=r.length),i&&s&&(n=s<=i?i:s),o<0&&(o=+(o+(a=Math.abs(o))).toFixed(n),e=+(e+a).toFixed(n));var c,l=(e-o)/100*t+o,_=this.options.step.toString().split(".")[1];return l=_?+l.toFixed(_.length):(l/=this.options.step,+(l*=this.options.step).toFixed(0)),a&&(l-=a),(c=_?+l.toFixed(_.length):this.toFixed(l))this.options.max&&(c=this.options.max),c},calcWithStep:function(t){var i=Math.round(t/this.coords.p_step)*this.coords.p_step;return 100h.max_interval&&(o=e-h.max_interval):o-e>h.max_interval&&(o=e+h.max_interval),this.convertToPercent(o)):t},checkDiapason:function(t,i,s){var o=this.convertToValue(t),e=this.options;return"number"!=typeof i&&(i=e.min),"number"!=typeof s&&(s=e.max),os.max&&(s.from=s.max)):(s.froms.max&&(s.from=s.max),s.tos.max&&(s.to=s.max),this.update_check.from&&(this.update_check.from!==s.from&&s.from>s.to&&(s.from=s.to),this.update_check.to!==s.to&&s.tos.to&&(s.from=s.to),s.tos.from_max&&(s.from=s.from_max),"number"==typeof s.to_min&&s.tos.to_max&&(s.to=s.to_max),o&&(o.min!==s.min&&(o.min=s.min),o.max!==s.max&&(o.max=s.max),(o.fromo.max)&&(o.from=s.from),(o.too.max)&&(o.to=s.to)),("number"!=typeof s.min_interval||isNaN(s.min_interval)||!s.min_interval||s.min_interval<0)&&(s.min_interval=0),("number"!=typeof s.max_interval||isNaN(s.max_interval)||!s.max_interval||s.max_interval<0)&&(s.max_interval=0),s.min_interval&&s.min_interval>s.max-s.min&&(s.min_interval=s.max-s.min),s.max_interval&&s.max_interval>s.max-s.min&&(s.max_interval=s.max-s.min)},decorate:function(t,i){var s="",o=this.options;return o.prefix&&(s+=o.prefix),s+=t,o.max_postfix&&(o.values.length&&t===o.p_values[o.max]?(s+=o.max_postfix,o.postfix&&(s+=" ")):i===o.max&&(s+=o.max_postfix,o.postfix&&(s+=" "))),o.postfix&&(s+=o.postfix),s},updateFrom:function(){this.result.from=this.options.from,this.result.from_percent=this.convertToPercent(this.result.from),this.result.from_pretty=this._prettify(this.result.from),this.options.values&&(this.result.from_value=this.options.values[this.result.from])},updateTo:function(){this.result.to=this.options.to,this.result.to_percent=this.convertToPercent(this.result.to),this.result.to_pretty=this._prettify(this.result.to),this.options.values&&(this.result.to_value=this.options.values[this.result.to])},updateResult:function(){this.result.min=this.options.min,this.result.max=this.options.max,this.updateFrom(),this.updateTo()},appendGrid:function(){if(this.options.grid){var t,i,s,o,e,h,r=this.options,n=r.max-r.min,a=r.grid_num,c=0,l=4,_="";for(this.calcGridMargin(),r.grid_snap&&(a=n/r.step),50';_+='',h=this.convertToValue(c),_+=''+(h=r.values.length?r.p_values[h]:this._prettify(h))+""}this.coords.big_num=Math.ceil(a+1),this.$cache.cont.addClass("irs-with-grid"),this.$cache.grid.html(_),this.cacheGridLabels()}},cacheGridLabels:function(){var t,i,s=this.coords.big_num;for(i=0;i100+this.coords.grid_gap&&(o[e-1]=100+this.coords.grid_gap,s[e-1]=this.toFixed(o[e-1]-this.coords.big_p[e-1]),this.coords.big_x[e-1]=this.toFixed(this.coords.big_p[e-1]-this.coords.grid_gap))),this.calcGridCollision(2,s,o),this.calcGridCollision(4,s,o),t=0;t i:first-child { 60 | position: absolute; 61 | display: block; 62 | top: 0; 63 | left: 50%; 64 | width: 2px; 65 | height: 100%; 66 | margin-left: -1px; 67 | background-color: @handle_color_1; 68 | } 69 | 70 | &.state_hover, 71 | &:hover { 72 | & > i:first-child { 73 | background-color: @handle_color_2; 74 | } 75 | } 76 | } 77 | 78 | .@{name}-min, 79 | .@{name}-max { 80 | top: 0; 81 | padding: 1px 3px; 82 | color: @minmax_text_color; 83 | font-size: 10px; 84 | line-height: 1.333; 85 | text-shadow: none; 86 | background-color: @minmax_bg_color; 87 | border-radius: @custom_radius; 88 | } 89 | 90 | .@{name}-from, 91 | .@{name}-to, 92 | .@{name}-single { 93 | color: @label_color_2; 94 | font-size: 10px; 95 | line-height: 1.333; 96 | text-shadow: none; 97 | padding: 1px 5px; 98 | background-color: @label_color_1; 99 | border-radius: @custom_radius; 100 | 101 | &:before { 102 | position: absolute; 103 | display: block; 104 | content: ""; 105 | bottom: -6px; 106 | left: 50%; 107 | width: 0; 108 | height: 0; 109 | margin-left: -3px; 110 | overflow: hidden; 111 | border: 3px solid transparent; 112 | border-top-color: @label_color_1; 113 | } 114 | } 115 | 116 | .@{name}-grid { 117 | &-pol { 118 | background-color: @grid_color_1; 119 | } 120 | 121 | &-text { 122 | color: @grid_color_2; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /less/skins/modern.less: -------------------------------------------------------------------------------- 1 | .irs--modern { 2 | @name: irs; 3 | 4 | @top: 25px; 5 | @bottom: 21px; 6 | @line_height: 5px; 7 | @handle_width: 12px; 8 | @handle_height: 13px; 9 | 10 | @line_color: #d1d6e0; 11 | @bar_color: #20b426; 12 | @handle_color_1: #e9e6e6; 13 | @handle_color_2: white; 14 | @handle_color_3: black; 15 | @minmax_text_color: white; 16 | @minmax_bg_color: #d1d6e0; 17 | @label_color_1: #20b426; 18 | @label_color_2: white; 19 | @grid_color_1: #dedede; 20 | @grid_color_2: silver; 21 | 22 | 23 | 24 | height: 55px; 25 | 26 | &.irs-with-grid { 27 | height: 55px; 28 | } 29 | 30 | .@{name}-line { 31 | top: @top; 32 | height: @line_height; 33 | background-color: @line_color; 34 | background: linear-gradient(to bottom, lighten(@line_color, 5%) 0%, @line_color 100%); 35 | border: 1px solid darken(@line_color, 15%); 36 | border-bottom-width: 0; 37 | border-radius: @line_height; 38 | } 39 | 40 | .@{name}-bar { 41 | top: @top; 42 | height: @line_height; 43 | background: @bar_color; 44 | background: linear-gradient(to bottom, @bar_color 0%, darken(@bar_color, 10%) 100%); 45 | 46 | &--single { 47 | border-radius: @line_height 0 0 @line_height; 48 | } 49 | } 50 | 51 | .@{name}-shadow { 52 | height: 1px; 53 | bottom: @bottom; 54 | background-color: fade(@line_color, 50%); 55 | } 56 | 57 | .@{name}-handle { 58 | top: 37px; 59 | width: @handle_width; 60 | height: @handle_height; 61 | border: 1px solid darken(@line_color, 15%); 62 | border-top-width: 0; 63 | box-shadow: 1px 1px 1px rgba(0,0,0,0.1); 64 | border-radius: 0 0 3px 3px; 65 | 66 | & > i:nth-child(1) { 67 | position: absolute; 68 | display: block; 69 | top: -4px; left: 1px; 70 | width: (@handle_width - 6px); 71 | height: (@handle_width - 6px); 72 | border: 1px solid darken(@line_color, 15%); 73 | background: @handle_color_2; 74 | transform: rotate(45deg); 75 | } 76 | 77 | & > i:nth-child(2) { 78 | position: absolute; 79 | display: block; 80 | box-sizing: border-box; 81 | top: 0; left: 0; 82 | width: (@handle_width - 2); 83 | height: (@handle_height - 1); 84 | background: @handle_color_1; 85 | background: linear-gradient(to bottom, @handle_color_2 0%, @handle_color_1 100%); 86 | border-radius: 0 0 3px 3px; 87 | } 88 | 89 | & > i:nth-child(3) { 90 | position: absolute; 91 | display: block; 92 | box-sizing: border-box; 93 | top: 3px; left: 3px; 94 | width: 4px; height: 5px; 95 | border-left: 1px solid darken(@line_color, 15%); 96 | border-right: 1px solid darken(@line_color, 15%); 97 | } 98 | 99 | &.state_hover, 100 | &:hover { 101 | border-color: darken(@line_color, 30%); 102 | background: #c3c7cd; 103 | background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(145,155,165,1) 30%,rgba(255,255,255,1) 100%); 104 | 105 | & > i:nth-child(1) { 106 | border-color: darken(@line_color, 30%); 107 | } 108 | 109 | & > i:nth-child(3) { 110 | border-color: darken(@line_color, 50%); 111 | } 112 | } 113 | } 114 | 115 | .@{name}-min, 116 | .@{name}-max { 117 | top: 0; 118 | font-size: 10px; 119 | line-height: 1.333; 120 | text-shadow: none; 121 | padding: 1px 5px; 122 | color: @minmax_text_color; 123 | background-color: @minmax_bg_color; 124 | border-radius: @line_height; 125 | } 126 | 127 | .@{name}-from, 128 | .@{name}-to, 129 | .@{name}-single { 130 | font-size: 10px; 131 | line-height: 1.333; 132 | text-shadow: none; 133 | padding: 1px 5px; 134 | background-color: @label_color_1; 135 | color: @label_color_2; 136 | border-radius: @line_height; 137 | 138 | &:before { 139 | position: absolute; 140 | display: block; 141 | content: ""; 142 | bottom: -6px; 143 | left: 50%; 144 | width: 0; 145 | height: 0; 146 | margin-left: -3px; 147 | overflow: hidden; 148 | border: 3px solid transparent; 149 | border-top-color: @label_color_1; 150 | } 151 | } 152 | 153 | .@{name}-grid { 154 | height: 25px; 155 | 156 | &-pol { 157 | background-color: @grid_color_1; 158 | } 159 | 160 | &-text { 161 | color: @grid_color_2; 162 | font-size: 13px; 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /less/skins/round.less: -------------------------------------------------------------------------------- 1 | // Skin design by Veaceslav Grimalschi 2 | // https://github.com/grimalschi 3 | 4 | .irs--round { 5 | @name: irs; 6 | 7 | @top: 36px; 8 | @bottom: 21px; 9 | @line_height: 4px; 10 | @handle_width: 24px; 11 | @handle_height: 24px; 12 | 13 | @line_color: #dee4ec; 14 | @bar_color: #006cfa; 15 | @handle_color_1: #006cfa; 16 | @handle_color_2: white; 17 | @handle_color_3: #f0f6ff; 18 | @minmax_text_color: #333; 19 | @minmax_bg_color: rgba(0,0,0,0.1); 20 | @label_color_1: #006cfa; 21 | @label_color_2: white; 22 | @grid_color_1: #dedede; 23 | @grid_color_2: silver; 24 | 25 | 26 | 27 | height: 50px; 28 | 29 | &.irs-with-grid { 30 | height: 65px; 31 | } 32 | 33 | .@{name}-line { 34 | top: @top; 35 | height: @line_height; 36 | background-color: @line_color; 37 | border-radius: @line_height; 38 | } 39 | 40 | .@{name}-bar { 41 | top: @top; 42 | height: @line_height; 43 | background-color: @bar_color; 44 | 45 | &--single { 46 | border-radius: @line_height 0 0 @line_height; 47 | } 48 | } 49 | 50 | .@{name}-shadow { 51 | height: 4px; 52 | bottom: @bottom; 53 | background-color: fade(@line_color, 50%); 54 | } 55 | 56 | .@{name}-handle { 57 | top: 26px; 58 | width: @handle_width; 59 | height: @handle_height; 60 | border: 4px solid @handle_color_1; 61 | background-color: @handle_color_2; 62 | border-radius: @handle_width; 63 | box-shadow: 0 1px 3px rgba(0, 0, 255, 0.3); 64 | 65 | &.state_hover, 66 | &:hover { 67 | background-color: @handle_color_3; 68 | } 69 | } 70 | 71 | .@{name}-min, 72 | .@{name}-max { 73 | color: @minmax_text_color; 74 | font-size: 14px; 75 | line-height: 1; 76 | top: 0; 77 | padding: 3px 5px; 78 | background-color: @minmax_bg_color; 79 | border-radius: @line_height; 80 | } 81 | 82 | .@{name}-from, 83 | .@{name}-to, 84 | .@{name}-single { 85 | font-size: 14px; 86 | line-height: 1; 87 | text-shadow: none; 88 | padding: 3px 5px; 89 | background-color: @label_color_1; 90 | color: @label_color_2; 91 | border-radius: @line_height; 92 | 93 | &:before { 94 | position: absolute; 95 | display: block; 96 | content: ""; 97 | bottom: -6px; 98 | left: 50%; 99 | width: 0; 100 | height: 0; 101 | margin-left: -3px; 102 | overflow: hidden; 103 | border: 3px solid transparent; 104 | border-top-color: @label_color_1; 105 | } 106 | } 107 | 108 | .@{name}-grid { 109 | height: 25px; 110 | 111 | &-pol { 112 | background-color: @grid_color_1; 113 | } 114 | 115 | &-text { 116 | color: @grid_color_2; 117 | font-size: 13px; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /less/skins/sharp.less: -------------------------------------------------------------------------------- 1 | .irs--sharp { 2 | @name: irs; 3 | 4 | @top: 30px; 5 | @bottom: 21px; 6 | @line_height: 2px; 7 | @handle_width: 10px; 8 | @handle_height: 10px; 9 | 10 | @line_color: black; 11 | @bar_color: #ee22fa; 12 | @handle_color_1: darken(#ee22fa, 20%); 13 | @handle_color_2: white; 14 | @handle_color_3: black; 15 | @minmax_text_color: white; 16 | @minmax_bg_color: darken(#ee22fa, 20%); 17 | @label_color_1: darken(#ee22fa, 20%); 18 | @label_color_2: white; 19 | @grid_color_1: #dedede; 20 | @grid_color_2: silver; 21 | 22 | 23 | 24 | height: 50px; 25 | font-size: 12px; 26 | line-height: 1; 27 | 28 | &.irs-with-grid { 29 | height: 57px; 30 | } 31 | 32 | .@{name}-line { 33 | top: @top; 34 | height: @line_height; 35 | background-color: @line_color; 36 | border-radius: @line_height; 37 | } 38 | 39 | .@{name}-bar { 40 | top: @top; 41 | height: @line_height; 42 | background-color: @bar_color; 43 | 44 | &--single { 45 | border-radius: @line_height 0 0 @line_height; 46 | } 47 | } 48 | 49 | .@{name}-shadow { 50 | height: 1px; 51 | bottom: @bottom; 52 | background-color: fade(@line_color, 50%); 53 | } 54 | 55 | .@{name}-handle { 56 | top: (@top - 5px); 57 | width: @handle_width; 58 | height: @handle_height; 59 | background-color: @handle_color_1; 60 | 61 | & > i:first-child { 62 | position: absolute; 63 | display: block; 64 | top: 100%; 65 | left: 0; 66 | width: 0; 67 | height: 0; 68 | border: 5px solid transparent; 69 | border-top-color: @handle_color_1; 70 | } 71 | 72 | &.state_hover, 73 | &:hover { 74 | background-color: @handle_color_3; 75 | 76 | & > i:first-child { 77 | border-top-color: @handle_color_3; 78 | } 79 | } 80 | } 81 | 82 | .@{name}-min, 83 | .@{name}-max { 84 | color: @minmax_text_color; 85 | font-size: 14px; 86 | line-height: 1; 87 | top: 0; 88 | padding: 3px 4px; 89 | opacity: 0.4; 90 | background-color: @minmax_bg_color; 91 | border-radius: @line_height; 92 | } 93 | 94 | .@{name}-from, 95 | .@{name}-to, 96 | .@{name}-single { 97 | font-size: 14px; 98 | line-height: 1; 99 | text-shadow: none; 100 | padding: 3px 4px; 101 | background-color: @label_color_1; 102 | color: @label_color_2; 103 | border-radius: @line_height; 104 | 105 | &:before { 106 | position: absolute; 107 | display: block; 108 | content: ""; 109 | bottom: -6px; 110 | left: 50%; 111 | width: 0; 112 | height: 0; 113 | margin-left: -3px; 114 | overflow: hidden; 115 | border: 3px solid transparent; 116 | border-top-color: @label_color_1; 117 | } 118 | } 119 | 120 | .@{name}-grid { 121 | height: 25px; 122 | 123 | &-pol { 124 | background-color: @grid_color_1; 125 | } 126 | 127 | &-text { 128 | color: @grid_color_2; 129 | font-size: 13px; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /less/skins/square.less: -------------------------------------------------------------------------------- 1 | // Skin design by Veaceslav Grimalschi 2 | // https://github.com/grimalschi 3 | 4 | .irs--square { 5 | @name: irs; 6 | 7 | @top: 31px; 8 | @bottom: 21px; 9 | @line_height: 4px; 10 | @handle_width: 16px; 11 | @handle_height: 16px; 12 | 13 | @line_color: #dedede; 14 | @bar_color: black; 15 | @handle_color_1: black; 16 | @handle_color_2: white; 17 | @handle_color_3: #f0f6ff; 18 | @minmax_text_color: #333; 19 | @minmax_bg_color: rgba(0,0,0,0.1); 20 | @label_color_1: black; 21 | @label_color_2: white; 22 | @grid_color_1: #dedede; 23 | @grid_color_2: silver; 24 | 25 | 26 | 27 | height: 50px; 28 | 29 | &.irs-with-grid { 30 | height: 60px; 31 | } 32 | 33 | .@{name}-line { 34 | top: @top; 35 | height: @line_height; 36 | background-color: @line_color; 37 | } 38 | 39 | .@{name}-bar { 40 | top: @top; 41 | height: @line_height; 42 | background-color: @bar_color; 43 | } 44 | 45 | .@{name}-shadow { 46 | height: 2px; 47 | bottom: @bottom; 48 | background-color: @line_color; 49 | } 50 | 51 | .@{name}-handle { 52 | top: (@top - 6px); 53 | width: @handle_width; 54 | height: @handle_height; 55 | border: 3px solid @handle_color_1; 56 | background-color: @handle_color_2; 57 | -webkit-transform: rotate(45deg); 58 | -ms-transform: rotate(45deg); 59 | transform: rotate(45deg); 60 | 61 | &.state_hover, 62 | &:hover { 63 | background-color: @handle_color_3; 64 | } 65 | } 66 | 67 | .@{name}-min, 68 | .@{name}-max { 69 | color: @minmax_text_color; 70 | font-size: 14px; 71 | line-height: 1; 72 | top: 0; 73 | padding: 3px 5px; 74 | background-color: @minmax_bg_color; 75 | } 76 | 77 | .@{name}-from, 78 | .@{name}-to, 79 | .@{name}-single { 80 | font-size: 14px; 81 | line-height: 1; 82 | text-shadow: none; 83 | padding: 3px 5px; 84 | background-color: @label_color_1; 85 | color: @label_color_2; 86 | } 87 | 88 | .@{name}-grid { 89 | height: 25px; 90 | 91 | &-pol { 92 | background-color: @grid_color_1; 93 | } 94 | 95 | &-text { 96 | color: @grid_color_2; 97 | font-size: 11px; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ion-rangeslider", 3 | "version": "2.3.1", 4 | "description": "Cool, comfortable and easily customizable range slider with many options and skin support", 5 | "homepage": "http://ionden.com/a/plugins/ion.rangeSlider/", 6 | "author": { 7 | "name": "Denis Ineshin (IonDen)", 8 | "email": "ionden.tech@gmail.com", 9 | "url": "https://github.com/IonDen" 10 | }, 11 | "keywords": [ 12 | "jquery-plugin", 13 | "ecosystem:jquery", 14 | "jquery", 15 | "form", 16 | "input", 17 | "range", 18 | "slider", 19 | "rangeslider", 20 | "interface", 21 | "diapason", 22 | "ui", 23 | "noui", 24 | "skins" 25 | ], 26 | "main": "./js/ion.rangeSlider.js", 27 | "directories": { 28 | "lib": "js" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "git://github.com/IonDen/ion.rangeSlider.git" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/IonDen/ion.rangeSlider/issues" 36 | }, 37 | "license": "MIT", 38 | "peerDependencies": { 39 | "jquery": ">=1.8" 40 | }, 41 | "ignore": [ 42 | ".idea", 43 | "_tmp", 44 | "PSD", 45 | "bower.json" 46 | ] 47 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![ion.rangeSlider](_tmp/logo-ion-range-slider.png) 2 | 3 | Ion.RangeSlider. Is an easy, flexible and responsive range slider with tons of options. 4 | 5 | *** 6 | 7 | * Version: 2.3.1 | *Version 3.x is under development now* 8 | * Project page and demos 9 | * Download ZIP 10 | * [Support the plugin on GitHub sponsors](https://github.com/sponsors/IonDen) 11 | 12 | ## Description 13 | * Ion.RangeSlider — cool, comfortable, responsive and easily customizable range slider 14 | * Supports events and public methods, has flexible settings, can be completely altered with CSS 15 | * Cross-browser: Google Chrome, Mozilla Firefox 3.6+, Opera 12+, Safari 5+, Internet Explorer 8+ 16 | * Ion.RangeSlider supports touch-devices (iPhone, iPad, Nexus, etc.). 17 | * Ion.RangeSlider freely distributed under terms of MIT licence. 18 | * With this plugin you will be able to build beautiful range sliders, like this: 19 | 20 | ![ion.rangeSlider](_tmp/ion-range-slider.png) 21 | 22 | ## Key features 23 | * Skin support. (6 skins included) 24 | * Any number of sliders at one page without conflicts and big performance problems 25 | * Two slider types single (1 slider) and double (2 sliders) 26 | * Support of negative and fractional values 27 | * Ability to set custom step and snap grid to step 28 | * Support of custom values diapason 29 | * Customisable grid of values 30 | * Ability to disable UI elements (min and max, current value, grid) 31 | * Postfixes and prefixes for your numbers ($20, 20 € etc.) 32 | * Additional postfix for maximum value (eg. $0 — $100+) 33 | * Ability to prettify large numbers (eg. 10000000 -> 10 000 000 or 10.000.000) 34 | * Slider writes its value right into input value field. This makes it easy to use in any html form 35 | * Any slider value can be set through input data-attribute (eg. data-min="10") 36 | * Slider supports disable param. You can set it true to make slider inactive 37 | * Slider supports external methods (update, reset and remove) to control it after creation 38 | * For advanced users slider has callbacks (onStart, onChange, onFinish, onUpdate). Slider pastes all its params to callback first argument as object 39 | * Slider supports date and time 40 | 41 | 42 | ## Demos 43 | 44 | * Basic demo 45 | * Advanced demo 46 | * Interactions demo 47 | 48 | 49 | ## Dependencies 50 | 51 | * jQuery 1.8.x+ 52 | 53 | 54 | ## Usage 55 | 56 | Add the following libraries to the page: 57 | * jQuery 58 | * ion.rangeSlider.min.js 59 | 60 | Add the following stylesheets to the page: 61 | * ion.rangeSlider.min.css 62 | 63 | 64 | 65 | ## CDN 66 | 67 | Use [CDNjs](https://cdnjs.com/libraries/ion-rangeslider) or [JSdelivr](https://www.jsdelivr.com/package/npm/ion-rangeslider) to get latest version of plugin and jQuery. 68 | ```html 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | ``` 78 | 79 | 80 | 81 | ## Install with NPM 82 | 83 | Use [NPM](https://www.npmjs.com/package/ion-rangeslider) to download latest version of a plugin and install it directly in to your project. 84 | 85 | * npm install ion-rangeslider 86 | 87 | 88 | 89 | ## Install with Bower 90 | 91 | Use [Bower](https://bower.io/) to download latest version of a plugin and install it directly in to your project. 92 | 93 | * bower install ion-rangeslider 94 | 95 | 96 | 97 | ## Install with Yarn 98 | 99 | Use [Yarn](https://yarnpkg.com/en/package/ion-rangeslider) to download latest version of a plugin and install it directly in to your project. 100 | 101 | * yarn add ion-rangeslider 102 | 103 | 104 | ## Initialisation 105 | 106 | The slider overrides a native text input element. 107 | ```html 108 | 109 | ``` 110 | 111 | To initialise the slider, call ionRangeSlider on the element: 112 | ```javascript 113 | $("#example_id").ionRangeSlider(); 114 | ``` 115 | 116 | 117 | ## Experiments playground 118 | 119 | Here you can find bunch of advanced JSFIDDLE demos with different, non-standard use cases: 120 | * [Custom marks on slider](https://jsfiddle.net/IonDen/tdvxs3zL/) 121 | * [1 handle bind to 1 input](https://jsfiddle.net/IonDen/khngpw3m/) 122 | * [2 handles bind to 2 inputs](https://jsfiddle.net/IonDen/avcm6wpj/) 123 | * [2 sliders connected to each other](https://jsfiddle.net/IonDen/1hnvxsg5/) 124 | * [2 dependant sliders](https://jsfiddle.net/IonDen/f1t6qpx0/) 125 | * [1st slider disables/enables 2nd slider](https://jsfiddle.net/IonDen/kqwm1294/) 126 | * [Non-linear slider](https://jsfiddle.net/IonDen/5f2730ds/) 127 | * [Plus and Minus buttons](https://jsfiddle.net/IonDen/e9as5k2m/) 128 | * [Calculating sum](https://jsfiddle.net/IonDen/dfcmryn2/) 129 | * [Adding one more diapazon on 1 slider](https://jsfiddle.net/IonDen/ckwrqv75/) 130 | * [Live editing of Min and Max values](https://jsfiddle.net/IonDen/wgfv76je/) 131 | * [Prettify and transform values at the same time](https://jsfiddle.net/IonDen/kc0tzreu/) 132 | * [Rendering money value n.nn](https://jsfiddle.net/IonDen/a0rghmd7/) 133 | * [Changing step live](https://jsfiddle.net/IonDen/5ptjgm6h/) 134 | * [Toggle slider](https://jsfiddle.net/IonDen/7m4otxwp/) 135 | * [Skip some values](https://jsfiddle.net/IonDen/bqyw1e7k/) 136 | * [Values array + prettify](https://jsfiddle.net/IonDen/p9gu71sL/) 137 | 138 | 139 | ## Settings 140 | 141 | 142 | | Option | Data-Attr | Defaults | Type | Description | 143 | | --- | --- | --- | --- | --- | 144 | | `skin` | `data-skin` | `flat` | string | Choose UI skin to use (flat, big, modern, round, sharp, square) | 145 | | `type` | `data-type` | `single` | string | Choose slider type, could be `single` - for one handle, or `double` for two handles | 146 | | `min` | `data-min` | `10` | number | Set slider minimum value | 147 | | `max` | `data-max` | `100` | number | Set slider maximum value | 148 | | `from` | `data-from` | `min` | number | Set start position for left handle (or for single handle) | 149 | | `to` | `data-to` | `max` | number | Set start position for right handle | 150 | | `step` | `data-step` | `1` | number | Set sliders step. Always > 0. Could be fractional | 151 | | `min_interval` | `data-min-interval` | `-` | number | Set minimum diapason between sliders. Only for **double** type | 152 | | `max_interval` | `data-max-interval` | `-` | number | Set minimum maximum between sliders. Only for **double** type | 153 | | `drag_interval` | `data-drag-interval` | `false` | boolean | Allow user to drag whole range. Only for **double** type | 154 | | `values` | `data-values` | `[]` | array | Set up your own array of possible slider values. They could be numbers or strings. If the values array is set up, min, max and step param, can no longer be changed | 155 | | `from_fixed` | `data-from-fixed` | `false` | boolean | Fix position of left (or single) handle | 156 | | `from_min` | `data-from-min` | `min` | number | Set minimum limit for left (or single) handle | 157 | | `from_max` | `data-from-max` | `max` | number | Set maximum limit for left (or single) handle | 158 | | `from_shadow` | `data-from-shadow` | `false` | boolean | Highlight the limits for left handle | 159 | | `to_fixed` | `data-to-fixed` | `false` | boolean | Fix position of right handle | 160 | | `to_min` | `data-to-min` | `min` | number | Set minimum limit for right handle | 161 | | `to_max` | `data-to-max` | `max` | number | Set maximum limit for right handle | 162 | | `to_shadow` | `data-to-shadow` | `false` | boolean | Highlight the right handle | 163 | | `prettify_enabled` | `data-prettify-enabled` | `true` | boolean | Improve readability of long numbers: 10000000 → 10 000 000 | 164 | | `prettify_separator` | `data-prettify-separator` | ` ` | string | Set up your own separator for long numbers: 10000000 → 10,000,000 etc. | 165 | | `prettify` | `-` | `null` | function | Set up your own prettify function. Can be anything. For example, you can set up unix time as slider values and than transform them to cool looking dates | 166 | | `force_edges` | `data-force-edges` | `false` | boolean | Sliders handles and tooltips will be always inside it's container | 167 | | `keyboard` | `data-keyboard` | `true` | boolean | Activates keyboard controls. Move left: ←, ↓, A, S. Move right: →, ↑, W, D. | 168 | | `grid` | `data-grid` | `true` | boolean | Enables grid of values above the slider | 169 | | `grid_margin` | `data-grid-margin` | `true` | boolean | Set left and right grid gaps | 170 | | `grid_num` | `data-grid-num` | `4` | number | Number of grid units | 171 | | `grid_snap` | `data-grid-snap` | `false` | boolean | Snap grid to sliders step (step param). If activated, grid_num will not be used. Max steps = 50 | 172 | | `hide_min_max` | `data-hide-min-max` | `false` | boolean | Hides **min** and **max** labels | 173 | | `hide_from_to` | `data-hide-from-to` | `false` | boolean | Hides **from** and **to** labels | 174 | | `prefix` | `data-prefix` | `` | string | Set prefix for values. Will be set up right before the number: **$**100 | 175 | | `postfix` | `data-postfix` | `` | string | Set postfix for values. Will be set up right after the number: 100**k** | 176 | | `max_postfix` | `data-max-postfix` | `` | string | Special postfix, used only for maximum value. Will be showed after handle will reach maximum right position. For example **0 — 100+** | 177 | | `decorate_both` | `data-decorate-both` | `true` | boolean | Used for **double** type and only if prefix or postfix was set up. Determine how to decorate close values. For example: **$10k — $100k** or **$10 — 100k** | 178 | | `values_separator` | `data-decorate-both` | ` - ` | string | Set your own separator for close values. Used for **double** type. Default: **10 — 100**. Or you may set: **10 to 100, 10 + 100, 10 → 100** etc. | 179 | | `input_values_separator` | `data-input-values-separator` | ` ; ` | string | Separator for **double** values in input value property. `` | 180 | | `disable` | `data-disable` | `false` | boolean | Locks slider and makes it inactive. Input is disabled too. Invisible to forms | 181 | | `block` | `data-blokc` | `false` | boolean | Locks slider and makes it inactive. Input is NOT disabled. Can be send with forms | 182 | | `extra_classes` | `data-extra-classes` | `—` | string | Traverse extra CSS-classes to sliders container | 183 | | `scope` | `-` | `null` | object | Scope for callbacks. Pass any object | 184 | | `onStart` | `-` | `null` | function | Callback. Is called on slider start. Gets all slider data as a 1st attribute | 185 | | `onChange` | `-` | `null` | function | Callback. IS called on each values change. Gets all slider data as a 1st attribute | 186 | | `onFinish` | `-` | `null` | function | Callback. Is called when user releases handle. Gets all slider data as a 1st attribute | 187 | | `onUpdate` | `-` | `null` | function | Callback. Is called when slider is modified by external methods `update` or `reset` | 188 | 189 | 190 | 191 | ## Description of data passed to callbacks (onChange and etc.) 192 | Result is object type and passed to callback as first argument: 193 | ```javascript 194 | Obj: { 195 | "input": object, // jQuery-link to input 196 | "slider": object, // jQuery-link to sliders container 197 | "min": 1000, // MIN value 198 | "max": 100000, // MAX values 199 | "from": 10000, // FROM value 200 | "from_percent": 10, // FROM value in percents 201 | "from_value": 0, // FROM index in values array (if used) 202 | "to": 90000, // TO value 203 | "to_percent": 90, // TO value in percents 204 | "to_value": 0, // TO index in values array (if used) 205 | "min_pretty": "1 000", // MIN prettified (if used) 206 | "max_pretty": "100 000", // MAX prettified (if used) 207 | "from_pretty": "10 000", // FROM prettified (if used) 208 | "to_pretty": "90 000" // TO prettified (if used) 209 | } 210 | ``` 211 | 212 | ## Creating slider (all params) 213 | An example of a customised slider: 214 | ```javascript 215 | $("#example").ionRangeSlider({ 216 | skin: "big", 217 | min: 0, 218 | max: 10000, 219 | from: 1000, 220 | to: 9000, 221 | type: 'double', 222 | prefix: "$", 223 | grid: true, 224 | grid_num: 10 225 | }); 226 | ``` 227 | 228 | You can also initialise slider with data-* attributes of input tag: 229 | ```html 230 | data-min="0" 231 | data-max="10000" 232 | data-from="1000" 233 | data-to="9000" 234 | data-type="double" 235 | data-prefix="$" 236 | data-grid="true" 237 | data-grid-num="10" 238 | ``` 239 | 240 | ## Public methods 241 | 242 | To use public methods, at first you must save slider instance to variable: 243 | ```javascript 244 | // Launch plugin 245 | $("#range").ionRangeSlider({ 246 | type: "double", 247 | min: 0, 248 | max: 1000, 249 | from: 200, 250 | to: 500, 251 | grid: true 252 | }); 253 | 254 | // Saving it's instance to var 255 | var slider = $("#range").data("ionRangeSlider"); 256 | 257 | // Fire public method 258 | slider.reset(); 259 | ``` 260 | 261 | There are 3 public methods: 262 | ```javascript 263 | // UPDATE - updates slider to any new values 264 | slider.update({ 265 | from: 300, 266 | to: 400 267 | }); 268 | 269 | // RESET - reset slider to it's first values 270 | slider.reset(); 271 | 272 | // DESTROY - destroys slider and restores original input field 273 | slider.destroy(); 274 | ``` 275 | 276 | 277 | ## One more look on demos 278 | 279 | * Basic demo 280 | * Advanced demo 281 | * Interactions demo 282 | 283 | All plugins options are covered in demos. 284 | 285 | 286 | ### Update history 287 | 288 | *** 289 | 290 | #### Support Ion-series plugins development: 291 | 292 | * [Support the plugin on GitHub sponsors](https://github.com/sponsors/IonDen) 293 | 294 | * Buy me a coffee: https://www.buymeacoffee.com/ionden 295 | --------------------------------------------------------------------------------