├── dist ├── img │ ├── jslider.png │ ├── jslider.blue.png │ ├── jslider.round.png │ ├── jslider.plastic.png │ ├── jslider.vertical.png │ ├── jslider.blue.vertical.png │ ├── jslider.round.plastic.png │ ├── jslider.round.vertical.png │ └── jslider.plastic.vertical.png ├── css │ └── angular-awesome-slider.min.css └── angular-awesome-slider.min.js ├── src ├── img │ ├── jslider.png │ ├── jslider.blue.png │ ├── jslider.round.png │ ├── jslider.plastic.png │ ├── jslider.vertical.png │ ├── jslider.blue.vertical.png │ ├── jslider.round.plastic.png │ ├── jslider.plastic.vertical.png │ └── jslider.round.vertical.png ├── css │ ├── sass │ │ ├── vertical │ │ │ ├── _pointers-value.sass │ │ │ ├── _main.sass │ │ │ ├── _labels.sass │ │ │ ├── _vertical.sass │ │ │ ├── _pointers.sass │ │ │ ├── _scales.sass │ │ │ └── _ranges.sass │ │ ├── horizontal │ │ │ ├── _main.sass │ │ │ ├── _scale.sass │ │ │ ├── _pointers-value.sass │ │ │ ├── _labels.sass │ │ │ ├── _horizontal.sass │ │ │ ├── _pointers.sass │ │ │ └── _ranges.sass │ │ ├── main.sass │ │ ├── core │ │ │ └── _variables.sass │ │ └── skins │ │ │ ├── _skin-plastic.sass │ │ │ ├── _skin-blue.sass │ │ │ ├── _skin-round.sass │ │ │ └── _skin-css.sass │ ├── scss │ │ ├── vertical │ │ │ ├── _main.scss │ │ │ ├── _pointers-value.scss │ │ │ ├── _labels.scss │ │ │ ├── _vertical.scss │ │ │ ├── _pointers.scss │ │ │ ├── _scales.scss │ │ │ └── _ranges.scss │ │ ├── horizontal │ │ │ ├── _main.scss │ │ │ ├── _pointers-value.scss │ │ │ ├── _scale.scss │ │ │ ├── _labels.scss │ │ │ ├── _horizontal.scss │ │ │ ├── _pointers.scss │ │ │ └── _ranges.scss │ │ ├── main.scss │ │ ├── core │ │ │ └── _variables.scss │ │ └── skins │ │ │ ├── _skin-plastic.scss │ │ │ ├── _skin-blue.scss │ │ │ ├── _skin-round.scss │ │ │ └── _skin-css.scss │ ├── less │ │ ├── variables.less │ │ ├── skin-plastic.less │ │ ├── skin-blue.less │ │ ├── skin-round.less │ │ ├── skin-css.less │ │ └── main.less │ └── angular-awesome-slider.css ├── core │ ├── config │ │ └── constants.js │ ├── utils │ │ └── utils.factory.js │ ├── template │ │ └── slider.tmpl.js │ ├── model │ │ ├── pointer.factory.js │ │ ├── draggable.factory.js │ │ └── slider.factory.js │ └── index.js ├── index.html └── jquery.slider.js ├── .travis.yml ├── .gitignore ├── bower.json ├── MIT-LICENSE.txt ├── package.json ├── test ├── my.conf.js └── prettySpec.js ├── Gruntfile.js └── README.md /dist/img/jslider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.png -------------------------------------------------------------------------------- /src/img/jslider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.png -------------------------------------------------------------------------------- /dist/img/jslider.blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.blue.png -------------------------------------------------------------------------------- /dist/img/jslider.round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.round.png -------------------------------------------------------------------------------- /src/img/jslider.blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.blue.png -------------------------------------------------------------------------------- /src/img/jslider.round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.round.png -------------------------------------------------------------------------------- /dist/img/jslider.plastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.plastic.png -------------------------------------------------------------------------------- /src/img/jslider.plastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.plastic.png -------------------------------------------------------------------------------- /src/img/jslider.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.vertical.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.11 4 | before_install: npm install -g grunt-cli 5 | install: npm install -------------------------------------------------------------------------------- /dist/img/jslider.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.vertical.png -------------------------------------------------------------------------------- /src/img/jslider.blue.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.blue.vertical.png -------------------------------------------------------------------------------- /src/img/jslider.round.plastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.round.plastic.png -------------------------------------------------------------------------------- /dist/img/jslider.blue.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.blue.vertical.png -------------------------------------------------------------------------------- /dist/img/jslider.round.plastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.round.plastic.png -------------------------------------------------------------------------------- /dist/img/jslider.round.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.round.vertical.png -------------------------------------------------------------------------------- /src/img/jslider.plastic.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.plastic.vertical.png -------------------------------------------------------------------------------- /src/img/jslider.round.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/src/img/jslider.round.vertical.png -------------------------------------------------------------------------------- /dist/img/jslider.plastic.vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darul75/angular-awesome-slider/HEAD/dist/img/jslider.plastic.vertical.png -------------------------------------------------------------------------------- /src/css/sass/vertical/_pointers-value.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | div.jslider-value 3 | top: 0 4 | left: 0 5 | 6 | div.jslider-value-to 7 | top: 80% 8 | left: 0 9 | 10 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_main.sass: -------------------------------------------------------------------------------- 1 | // Vertical Styles 2 | 3 | @import vertical 4 | @import ranges 5 | @import pointers 6 | @import labels 7 | @import pointers-value 8 | @import scales 9 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_main.sass: -------------------------------------------------------------------------------- 1 | // Horizontal Styles 2 | 3 | @import horizontal 4 | @import ranges 5 | @import pointers 6 | @import labels 7 | @import pointers-value 8 | @import scale 9 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_main.scss: -------------------------------------------------------------------------------- 1 | // Vertical Styles 2 | 3 | @import "vertical"; 4 | @import "ranges"; 5 | @import "pointers"; 6 | @import "labels"; 7 | @import "pointers-value"; 8 | @import "scales"; 9 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_main.scss: -------------------------------------------------------------------------------- 1 | // Horizontal Styles 2 | 3 | @import "horizontal"; 4 | @import "ranges"; 5 | @import "pointers"; 6 | @import "labels"; 7 | @import "pointers-value"; 8 | @import "scale"; 9 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_pointers-value.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | div.jslider-value { 3 | top: 0; 4 | left: 0; 5 | } 6 | div.jslider-value-to { 7 | top: 80%; 8 | left: 0; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_labels.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | div.jslider-label 3 | top: -5px 4 | margin-left: 22px 5 | 6 | &.jslider-label-to 7 | top: 100% 8 | left: inherit 9 | right: inherit 10 | margin-top: -5px 11 | 12 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_labels.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | div.jslider-label { 3 | top: -5px; 4 | margin-left: 22px; 5 | &.jslider-label-to { 6 | top: 100%; 7 | left: inherit; 8 | right: inherit; 9 | margin-top: -5px; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Node ### 4 | lib-cov 5 | lcov.info 6 | *.seed 7 | *.log 8 | *.csv 9 | *.dat 10 | *.out 11 | *.pid 12 | *.gz 13 | *.scssc 14 | *.sassc 15 | 16 | pids 17 | logs 18 | results 19 | build 20 | .grunt 21 | .history/ 22 | 23 | node_modules 24 | bower_components 25 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_scale.sass: -------------------------------------------------------------------------------- 1 | div.jslider-scale 2 | position: relative 3 | top: 9px 4 | 5 | span 6 | position: absolute 7 | height: 5px 8 | border-left: 1px solid $gray 9 | font-size: 0 10 | 11 | ins 12 | +position(absolute, 5px null 0 null) 13 | font-size: 9px 14 | text-decoration: none 15 | color: $gray 16 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_vertical.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | +position(relative, 0.6em null null null) 3 | display: block 4 | +size(17px 100%) 5 | font-family: Arial, sans-serif 6 | 7 | table 8 | height: 100% 9 | 10 | &.sliderCSS .jslider-bg i, 11 | &.jslider-pointer 12 | background-color: silver 13 | background-image: none 14 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_pointers-value.sass: -------------------------------------------------------------------------------- 1 | div.jslider-value 2 | +position(absolute, -19px null 0 null) 3 | padding: 1px 2px 0 4 | // background: white 5 | font-size: $font-size-pointers-value 6 | line-height: $line-height-pointers-value 7 | white-space: nowrap 8 | border-radius: 2px 9 | 10 | &.jslider-value-to 11 | left: 80% 12 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_pointers.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | div.jslider-pointer 3 | left: 62% 4 | background-position: -7px -1px 5 | 6 | &.jslider-pointer-hover 7 | background-position: -7px -21px 8 | 9 | &.jslider-pointer-to 10 | left: 62% 11 | 12 | &.jslider-pointer-to.jslider-pointer-hover 13 | background-position: -7px -21px 14 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_scales.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | div.jslider-scale 3 | position: inherit 4 | 5 | span 6 | position: absolute 7 | +size(5px 1px) 8 | border-left: none 9 | font-size: 0 10 | border-top: 1px solid #999 11 | 12 | ins 13 | +position(absolute, 5px null 0 null) 14 | font-size: 9px 15 | text-decoration: none 16 | color: $color-scale 17 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_pointers-value.scss: -------------------------------------------------------------------------------- 1 | div.jslider-value { 2 | @include position(absolute, -19px null 0 null); 3 | padding: 1px 2px 0; 4 | // background: white 5 | font-size: $font-size-pointers-value; 6 | line-height: $line-height-pointers-value; 7 | white-space: nowrap; 8 | border-radius: 2px; 9 | &.jslider-value-to { 10 | left: 80%; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_vertical.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | @include position(relative, 0.6em null null null); 3 | display: block; 4 | @include size(17px 100%); 5 | font-family: Arial, sans-serif; 6 | table { 7 | height: 100%; 8 | } 9 | &.sliderCSS .jslider-bg i, 10 | &.jslider-pointer { 11 | background-color: silver; 12 | background-image: none; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_scale.scss: -------------------------------------------------------------------------------- 1 | div.jslider-scale { 2 | position: relative; 3 | top: 9px; 4 | span { 5 | position: absolute; 6 | height: 5px; 7 | border-left: 1px solid $gray; 8 | font-size: 0; 9 | } 10 | ins { 11 | @include position(absolute, 5px null 0 null); 12 | font-size: 9px; 13 | text-decoration: none; 14 | color: $gray; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_pointers.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | div.jslider-pointer { 3 | left: 62%; 4 | background-position: (-7px) -1px; 5 | &.jslider-pointer-hover { 6 | background-position: (-7px) -21px; 7 | } 8 | &.jslider-pointer-to { 9 | left: 62%; 10 | } 11 | &.jslider-pointer-to.jslider-pointer-hover { 12 | background-position: (-7px) -21px; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/css/sass/main.sass: -------------------------------------------------------------------------------- 1 | // Import Bourbon Mixins 2 | @import ../../../bower_components/bourbon/app/assets/stylesheets/bourbon 3 | 4 | // Main slider css rules 5 | @import core/variables 6 | 7 | // Horizontal Slider 8 | @import horizontal/main 9 | 10 | // Vertical Slider 11 | @import vertical/main 12 | 13 | // Skins 14 | @import skins/skin-css 15 | @import skins/skin-round 16 | @import skins/skin-blue 17 | @import skins/skin-plastic 18 | -------------------------------------------------------------------------------- /src/css/scss/main.scss: -------------------------------------------------------------------------------- 1 | // Import Bourbon Mixins 2 | @import "../../../bower_components/bourbon/app/assets/stylesheets/bourbon"; 3 | 4 | // Main slider css rules 5 | @import "core/variables"; 6 | 7 | // Horizontal Slider 8 | @import "horizontal/main"; 9 | 10 | // Vertical Slider 11 | @import "vertical/main"; 12 | 13 | // Skins 14 | @import "skins/skin-css"; 15 | @import "skins/skin-round"; 16 | @import "skins/skin-blue"; 17 | @import "skins/skin-plastic"; 18 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_scales.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | div.jslider-scale { 3 | position: inherit; 4 | span { 5 | position: absolute; 6 | @include size(5px 1px); 7 | border-left: none; 8 | font-size: 0; 9 | border-top: 1px solid #999; 10 | } 11 | ins { 12 | @include position(absolute, 5px null 0 null); 13 | font-size: 9px; 14 | text-decoration: none; 15 | color: $color-scale; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_labels.sass: -------------------------------------------------------------------------------- 1 | div.jslider-label small, 2 | div.jslider-value small 3 | +position(relative, -0.4em null null null) 4 | 5 | // limits 6 | div.jslider-label 7 | +position(absolute, -18px null 0 null) 8 | padding: 0px 2px 9 | opacity: 0.4 10 | color: $color-pointers-label 11 | font-size: $font-size-pointers-label 12 | line-height: $line-height-pointers-label 13 | white-space: nowrap 14 | 15 | &.jslider-label-to 16 | left: auto 17 | right: 0 18 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_horizontal.sass: -------------------------------------------------------------------------------- 1 | // Horizontal Styles 2 | 3 | .jslider 4 | +position(relative, 0.6em null null null) 5 | cursor: pointer 6 | display: block 7 | +size(100% 1em) 8 | font-family: $font-family-base 9 | 10 | &.disabled 11 | opacity: 0.5 12 | 13 | table 14 | border-collapse: collapse 15 | border: 0 16 | width: 100% 17 | 18 | td, th 19 | width: 100% 20 | border: 0 21 | padding: 0 22 | text-align: left 23 | vertical-align: top 24 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_pointers.sass: -------------------------------------------------------------------------------- 1 | // single value hide to 2 | .jslider-single 3 | div.jslider-pointer-to, 4 | div.jslider-value-to, 5 | div.jslider-bg .v, 6 | .jslider-limitless .jslider-label 7 | display: none 8 | 9 | div.jslider-pointer 10 | +position(absolute, -4px null 20% null) 11 | +size(15px) 12 | background-position: 2px -60px 13 | margin-left: -8px 14 | cursor: hand 15 | z-index: 2 16 | 17 | &.jslider-pointer-to 18 | left: 80% 19 | 20 | &.jslider-pointer-hover 21 | background-position: -19px -60px 22 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_labels.scss: -------------------------------------------------------------------------------- 1 | div.jslider-label small, 2 | div.jslider-value small { 3 | @include position(relative, -0.4em null null null); 4 | } 5 | 6 | // limits 7 | div.jslider-label { 8 | @include position(absolute, -18px null 0 null); 9 | padding: 0px 2px; 10 | opacity: 0.4; 11 | color: $color-pointers-label; 12 | font-size: $font-size-pointers-label; 13 | line-height: $line-height-pointers-label; 14 | white-space: nowrap; 15 | &.jslider-label-to { 16 | left: auto; 17 | right: 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_horizontal.scss: -------------------------------------------------------------------------------- 1 | // Horizontal Styles 2 | 3 | .jslider { 4 | @include position(relative, 0.6em null null null); 5 | cursor: pointer; 6 | display: block; 7 | @include size(100% 1em); 8 | font-family: $font-family-base; 9 | &.disabled { 10 | opacity: 0.5; 11 | } 12 | table { 13 | border-collapse: collapse; 14 | border: 0; 15 | width: 100%; 16 | td, th { 17 | width: 100%; 18 | border: 0; 19 | padding: 0; 20 | text-align: left; 21 | vertical-align: top; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/css/scss/horizontal/_pointers.scss: -------------------------------------------------------------------------------- 1 | // single value hide to 2 | .jslider-single { 3 | div.jslider-pointer-to, 4 | div.jslider-value-to, 5 | div.jslider-bg .v, 6 | .jslider-limitless .jslider-label { 7 | display: none; 8 | } 9 | } 10 | 11 | div.jslider-pointer { 12 | @include position(absolute, -4px null 20% null); 13 | @include size(15px); 14 | background-position: 2px -60px; 15 | margin-left: -8px; 16 | cursor: hand; 17 | z-index: 2; 18 | &.jslider-pointer-to { 19 | left: 80%; 20 | } 21 | &.jslider-pointer-hover { 22 | background-position: (-19px) -60px; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/css/sass/horizontal/_ranges.sass: -------------------------------------------------------------------------------- 1 | div.jslider-bg i, div.jslider-pointer 2 | background: url("../img/jslider.png") no-repeat 0 0 3 | 4 | div.jslider-bg 5 | position: relative 6 | i 7 | +position(absolute, 0 null null null) 8 | height: 5px 9 | 10 | &.left 11 | left: 0 12 | width: 50% 13 | background-position: 0 0 14 | 15 | &.right 16 | left: 50% 17 | width: 50% 18 | background-position: right 0 19 | 20 | &.range 21 | +position(absolute, 0 null null 20%) 22 | +size(60% 5px) 23 | background-repeat: repeat-x 24 | background-position: 0 -40px 25 | z-index: 1 26 | 27 | &.default 28 | left: 0 29 | width: 1px 30 | z-index: 1 31 | background-color: $color-pointers-default-value 32 | -------------------------------------------------------------------------------- /src/core/config/constants.js: -------------------------------------------------------------------------------- 1 | (function(angular){ 2 | 'use strict'; 3 | angular.module('angularAwesomeSlider').constant('sliderConstants', { 4 | SLIDER: { 5 | settings: { 6 | from: 1, 7 | to: 40, 8 | step: 1, 9 | smooth: true, 10 | limits: false, 11 | round: false, 12 | value: "3", 13 | dimension: "", 14 | vertical: false, 15 | calculate: false, 16 | onstatechange: false, 17 | callback: false, 18 | realtime: false 19 | }, 20 | className: "jslider", 21 | selector: ".jslider-", 22 | css: { 23 | visible : { visibility: "visible" }, 24 | hidden : { visibility: "hidden" } 25 | } 26 | }, 27 | EVENTS: { 28 | 29 | } 30 | }); 31 | 32 | }(angular)); -------------------------------------------------------------------------------- /src/css/scss/horizontal/_ranges.scss: -------------------------------------------------------------------------------- 1 | div.jslider-bg i, div.jslider-pointer { 2 | background: url("../img/jslider.png") no-repeat 0 0; 3 | } 4 | 5 | div.jslider-bg { 6 | position: relative; 7 | i { 8 | @include position(absolute, 0 null null null); 9 | height: 5px; 10 | &.left { 11 | left: 0; 12 | width: 50%; 13 | background-position: 0 0; 14 | } 15 | &.right { 16 | left: 50%; 17 | width: 50%; 18 | background-position: right 0; 19 | } 20 | &.range { 21 | @include position(absolute, 0 null null 20%); 22 | @include size(60% 5px); 23 | background-repeat: repeat-x; 24 | background-position: 0 -40px; 25 | z-index: 1; 26 | } 27 | &.default { 28 | left: 0; 29 | width: 1px; 30 | z-index: 1; 31 | background-color: $color-pointers-default-value; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/css/sass/core/_variables.sass: -------------------------------------------------------------------------------- 1 | // Colors 2 | 3 | $black: #000000 4 | $white: #ffffff 5 | $gray: #999999 6 | $gray2: #c2c7Ca 7 | $blue: #185f83 8 | 9 | // Typography 10 | 11 | $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif 12 | $font-family-base: $font-family-sans-serif 13 | $font-size-pointers-label: 9px 14 | $line-height-pointers-label: 12px 15 | $font-size-pointers-value: $font-size-pointers-label 16 | $line-height-pointers-value: $line-height-pointers-label 17 | $color-pointers-label: $black 18 | $color-pointers-value: $color-pointers-label 19 | $color-scale: $gray 20 | $color-pointers-default-value: $blue 21 | 22 | // Skin CSS 23 | 24 | $color-skin-pointers-default-value: $gray2 25 | $color-skin-background: silver 26 | $color-skin-css-pointers-default-value: $white 27 | $color-skin-css-pointers-before-value: rgba(92, 98, 203, 0.89) 28 | $color-skin-css-pointers-after-value: rgb(14, 23, 115) 29 | -------------------------------------------------------------------------------- /src/css/scss/core/_variables.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | 3 | $black: #000000; 4 | $white: #ffffff; 5 | $gray: #999999; 6 | $gray2: #c2c7Ca; 7 | $blue: #185f83; 8 | 9 | // Typography 10 | 11 | $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; 12 | $font-family-base: $font-family-sans-serif; 13 | $font-size-pointers-label: 9px; 14 | $line-height-pointers-label: 12px; 15 | $font-size-pointers-value: $font-size-pointers-label; 16 | $line-height-pointers-value: $line-height-pointers-label; 17 | $color-pointers-label: $black; 18 | $color-pointers-value: $color-pointers-label; 19 | $color-scale: $gray; 20 | $color-pointers-default-value: $blue; 21 | 22 | // Skin CSS 23 | 24 | $color-skin-pointers-default-value: $gray2; 25 | $color-skin-background: silver; 26 | $color-skin-css-pointers-default-value: $white; 27 | $color-skin-css-pointers-before-value: rgba(92, 98, 203, 0.89); 28 | $color-skin-css-pointers-after-value: rgb(14, 23, 115); 29 | -------------------------------------------------------------------------------- /src/css/sass/vertical/_ranges.sass: -------------------------------------------------------------------------------- 1 | .vertical 2 | div.jslider-bg i, 3 | .jslider-pointer 4 | background: url("../img/jslider.vertical.png") no-repeat 0 0 5 | 6 | div.jslider-bg 7 | position: relative 8 | height: 100% 9 | 10 | i 11 | +position(absolute, 0 null null null) 12 | width: 5px 13 | font-size: 0 14 | 15 | &.before 16 | left: 50% 17 | background: none 18 | 19 | &.left 20 | top: 0 21 | left: 50% 22 | height: 50% 23 | background-position: right 0 24 | background-repeat: repeat-y 25 | 26 | &.right 27 | top: 50% 28 | left: 50% 29 | height: 50% 30 | background-position: right 0 31 | background-repeat: repeat-y 32 | 33 | &.range 34 | position: absolute 35 | top: 0 36 | left: 50% 37 | +size(60% 100%) 38 | z-index: 1 39 | background-repeat: repeat-y 40 | background-position: -36px 0px 41 | 42 | &.default 43 | left: 50% 44 | +size(5px 1px) 45 | z-index: 1 46 | background-color: $color-pointers-default-value 47 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-awesome-slider", 3 | "version": "2.4.4", 4 | "author": { 5 | "name": "Julien Valéry", 6 | "email": "darul75@gmail.com" 7 | }, 8 | "homepage": "https://github.com/darul75/angular-awesome-slider", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/darul75/angular-awesome-slider.git" 12 | }, 13 | "keywords": [ 14 | "angular", 15 | "slider", 16 | "control", 17 | "ui" 18 | ], 19 | "main": [ 20 | "./dist/angular-awesome-slider.js", 21 | "./dist/css/angular-awesome-slider.min.css", 22 | "./dist/img/*" 23 | ], 24 | "dependencies": { 25 | "angular": "^1.3.x" 26 | }, 27 | "devDependencies": { 28 | "angular-mocks": "^1.3.x", 29 | "bourbon": "~4.2.2" 30 | }, 31 | "authors": [ 32 | "darul " 33 | ], 34 | "description": "AngularJS directive slider control.", 35 | "license": "MIT", 36 | "ignore": [ 37 | "**/.*", 38 | "node_modules", 39 | "bower_components", 40 | "test", 41 | "tests" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2013 Julien Valéry 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. -------------------------------------------------------------------------------- /src/css/sass/skins/_skin-plastic.sass: -------------------------------------------------------------------------------- 1 | // Plastic Skin 2 | 3 | .jslider_plastic 4 | .jslider-bg i, 5 | .jslider-pointer 6 | background: url("../img/jslider.plastic.png") no-repeat 0 0 7 | 8 | .jslider-bg 9 | i 10 | background-position: 2px -20px 11 | 12 | &.default 13 | background-color: $color-skin-pointers-default-value 14 | 15 | &.range 16 | z-index: 1 17 | background-position: 0 -40px 18 | 19 | .jslider-pointer 20 | z-index: 2 21 | +size(20px 17px) 22 | top: -6px 23 | background-position: 2px -60px 24 | 25 | &.vertical 26 | div.jslider-bg i, 27 | div.jslider-pointer 28 | background: url("../img/jslider.plastic.vertical.png") no-repeat 0 0 29 | 30 | div.jslider-bg 31 | i 32 | background-position: right 0 33 | 34 | &.range 35 | background-position: -35px 0 36 | 37 | &.before, 38 | &.after 39 | background: none 40 | 41 | &.default 42 | background-color: $color-skin-pointers-default-value 43 | 44 | div.jslider-pointer 45 | top: -6px 46 | margin-left: -6px 47 | +size(20px 17px) 48 | background-position: -7px -1px 49 | 50 | &.jslider-pointer-hover 51 | background-position: -7px -21px 52 | -------------------------------------------------------------------------------- /src/css/sass/skins/_skin-blue.sass: -------------------------------------------------------------------------------- 1 | // Blue Skin 2 | 3 | .jslider_blue 4 | .jslider-bg i, 5 | .jslider-pointer 6 | background: url("../img/jslider.blue.png") no-repeat 0 0 7 | 8 | .jslider-bg 9 | i 10 | background-position: 2px -20px 11 | 12 | &.default 13 | background-color: $color-skin-pointers-default-value 14 | 15 | &.range 16 | z-index: 1 17 | background-position: 0 -40px 18 | 19 | div.jslider-pointer 20 | top: -6px 21 | width: 20px 22 | height: 17px 23 | background-position: 2px -60px 24 | z-index: 2 25 | 26 | &.vertical 27 | div.jslider-bg i, 28 | div.jslider-pointer 29 | background: url("../img/jslider.blue.vertical.png") no-repeat 0 0 30 | 31 | div.jslider-bg 32 | i 33 | background-position: right 0 34 | 35 | &.range 36 | background-position: -37px 0 37 | 38 | &.before, 39 | &.after 40 | background: none 41 | 42 | &.default 43 | background-color: $color-skin-pointers-default-value 44 | 45 | div.jslider-pointer 46 | top: -6px 47 | width: 20px 48 | height: 17px 49 | background-position: -7px 0 50 | 51 | &.jslider-pointer-hover 52 | background-position: -7px -20px 53 | 54 | div.jslider-value 55 | left: 0 56 | -------------------------------------------------------------------------------- /src/css/sass/skins/_skin-round.sass: -------------------------------------------------------------------------------- 1 | // Round Skin 2 | 3 | .jslider_round 4 | div.jslider-bg i, 5 | div.jslider-pointer 6 | background: url("../img/jslider.round.png") no-repeat 0 0 7 | 8 | div.jslider-bg 9 | i 10 | background-position: 0 -20px 11 | 12 | &.default 13 | background-color: $gray2 14 | 15 | &.range 16 | z-index: 1 17 | background-position: 0 -40px 18 | 19 | div.jslider-pointer 20 | top: -6px 21 | +size(20px 17px) 22 | background-position: 0 -60px 23 | z-index: 2 24 | 25 | &.vertical 26 | div.jslider-bg i, 27 | div.jslider-pointer 28 | background: url("../img/jslider.round.vertical.png") no-repeat 0 0 29 | 30 | div.jslider-bg 31 | i 32 | background-position: right 0 33 | 34 | &.range 35 | background-position: -37px 0 36 | 37 | &.before, 38 | &.after 39 | background: none 40 | 41 | &.default 42 | background-color: $color-skin-pointers-default-value 43 | 44 | div.jslider-pointer 45 | top: -6px 46 | +size(20px 17px) 47 | background-position: -4px -3px 48 | 49 | &.jslider-pointer-hover 50 | background-position: -4px -23px 51 | 52 | &.jslider-value-to 53 | left: 80% 54 | 55 | div.jslider-value 56 | left: 0 57 | -------------------------------------------------------------------------------- /src/core/utils/utils.factory.js: -------------------------------------------------------------------------------- 1 | (function(angular){ 2 | 'use strict'; 3 | 4 | angular.module('angularAwesomeSlider').factory('sliderUtils', ['$window', function(win) { 5 | return { 6 | offset: function(elm) { 7 | // try {return elm.offset();} catch(e) {} 8 | var rawDom = elm[0]; 9 | var _x = 0; 10 | var _y = 0; 11 | var body = document.documentElement || document.body; 12 | var scrollX = window.pageXOffset || body.scrollLeft; 13 | var scrollY = window.pageYOffset || body.scrollTop; 14 | _x = rawDom.getBoundingClientRect().left + scrollX; 15 | _y = rawDom.getBoundingClientRect().top + scrollY; 16 | return { left: _x, top:_y }; 17 | }, 18 | browser: function() { 19 | // TODO finish browser detection and this case 20 | var userAgent = win.navigator.userAgent; 21 | var browsers = {mozilla: /mozilla/i, chrome: /chrome/i, safari: /safari/i, firefox: /firefox/i, ie: /internet explorer/i}; 22 | for(var key in browsers) { 23 | if (browsers[key].test(userAgent)) { 24 | return key; 25 | } 26 | } 27 | return 'unknown'; 28 | } 29 | }; 30 | }]); 31 | })(angular); 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/css/less/variables.less: -------------------------------------------------------------------------------- 1 | // 2 | // Variables 3 | // -------------------------------------------------- 4 | 5 | 6 | //== Colors 7 | // 8 | 9 | @black: #000; 10 | @white: #fff; 11 | @gray: #999; 12 | @gray2: #C2C7CA; 13 | @blue: #185F83; 14 | 15 | //== Typography 16 | // 17 | 18 | @font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; 19 | @font-family-base: @font-family-sans-serif; 20 | 21 | @font-size-pointers-label: 9px; 22 | @line-height-pointers-label: 12px; 23 | @font-size-pointers-value: @font-size-pointers-label; 24 | @line-height-pointers-value: @line-height-pointers-label; 25 | 26 | @color-pointers-label: @black; 27 | @color-pointers-value: @color-pointers-label; 28 | @color-scale: @gray; 29 | 30 | @color-pointers-default-value: @blue; 31 | 32 | //== Skin CSS 33 | // 34 | 35 | @color-skin-pointers-default-value: @gray2; 36 | 37 | @color-skin-background: silver; 38 | @color-skin-css-pointers-default-value: @white; 39 | @color-skin-css-pointers-before-value: rgba(92, 98, 203, 0.89); 40 | @color-skin-css-pointers-after-value: rgb(14, 23, 115); 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/css/scss/vertical/_ranges.scss: -------------------------------------------------------------------------------- 1 | .vertical { 2 | div.jslider-bg i, 3 | .jslider-pointer { 4 | background: url("../img/jslider.vertical.png") no-repeat 0 0; 5 | } 6 | div.jslider-bg { 7 | position: relative; 8 | height: 100%; 9 | i { 10 | @include position(absolute, 0 null null null); 11 | width: 5px; 12 | font-size: 0; 13 | &.before { 14 | left: 50%; 15 | background: none; 16 | } 17 | &.left { 18 | top: 0; 19 | left: 50%; 20 | height: 50%; 21 | background-position: right 0; 22 | background-repeat: repeat-y; 23 | } 24 | &.right { 25 | top: 50%; 26 | left: 50%; 27 | height: 50%; 28 | background-position: right 0; 29 | background-repeat: repeat-y; 30 | } 31 | &.range { 32 | position: absolute; 33 | top: 0; 34 | left: 50%; 35 | @include size(60% 100%); 36 | z-index: 1; 37 | background-repeat: repeat-y; 38 | background-position: (-36px) 0px; 39 | } 40 | &.default { 41 | left: 50%; 42 | @include size(5px 1px); 43 | z-index: 1; 44 | background-color: $color-pointers-default-value; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-awesome-slider", 3 | "description": "AngularJS directive slider control.", 4 | "version": "2.4.5", 5 | "license": "MIT", 6 | "author": { 7 | "name": "Julien Valéry", 8 | "email": "darul75@gmail.com" 9 | }, 10 | "filename": "./src/ng-slider.js", 11 | "main": "dist/angular-awesome-slider.js", 12 | "homepage": "https://github.com/darul75/angular-awesome-slider", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/darul75/angular-awesome-slider.git" 16 | }, 17 | "keywords": [ 18 | "angular", 19 | "slider", 20 | "control", 21 | "ui" 22 | ], 23 | "bugs": { 24 | "url": "https://github.com/darul75/angular-awesome-slider/issues" 25 | }, 26 | "scripts": { 27 | "test": "grunt test-continuous" 28 | }, 29 | "dependencies": {}, 30 | "devDependencies": { 31 | "grunt": "1.0.4", 32 | "grunt-bower-task": "0.5.0", 33 | "grunt-contrib-concat": "1.0.1", 34 | "grunt-contrib-copy": "1.0.0", 35 | "grunt-contrib-cssmin": "3.0.0", 36 | "grunt-contrib-jshint": "2.1.0", 37 | "grunt-contrib-less": "2.0.0", 38 | "grunt-contrib-uglify": "4.0.1", 39 | "grunt-karma": "3.0.0", 40 | "karma": "3.0.0", 41 | "karma-chrome-launcher": "2.2.0", 42 | "karma-firefox-launcher": "1.1.0", 43 | "karma-jasmine": "2.0.1", 44 | "karma-phantomjs-launcher": "1.0.4" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/core/template/slider.tmpl.js: -------------------------------------------------------------------------------- 1 | (function(angular, undefined) { 2 | 'use strict'; 3 | 4 | angular.module('angularAwesomeSlider') 5 | .run(['$templateCache', function ($templateCache) { 6 | $templateCache.put('ng-slider/slider-bar.tmpl.html', 7 | '' + 8 | '
' + 9 | '
' + 10 | ''+ 11 | ''+ 12 | ''+ 13 | ''+ 14 | ''+ 15 | ''+ 16 | ''+ 17 | '
' + 18 | '
' + 19 | '
' + 20 | '
{{options.dimension}}
' + 21 | '
{{options.dimension}}
' + 22 | '
{{options.dimension}}
' + 23 | '
{{options.dimension}}
' + 24 | '
' + 25 | '
' + 26 | '
'); 27 | }]); 28 | 29 | })(window.angular); 30 | -------------------------------------------------------------------------------- /src/css/scss/skins/_skin-plastic.scss: -------------------------------------------------------------------------------- 1 | // Plastic Skin 2 | 3 | .jslider_plastic { 4 | .jslider-bg i, 5 | .jslider-pointer { 6 | background: url("../img/jslider.plastic.png") no-repeat 0 0; 7 | } 8 | .jslider-bg { 9 | i { 10 | background-position: 2px -20px; 11 | &.default { 12 | background-color: $color-skin-pointers-default-value; 13 | } 14 | &.range { 15 | z-index: 1; 16 | background-position: 0 -40px; 17 | } 18 | } 19 | } 20 | .jslider-pointer { 21 | z-index: 2; 22 | @include size(20px 17px); 23 | top: -6px; 24 | background-position: 2px -60px; 25 | } 26 | &.vertical { 27 | div.jslider-bg i, 28 | div.jslider-pointer { 29 | background: url("../img/jslider.plastic.vertical.png") no-repeat 0 0; 30 | } 31 | div.jslider-bg { 32 | i { 33 | background-position: right 0; 34 | &.range { 35 | background-position: (-35px) 0; 36 | } 37 | &.before, 38 | &.after { 39 | background: none; 40 | } 41 | &.default { 42 | background-color: $color-skin-pointers-default-value; 43 | } 44 | } 45 | } 46 | div.jslider-pointer { 47 | top: -6px; 48 | margin-left: -6px; 49 | @include size(20px 17px); 50 | background-position: (-7px) -1px; 51 | &.jslider-pointer-hover { 52 | background-position: (-7px) -21px; 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/css/scss/skins/_skin-blue.scss: -------------------------------------------------------------------------------- 1 | // Blue Skin 2 | 3 | .jslider_blue { 4 | .jslider-bg i, 5 | .jslider-pointer { 6 | background: url("../img/jslider.blue.png") no-repeat 0 0; 7 | } 8 | .jslider-bg { 9 | i { 10 | background-position: 2px -20px; 11 | &.default { 12 | background-color: $color-skin-pointers-default-value; 13 | } 14 | &.range { 15 | z-index: 1; 16 | background-position: 0 -40px; 17 | } 18 | } 19 | } 20 | div.jslider-pointer { 21 | top: -6px; 22 | width: 20px; 23 | height: 17px; 24 | background-position: 2px -60px; 25 | z-index: 2; 26 | } 27 | &.vertical { 28 | div.jslider-bg i, 29 | div.jslider-pointer { 30 | background: url("../img/jslider.blue.vertical.png") no-repeat 0 0; 31 | } 32 | div.jslider-bg { 33 | i { 34 | background-position: right 0; 35 | &.range { 36 | background-position: (-37px) 0; 37 | } 38 | &.before, 39 | &.after { 40 | background: none; 41 | } 42 | &.default { 43 | background-color: $color-skin-pointers-default-value; 44 | } 45 | } 46 | } 47 | div.jslider-pointer { 48 | top: -6px; 49 | width: 20px; 50 | height: 17px; 51 | background-position: (-7px) 0; 52 | &.jslider-pointer-hover { 53 | background-position: (-7px) -20px; 54 | } 55 | } 56 | div.jslider-value { 57 | left: 0; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/css/scss/skins/_skin-round.scss: -------------------------------------------------------------------------------- 1 | // Round Skin 2 | 3 | .jslider_round { 4 | div.jslider-bg i, 5 | div.jslider-pointer { 6 | background: url("../img/jslider.round.png") no-repeat 0 0; 7 | } 8 | div.jslider-bg { 9 | i { 10 | background-position: 0 -20px; 11 | &.default { 12 | background-color: $gray2; 13 | } 14 | &.range { 15 | z-index: 1; 16 | background-position: 0 -40px; 17 | } 18 | } 19 | } 20 | div.jslider-pointer { 21 | top: -6px; 22 | @include size(20px 17px); 23 | background-position: 0 -60px; 24 | z-index: 2; 25 | } 26 | &.vertical { 27 | div.jslider-bg i, 28 | div.jslider-pointer { 29 | background: url("../img/jslider.round.vertical.png") no-repeat 0 0; 30 | } 31 | div.jslider-bg { 32 | i { 33 | background-position: right 0; 34 | &.range { 35 | background-position: (-37px) 0; 36 | } 37 | &.before, 38 | &.after { 39 | background: none; 40 | } 41 | &.default { 42 | background-color: $color-skin-pointers-default-value; 43 | } 44 | } 45 | } 46 | div.jslider-pointer { 47 | top: -6px; 48 | @include size(20px 17px); 49 | background-position: (-4px) -3px; 50 | &.jslider-pointer-hover { 51 | background-position: (-4px) -23px; 52 | } 53 | &.jslider-value-to { 54 | left: 80%; 55 | } 56 | } 57 | div.jslider-value { 58 | left: 0; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/css/less/skin-plastic.less: -------------------------------------------------------------------------------- 1 | // 2 | // Plastic skin 3 | // -------------------------------------------------- 4 | 5 | &.jslider_plastic { 6 | .jslider-bg i, 7 | .jslider-pointer { 8 | background: url(../img/jslider.plastic.png) no-repeat 0 0; 9 | } 10 | 11 | .jslider-bg { 12 | i { 13 | background-position: 2px -20px; 14 | &.default { 15 | background-color: @color-skin-pointers-default-value; 16 | } 17 | 18 | &.range { 19 | z-index: 1; 20 | background-position: 0 -40px; 21 | } 22 | } 23 | } 24 | 25 | .jslider-pointer { 26 | z-index: 2; 27 | width: 20px; 28 | height: 17px; 29 | top: -4px; 30 | background-position: 2px -60px; 31 | 32 | &.jslider-pointer-hover { 33 | background-position: -18px -60px; 34 | } 35 | } 36 | 37 | &.vertical { 38 | div.jslider-bg i, 39 | div.jslider-pointer { 40 | background: url(../img/jslider.plastic.vertical.png) no-repeat 0 0; 41 | } 42 | 43 | div.jslider-bg { 44 | 45 | i { 46 | background-position: right 0; 47 | 48 | &.range { 49 | background-position: -35px 0; 50 | } 51 | 52 | &.before, 53 | &.after { 54 | background: none; 55 | } 56 | 57 | &.default { 58 | background-color: @color-skin-pointers-default-value; 59 | } 60 | } 61 | } 62 | 63 | div.jslider-pointer { 64 | top: -6px; 65 | margin-left: -6px; 66 | width: 20px; 67 | height: 17px; 68 | background-position: -7px -1px; 69 | 70 | &.jslider-pointer-hover { 71 | background-position: -7px -21px; 72 | } 73 | 74 | } 75 | 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/css/less/skin-blue.less: -------------------------------------------------------------------------------- 1 | // 2 | // Blue skin 3 | // -------------------------------------------------- 4 | 5 | &.jslider_blue { 6 | .jslider-bg i, 7 | .jslider-pointer { 8 | background: url(../img/jslider.blue.png) no-repeat 0 0; 9 | } 10 | 11 | .jslider-bg { 12 | i { 13 | background-position: 2px -20px; 14 | &.default { 15 | background-color: @color-skin-pointers-default-value; 16 | } 17 | 18 | &.range { 19 | z-index: 1; 20 | background-position: 0 -40px; 21 | } 22 | } 23 | } 24 | 25 | div.jslider-pointer { 26 | top: -6px; 27 | width: 20px; 28 | height: 17px; 29 | background-position: 2px -60px; 30 | z-index: 2; 31 | 32 | &.jslider-pointer-hover { 33 | background-position: -20px -60px; 34 | } 35 | } 36 | 37 | &.vertical { 38 | div.jslider-bg i, 39 | div.jslider-pointer { 40 | background: url(../img/jslider.blue.vertical.png) no-repeat 0 0; 41 | } 42 | 43 | div.jslider-bg { 44 | i { 45 | background-position: right 0; 46 | 47 | &.range { 48 | background-position: -37px 0; 49 | } 50 | 51 | &.before, 52 | &.after { 53 | background: none; 54 | } 55 | 56 | &.default { 57 | background-color: @color-skin-pointers-default-value; 58 | } 59 | } 60 | } 61 | 62 | div.jslider-pointer { 63 | top: -6px; 64 | width: 20px; 65 | height: 17px; 66 | background-position: -7px 0; 67 | 68 | &.jslider-pointer-hover { 69 | background-position: -7px -20px; 70 | } 71 | 72 | } 73 | 74 | div.jslider-value { 75 | left: 0; 76 | } 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /src/css/less/skin-round.less: -------------------------------------------------------------------------------- 1 | // 2 | // Round skin 3 | // -------------------------------------------------- 4 | 5 | &.jslider_round { 6 | div.jslider-bg i, 7 | div.jslider-pointer { 8 | background: url(../img/jslider.round.png) no-repeat 0 0; 9 | } 10 | 11 | div.jslider-bg { 12 | i { 13 | background-position: 0 -20px; 14 | &.default { 15 | background-color: #C2C7CA; 16 | } 17 | 18 | &.range { 19 | z-index: 1; 20 | background-position: 0 -40px; 21 | } 22 | } 23 | } 24 | 25 | div.jslider-pointer { 26 | top: -6px; 27 | width: 20px; 28 | height: 17px; 29 | background-position: 0 -60px; 30 | z-index: 2; 31 | 32 | &.jslider-pointer-hover { 33 | background-position: -20px -60px; 34 | } 35 | } 36 | 37 | &.vertical { 38 | div.jslider-bg i, 39 | div.jslider-pointer { 40 | background: url(../img/jslider.round.vertical.png) no-repeat 0 0; 41 | } 42 | 43 | div.jslider-bg { 44 | i { 45 | background-position: right 0; 46 | &.range { 47 | background-position: -37px 0; 48 | } 49 | 50 | &.before, 51 | &.after { 52 | background: none; 53 | } 54 | 55 | &.default { 56 | background-color: @color-skin-pointers-default-value; 57 | } 58 | } 59 | } 60 | 61 | div.jslider-pointer { 62 | top: -6px; 63 | width: 20px; 64 | height: 17px; 65 | background-position: -4px -3px; 66 | 67 | &.jslider-pointer-hover { 68 | background-position: -4px -23px; 69 | } 70 | 71 | &.jslider-value-to { 72 | left: 80%; 73 | } 74 | } 75 | 76 | div.jslider-value { 77 | left: 0; 78 | } 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /test/my.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Wed Nov 06 2013 00:03:21 GMT+0100 (CET) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path, that will be used to resolve files and exclude 8 | basePath: '../', 9 | 10 | 11 | // frameworks to use 12 | frameworks: ['jasmine'], 13 | 14 | 15 | // list of files / patterns to load in the browser 16 | files: [ 17 | 'lib/angular/angular.min.js', 18 | 'lib/angular-mocks/angular-mocks.js', 19 | 'src/*.js', 20 | 'test/*Spec.js' 21 | ], 22 | 23 | 24 | // list of files to exclude 25 | exclude: [ 26 | 27 | ], 28 | 29 | 30 | // test results reporter to use 31 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 32 | reporters: ['progress'], 33 | 34 | 35 | // web server port 36 | port: 9876, 37 | 38 | 39 | // enable / disable colors in the output (reporters and logs) 40 | colors: true, 41 | 42 | 43 | // level of logging 44 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 45 | logLevel: config.LOG_INFO, 46 | 47 | 48 | // enable / disable watching file and executing tests whenever any file changes 49 | autoWatch: true, 50 | 51 | 52 | // Start these browsers, currently available: 53 | // - Chrome 54 | // - ChromeCanary 55 | // - Firefox 56 | // - Opera (has to be installed with `npm install karma-opera-launcher`) 57 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) 58 | // - PhantomJS 59 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) 60 | // browsers: ['Chrome', 'PhantomJS'], 61 | browsers: ['PhantomJS'], 62 | 63 | 64 | // If browser does not capture in given timeout [ms], kill it 65 | captureTimeout: 60000, 66 | 67 | 68 | // Continuous Integration mode 69 | // if true, it capture browsers, run tests and exit 70 | singleRun: true 71 | }); 72 | }; 73 | -------------------------------------------------------------------------------- /test/prettySpec.js: -------------------------------------------------------------------------------- 1 | describe('ngSlider', function () { 2 | var testDirective, 3 | noop = angular.noop, 4 | scope, 5 | fixture = function fixture($compile, $rootScope, $timeout) { 6 | scope = $rootScope.$new(); 7 | scope.options = options; 8 | scope.value = 40; 9 | scope.value2 = 10; 10 | scope.value3 = 90; 11 | 12 | 13 | /** 14 | * Compiles markup and compares resulting output to expected.s 15 | * @param {string} markup Markup to compile 16 | * @param {value} slider value to compare with position generated 17 | */ 18 | return function tester(markup, value) { 19 | 20 | var element = $compile(markup)(scope); 21 | scope.$digest(); 22 | 23 | $timeout.flush(2000); 24 | 25 | var sliderDom = element.next(); 26 | angular.element(document.body).append(sliderDom); 27 | 28 | // fetch first pointer 29 | var prcPosition = angular.element(sliderDom.find("div")[1]).css("left").replace("%", ""); 30 | 31 | // force re-rendering 32 | angular.element(window).triggerHandler("resize"); 33 | 34 | expect(prcPosition).toBeLessThan(value+1); 35 | expect(prcPosition).toBeGreaterThan(value-1); 36 | 37 | return element; 38 | }; 39 | }, 40 | 41 | obj; 42 | 43 | beforeEach(module('angularAwesomeSlider')); 44 | 45 | beforeEach(inject(function ($injector) { 46 | options = { 47 | from: 1, 48 | to: 100, 49 | step: 1, 50 | dimension: " km", 51 | css: { 52 | background: {"background-color": "silver"}, 53 | before: {"background-color": "purple"}, 54 | default: {"background-color": "white"}, 55 | after: {"background-color": "green"}, 56 | pointer: {"background-color": "red"} 57 | } 58 | }; 59 | testDirective = $injector.invoke(fixture); 60 | })); 61 | 62 | describe('slider directive', function () { 63 | it('horizontal ', function () { 64 | testDirective('', scope.value); 65 | }); 66 | 67 | it('simple', function () { 68 | testDirective('', scope.value2); 69 | }); 70 | 71 | it('simple', function () { 72 | testDirective('', scope.value3); 73 | }); 74 | }); 75 | 76 | }); 77 | -------------------------------------------------------------------------------- /src/css/sass/skins/_skin-css.sass: -------------------------------------------------------------------------------- 1 | $skin-gray: #777575 2 | $skin-gray-2: #615959 3 | 4 | // Main slider custom overrided js css rules 5 | 6 | .sliderCSS 7 | div.jslider-bg 8 | i 9 | &.left 10 | left: 0 11 | width: 50% 12 | background-color: $color-skin-background 13 | background-image: none 14 | 15 | &.right 16 | width: 50% 17 | left: 50% 18 | background-color: $color-skin-background 19 | background-image: none 20 | 21 | &.before 22 | left: 0 23 | width: 1px 24 | background-color: $color-skin-css-pointers-before-value 25 | background-image: none 26 | 27 | &.default 28 | left: 0 29 | width: 1px 30 | z-index: 1 31 | background-color: $color-skin-css-pointers-default-value 32 | background-image: none 33 | 34 | &.after 35 | left: 0 36 | background-color: $color-skin-css-pointers-after-value 37 | background-image: none 38 | 39 | &.range 40 | +position(absolute, 0 null 20% null) 41 | +size(60% 5px) 42 | background-image: none 43 | background-color: $skin-gray 44 | z-index: 1 45 | 46 | div.jslider-pointer 47 | top: -3px 48 | left: 15px 49 | +size(10px) 50 | background-color: silver 51 | background-color: $skin-gray-2 52 | border-radius: 50% 53 | 54 | div.jslider-bg i, div.jslider-pointer 55 | background: none 56 | 57 | // vertical 58 | &.vertical 59 | td { 60 | height: 100%; 61 | } 62 | div.jslider-bg 63 | i 64 | left: 50% 65 | width: 5px 66 | 67 | &.left 68 | top: 0 69 | height: 50% 70 | background-color: $color-skin-background 71 | background-image: none 72 | 73 | &.right 74 | height: 50% 75 | top: 50% 76 | background-color: $color-skin-background 77 | background-image: none 78 | 79 | &.range 80 | height: 100% 81 | z-index: 1 82 | background-color: $skin-gray 83 | background-image: none 84 | 85 | &.before 86 | background-color: $color-skin-css-pointers-before-value 87 | background-image: none 88 | 89 | &.default 90 | height: 1px 91 | background-color: $color-skin-css-pointers-default-value 92 | background-image: none 93 | z-index: 2 94 | 95 | &.after 96 | background-color: $color-skin-css-pointers-after-value 97 | background-image: none 98 | 99 | div.jslider-bg i, div.jslider-pointer 100 | background: none 101 | 102 | div.jslider-pointer 103 | left: 50% 104 | +size(10px) 105 | background-color: $skin-gray-2 106 | border-radius: 50% 107 | margin-left: -3px 108 | 109 | &.jslider-pointer-to 110 | left: 50% 111 | -------------------------------------------------------------------------------- /src/css/scss/skins/_skin-css.scss: -------------------------------------------------------------------------------- 1 | $skin-gray: #777575; 2 | $skin-gray-2: #615959; 3 | 4 | // Main slider custom overrided js css rules 5 | 6 | .sliderCSS { 7 | div.jslider-bg { 8 | i { 9 | &.left { 10 | left: 0; 11 | width: 50%; 12 | background-color: $color-skin-background; 13 | background-image: none; 14 | } 15 | &.right { 16 | width: 50%; 17 | left: 50%; 18 | background-color: $color-skin-background; 19 | background-image: none; 20 | } 21 | &.before { 22 | left: 0; 23 | width: 1px; 24 | background-color: $color-skin-css-pointers-before-value; 25 | background-image: none; 26 | } 27 | &.default { 28 | left: 0; 29 | width: 1px; 30 | z-index: 1; 31 | background-color: $color-skin-css-pointers-default-value; 32 | background-image: none; 33 | } 34 | &.after { 35 | left: 0; 36 | background-color: $color-skin-css-pointers-after-value; 37 | background-image: none; 38 | } 39 | &.range { 40 | @include position(absolute, 0 null 20% null); 41 | @include size(60% 5px); 42 | background-image: none; 43 | background-color: $skin-gray; 44 | z-index: 1; 45 | } 46 | } 47 | } 48 | div.jslider-pointer { 49 | top: -3px; 50 | left: 15px; 51 | @include size(10px); 52 | background-color: silver; 53 | background-color: $skin-gray-2; 54 | border-radius: 50%; 55 | } 56 | div.jslider-bg i, div.jslider-pointer { 57 | background: none; 58 | } 59 | // vertical 60 | &.vertical { 61 | td { 62 | height: 100%; 63 | } 64 | div.jslider-bg { 65 | i { 66 | left: 50%; 67 | width: 5px; 68 | &.left { 69 | top: 0; 70 | height: 50%; 71 | background-color: $color-skin-background; 72 | background-image: none; 73 | } 74 | &.right { 75 | height: 50%; 76 | top: 50%; 77 | background-color: $color-skin-background; 78 | background-image: none; 79 | } 80 | &.range { 81 | height: 100%; 82 | z-index: 1; 83 | background-color: $skin-gray; 84 | background-image: none; 85 | } 86 | &.before { 87 | background-color: $color-skin-css-pointers-before-value; 88 | background-image: none; 89 | } 90 | &.default { 91 | height: 1px; 92 | background-color: $color-skin-css-pointers-default-value; 93 | background-image: none; 94 | z-index: 2; 95 | } 96 | &.after { 97 | background-color: $color-skin-css-pointers-after-value; 98 | background-image: none; 99 | } 100 | } 101 | } 102 | div.jslider-bg i, div.jslider-pointer { 103 | background: none; 104 | } 105 | div.jslider-pointer { 106 | left: 50%; 107 | @include size(10px); 108 | background-color: $skin-gray-2; 109 | border-radius: 50%; 110 | margin-left: -3px; 111 | &.jslider-pointer-to { 112 | left: 50%; 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/css/less/skin-css.less: -------------------------------------------------------------------------------- 1 | // 2 | // Main slider custom overrided js css rules 3 | // -------------------------------------------------- 4 | &.sliderCSS { 5 | 6 | div.jslider-bg { 7 | 8 | i { 9 | &.left { 10 | left: 0; 11 | width: 50%; 12 | background-color: @color-skin-background; 13 | background-image: none; 14 | } 15 | &.right { 16 | width: 50%; 17 | left: 50%; 18 | background-color: @color-skin-background; 19 | background-image: none; 20 | } 21 | &.before { 22 | left: 0; 23 | width: 1px; 24 | background-color: @color-skin-css-pointers-before-value; 25 | background-image: none; 26 | } 27 | &.default { 28 | left: 0; 29 | width: 1px; 30 | z-index: 1; 31 | background-color: @color-skin-css-pointers-default-value; 32 | background-image: none; 33 | } 34 | &.after { 35 | left: 0; 36 | background-color: @color-skin-css-pointers-after-value; 37 | background-image: none; 38 | } 39 | &.range { 40 | position: absolute; 41 | top: 0; 42 | left: 20%; 43 | width: 60%; 44 | height: 5px; 45 | z-index: 1; 46 | background-image: none; 47 | background-color: #777575 48 | } 49 | } 50 | } 51 | 52 | div.jslider-pointer { 53 | top: -3px; 54 | left: 15px; 55 | width: 10px; 56 | height: 10px; 57 | margin-left: -5px; 58 | background-color: silver; 59 | background-color: #615959; 60 | border-radius: 50%; 61 | } 62 | 63 | div.jslider-bg i,div.jslider-pointer { 64 | background: none; 65 | } 66 | 67 | // vertical 68 | &.vertical { 69 | 70 | td { 71 | height: 100%; 72 | } 73 | 74 | div.jslider-bg { 75 | 76 | i { 77 | left: 50%; 78 | width: 5px; 79 | 80 | &.left { 81 | top: 0; 82 | height: 50%; 83 | background-color: @color-skin-background; 84 | background-image: none; 85 | } 86 | 87 | &.right { 88 | height: 50%; 89 | top: 50%; 90 | background-color: @color-skin-background; 91 | background-image: none; 92 | } 93 | 94 | &.range { 95 | height: 100%; 96 | z-index: 1; 97 | background-color: #777575; 98 | background-image: none; 99 | } 100 | 101 | &.before { 102 | background-color: @color-skin-css-pointers-before-value; 103 | background-image: none; 104 | } 105 | 106 | &.default { 107 | height: 1px; 108 | background-color: @color-skin-css-pointers-default-value; 109 | background-image: none; 110 | z-index: 2; 111 | } 112 | 113 | &.after { 114 | background-color: @color-skin-css-pointers-after-value; 115 | background-image: none; 116 | } 117 | 118 | } 119 | 120 | } 121 | 122 | div.jslider-bg i,div.jslider-pointer { 123 | background: none; 124 | } 125 | 126 | div.jslider-pointer { 127 | left: 50%; 128 | width: 10px; 129 | height: 10px; 130 | background-color: #615959; 131 | border-radius: 50%; 132 | margin-left: -3px; 133 | 134 | &.jslider-pointer-to { 135 | left: 50%; 136 | } 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/core/model/pointer.factory.js: -------------------------------------------------------------------------------- 1 | (function(angular){ 2 | 'use strict'; 3 | 4 | angular.module('angularAwesomeSlider').factory('sliderPointer', ['sliderDraggable', 'sliderUtils', function(Draggable, utils) { 5 | 6 | function SliderPointer() { 7 | Draggable.apply(this, arguments); 8 | } 9 | 10 | SliderPointer.prototype = new Draggable(); 11 | 12 | SliderPointer.prototype.oninit = function( ptr, id, vertical, label, _constructor ) { 13 | this.uid = id; 14 | this.parent = _constructor; 15 | this.value = {}; 16 | this.vertical = vertical; 17 | this.settings = angular.copy(_constructor.settings); 18 | this.threshold = this.settings.threshold; 19 | }; 20 | 21 | SliderPointer.prototype.onmousedown = function( evt ) { 22 | var off = utils.offset(this.parent.domNode); 23 | 24 | var offset = { 25 | left: off.left, 26 | top: off.top, 27 | width: this.parent.domNode[0].clientWidth, 28 | height: this.parent.domNode[0].clientHeight 29 | }; 30 | 31 | this._parent = { 32 | offset: offset, 33 | width: offset.width, 34 | height: offset.height 35 | }; 36 | 37 | this.ptr.addClass('jslider-pointer-hover'); 38 | }; 39 | 40 | SliderPointer.prototype.onmousemove = function( evt, x, y ){ 41 | var coords = this._getPageCoords( evt ); 42 | this._set(!this.vertical ? this.calc( coords.x ) : this.calc( coords.y )); 43 | if( this.settings.realtime && this.settings.cb && angular.isFunction(this.settings.cb) ) 44 | this.settings.cb.call( this.parent, this.parent.getValue(), !this.is.drag ); 45 | }; 46 | 47 | SliderPointer.prototype.onmouseup = function(evt){ 48 | if( this.settings.cb && angular.isFunction(this.settings.cb)) 49 | this.settings.cb.call( this.parent, this.parent.getValue(), !this.is.drag ); 50 | 51 | if (!this.is.drag) 52 | this.ptr.removeClass('jslider-pointer-hover'); 53 | }; 54 | 55 | SliderPointer.prototype.limits = function( x ){ 56 | return this.parent.limits(x, this); 57 | }; 58 | 59 | SliderPointer.prototype.calc = function( coords ){ 60 | return !this.vertical ? 61 | this.limits(((coords-this._parent.offset.left)*100)/this._parent.width) 62 | : 63 | this.limits(((coords-this._parent.offset.top)*100)/this._parent.height); 64 | }; 65 | 66 | SliderPointer.prototype.set = function( value, opt_origin ){ 67 | this.value.origin = this.parent.round(value); 68 | this._set(this.parent.valueToPrc(value,this), opt_origin); 69 | }; 70 | 71 | SliderPointer.prototype._set = function( prc, opt_origin ){ 72 | this.allowed = true; 73 | 74 | var oldOrigin = this.value.origin; 75 | var oldPerc = this.value.prc; 76 | 77 | this.value.origin = this.parent.prcToValue(prc); 78 | this.value.prc = prc; 79 | 80 | // check threshold 81 | if (this.threshold && this.parent.o.pointers[1]) { 82 | var v1 = this.value.origin, 83 | v2 = this.parent.o.pointers[this.uid === 0 ? 1:0].value.origin; 84 | this.allowed = Math.abs(v2 - v1) >= this.threshold; 85 | if (!this.allowed && oldOrigin !== undefined && oldPerc !== undefined){ 86 | this.value.origin = oldOrigin; 87 | this.value.prc = oldPerc; 88 | } 89 | } 90 | 91 | if (!this.vertical) 92 | this.ptr.css({left:this.value.prc+'%'}); 93 | else 94 | this.ptr.css({top:this.value.prc+'%', marginTop: -5}); 95 | this.parent.redraw(this); 96 | }; 97 | 98 | return SliderPointer; 99 | }]); 100 | }(angular)); 101 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | pkg: grunt.file.readJSON('package.json'), 7 | jshint: { 8 | files: ['src/core/**/*.js', 'test/**/*.js'] 9 | }, 10 | // BOWER 11 | bower: { 12 | install: { 13 | options: { 14 | targetDir: './bower_components' 15 | } 16 | } 17 | }, 18 | // KARMA TASK CONFIG 19 | karma: { 20 | options: { 21 | basePath: './', 22 | frameworks: ['jasmine'], 23 | files: [ 24 | 'bower_components/angular/angular.js', 25 | 'bower_components/angular-mocks/angular-mocks.js', 26 | 'dist/angular-awesome-slider.min.js', 27 | /*'src/core/ng-slider.js', 28 | 'src/core/config/constants.js', 29 | 'src/core/model/draggable.factory.js', 30 | 'src/core/model/pointer.factory.js', 31 | 'src/core/model/slider.factory.js', 32 | 'src/core/utils/utils.factory.js', 33 | 'src/core/template/slider.tmpl.js',*/ 34 | 'dist/css/angular-awesome-slider.min.css', 35 | 'test/**/*Spec.js' 36 | ], 37 | autoWatch: true, 38 | singleRun: true 39 | }, 40 | unit: { 41 | options: { 42 | browsers: ['PhantomJS'] 43 | } 44 | }, 45 | captureTimeout: 20000, 46 | continuous: { 47 | options: { 48 | browsers: ['PhantomJS'] 49 | } 50 | } 51 | }, 52 | // LESS CSS TASKS 53 | less: { 54 | development: { 55 | options: { 56 | paths: ['src/css/less/'] 57 | }, 58 | files: { 59 | 'src/css/angular-awesome-slider.css': 'src/css/less/main.less' 60 | } 61 | } 62 | }, 63 | // UGLIFY TASK 64 | uglify: { 65 | task1: { 66 | options: { 67 | preserveComments: 'some', 68 | report: 'min', 69 | banner: '/** \n* @license <%= pkg.name %> - v<%= pkg.version %>\n' + 70 | '* (c) 2013 Julien VALERY https://github.com/darul75/angular-awesome-slider\n' + 71 | '* License: MIT \n**/\n' 72 | }, 73 | files: { 74 | 'dist/angular-awesome-slider.min.js': ['dist/angular-awesome-slider.js'] 75 | /*'dist/ng-slider.tmpl.min.js': ['src/ng-slider.tmpl.js']*/ 76 | } 77 | } 78 | }, 79 | // CONCAT FILES 80 | concat: { 81 | options: { 82 | separator: ';' 83 | }, 84 | dist: { 85 | src: [ 86 | 'src/core/index.js', 87 | 'src/core/config/constants.js', 88 | 'src/core/utils/utils.factory.js', 89 | 'src/core/model/draggable.factory.js', 90 | 'src/core/model/pointer.factory.js', 91 | 'src/core/model/slider.factory.js', 92 | 'src/core/template/slider.tmpl.js' 93 | ], 94 | dest: 'dist/angular-awesome-slider.js' 95 | } 96 | }, 97 | // MINIFY CSS 98 | cssmin: { 99 | options: { 100 | keepSpecialComments: false, 101 | banner: '/** \n* @license <%= pkg.name %> - v<%= pkg.version %>\n' + 102 | '* (c) 2013 Julien VALERY https://github.com/darul75/angular-awesome-slider\n' + 103 | '* License: MIT \n**/\n' 104 | }, 105 | compress: { 106 | files: { 107 | 'dist/css/angular-awesome-slider.min.css': ['src/css/angular-awesome-slider.css'] 108 | } 109 | } 110 | }, 111 | // COPY CONTENT 112 | copy: { 113 | main: { 114 | files: [ 115 | // slider 116 | {expand: true, flatten: true, src: ['src/img/*'], dest: 'dist/img/'}, 117 | ] 118 | } 119 | }, 120 | }); 121 | 122 | // LOAD PLUGINS 123 | grunt.loadNpmTasks('grunt-bower-task'); 124 | grunt.loadNpmTasks('grunt-contrib-copy'); 125 | grunt.loadNpmTasks('grunt-contrib-concat'); 126 | grunt.loadNpmTasks('grunt-contrib-jshint'); 127 | grunt.loadNpmTasks('grunt-contrib-less'); 128 | grunt.loadNpmTasks('grunt-contrib-uglify'); 129 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 130 | grunt.loadNpmTasks('grunt-karma'); 131 | 132 | // TASK REGISTER 133 | //grunt.registerTask('default', ['jshint', 'cssmin', 'uglify:task1', 'karma']); 134 | grunt.registerTask('default', ['bower', 'copy', 'concat', 'less', 'cssmin', 'jshint', 'uglify:task1']); 135 | grunt.registerTask('test-continuous', ['jshint', 'bower', 'karma:unit']); 136 | }; 137 | -------------------------------------------------------------------------------- /src/core/model/draggable.factory.js: -------------------------------------------------------------------------------- 1 | (function(angular){ 2 | 'use strict'; 3 | 4 | angular.module('angularAwesomeSlider').factory('sliderDraggable', ['sliderUtils', function(utils) { 5 | 6 | function Draggable(){ 7 | this._init.apply( this, arguments ); 8 | } 9 | 10 | Draggable.prototype.oninit = function(){ 11 | }; 12 | 13 | Draggable.prototype.events = function(){ 14 | }; 15 | 16 | Draggable.prototype.onmousedown = function(){ 17 | this.ptr.css({ position: 'absolute' }); 18 | }; 19 | 20 | Draggable.prototype.onmousemove = function( evt, x, y ){ 21 | this.ptr.css({ left: x, top: y }); 22 | }; 23 | 24 | Draggable.prototype.onmouseup = function(){}; 25 | 26 | Draggable.prototype.isDefault = { 27 | drag: false, 28 | clicked: false, 29 | toclick: true, 30 | mouseup: false 31 | }; 32 | 33 | Draggable.prototype._init = function() { 34 | if( arguments.length > 0 ){ 35 | this.ptr = arguments[0]; 36 | this.label = arguments[3]; 37 | this.parent = arguments[2]; 38 | 39 | if (!this.ptr) 40 | return; 41 | //this.outer = $(".draggable-outer"); 42 | 43 | this.is = {}; 44 | angular.extend( this.is, this.isDefault ); 45 | var offset = utils.offset(this.ptr); 46 | 47 | this.d = { 48 | left: offset.left, 49 | top: offset.top, 50 | width: this.ptr[0].clientWidth, 51 | height: this.ptr[0].clientHeight 52 | }; 53 | 54 | this.oninit.apply( this, arguments ); 55 | 56 | this._events(); 57 | } 58 | }; 59 | 60 | Draggable.prototype._getPageCoords = function( event ){ 61 | if( event.targetTouches && event.targetTouches[0] ){ 62 | return { x: event.targetTouches[0].pageX, y: event.targetTouches[0].pageY }; 63 | } else 64 | return { x: event.pageX, y: event.pageY }; 65 | }; 66 | 67 | Draggable.prototype._bindEvent = function( ptr, eventType, handler ){ 68 | var self = this; 69 | 70 | // PS need to bind to touch and non-touch events for devices which support both 71 | if( this.supportTouches_ ){ 72 | ptr[0].addEventListener( this.events_[ eventType ].touch, handler, false ); 73 | } 74 | 75 | ptr.bind( this.events_[ eventType ].nonTouch, handler ); 76 | }; 77 | 78 | Draggable.prototype._events = function(){ 79 | var self = this; 80 | 81 | this.supportTouches_ = 'ontouchend' in document; 82 | this.events_ = { 83 | 'click': { touch : 'touchstart', nonTouch : 'click' }, 84 | 'down': { touch : 'touchstart', nonTouch : 'mousedown' }, 85 | 'move': { touch : 'touchmove', nonTouch : 'mousemove' }, 86 | 'up' : { touch : 'touchend', nonTouch: 'mouseup'}, 87 | 'mousedown' : { touch : 'mousedown', nonTouch : 'mousedown' } 88 | }; 89 | 90 | var documentElt = angular.element(window.document); 91 | 92 | this._bindEvent(documentElt, 'move', function(event) { 93 | if(self.is.drag) { 94 | event.stopPropagation(); 95 | event.preventDefault(); 96 | if (!self.parent.disabled) { 97 | self._mousemove(event); 98 | } 99 | } 100 | }); 101 | this._bindEvent(documentElt, 'down', function(event) { 102 | if(self.is.drag) { 103 | event.stopPropagation(); 104 | event.preventDefault(); 105 | } 106 | }); 107 | this._bindEvent(documentElt, 'up', function(event) { 108 | self._mouseup(event); 109 | }); 110 | 111 | this._bindEvent( this.label, 'down', function(event) { 112 | self._mousedown( event ); 113 | return false; 114 | }); 115 | this._bindEvent( this.label, 'up', function(event) { 116 | self._mouseup( event ); 117 | }); 118 | 119 | this._bindEvent( this.ptr, 'down', function(event) { 120 | self._mousedown( event ); 121 | return false; 122 | }); 123 | this._bindEvent( this.ptr, 'up', function(event) { 124 | self._mouseup( event ); 125 | }); 126 | 127 | // TODO see if needed 128 | this.events(); 129 | }; 130 | 131 | Draggable.prototype._mousedown = function( evt ){ 132 | this.is.drag = true; 133 | this.is.clicked = false; 134 | this.is.mouseup = false; 135 | 136 | var coords = this._getPageCoords( evt ); 137 | this.cx = coords.x - this.ptr[0].offsetLeft; 138 | this.cy = coords.y - this.ptr[0].offsetTop; 139 | 140 | angular.extend(this.d, { 141 | left: coords.x, 142 | top: coords.y, 143 | width: this.ptr[0].clientWidth, 144 | height: this.ptr[0].clientHeight 145 | }); 146 | 147 | if( this.outer && this.outer.get(0) ){ 148 | this.outer.css({ height: Math.max(this.outer.height(), $(document.body).height()), overflow: 'hidden' }); 149 | } 150 | 151 | this.onmousedown( evt ); 152 | }; 153 | 154 | Draggable.prototype._mousemove = function( evt ){ 155 | this.is.toclick = false; 156 | var coords = this._getPageCoords( evt ); 157 | this.onmousemove( evt, coords.x - this.cx, coords.y - this.cy ); 158 | }; 159 | 160 | Draggable.prototype._mouseup = function( evt ){ 161 | var oThis = this; 162 | 163 | if( this.is.drag ){ 164 | this.is.drag = false; 165 | 166 | var browser = utils.browser(); 167 | 168 | if( this.outer && this.outer.get(0) ) { 169 | 170 | if( browser === 'mozilla' ){ 171 | this.outer.css({ overflow: "hidden" }); 172 | } else { 173 | this.outer.css({ overflow: "visible" }); 174 | } 175 | 176 | // TODO finish browser detection and this case, remove following line 177 | this.outer.css({ height: "auto" }); 178 | // if( browser === 'ie' && $.browser.version == '6.0' ){ 179 | // this.outer.css({ height: "100%" }); 180 | // } else { 181 | // this.outer.css({ height: "auto" }); 182 | // } 183 | 184 | } 185 | 186 | this.onmouseup( evt ); 187 | } 188 | }; 189 | 190 | return Draggable; 191 | }]); 192 | }(angular)); 193 | -------------------------------------------------------------------------------- /src/core/index.js: -------------------------------------------------------------------------------- 1 | (function (angular) { 2 | 'use strict'; 3 | 4 | angular.module('angularAwesomeSlider', []) 5 | // DIRECTIVE 6 | .directive('slider', [ 7 | '$compile', '$templateCache','$timeout', '$window', 'slider', 8 | function(compile, templateCache, timeout, win, Slider) { 9 | return { 10 | restrict : 'AE', 11 | require: '?ngModel', 12 | scope: { options:'=', ngDisabled: '='}, 13 | priority: 1, 14 | link : function(scope, element, attrs, ngModel) { 15 | 16 | if(!ngModel) return; 17 | 18 | if (!scope.options) 19 | throw new Error('You must provide a value for "options" attribute.'); 20 | 21 | var injector = angular.injector(); 22 | 23 | // options as inline variable 24 | if (angular.isString(scope.options)) { 25 | scope.options = angular.toJson(scope.options); 26 | } 27 | 28 | scope.mainSliderClass = 'jslider'; 29 | scope.mainSliderClass += scope.options.skin ? ' jslider_' + scope.options.skin : ' '; 30 | scope.mainSliderClass += scope.options.vertical ? ' vertical ' : ''; 31 | scope.mainSliderClass += scope.options.css ? ' sliderCSS' : ''; 32 | scope.mainSliderClass += scope.options.className ? ' ' + scope.options.className : ''; 33 | 34 | // handle limit labels visibility 35 | scope.options.limits = angular.isDefined(scope.options.limits) ? scope.options.limits : true; 36 | 37 | // compile template 38 | element.after(compile(templateCache.get('ng-slider/slider-bar.tmpl.html'))(scope, function(clonedElement, scope) { 39 | scope.tmplElt = clonedElement; 40 | })); 41 | 42 | // init 43 | 44 | var initialized = false; 45 | 46 | var init = function(value) { 47 | scope.from = ''+scope.options.from; 48 | scope.to = ''+scope.options.to; 49 | if (scope.options.calculate && angular.isFunction(scope.options.calculate)) { 50 | scope.from = scope.options.calculate(scope.from); 51 | scope.to = scope.options.calculate(scope.to); 52 | } 53 | 54 | var OPTIONS = { 55 | from: !scope.options.round ? parseInt(scope.options.from, 10) : parseFloat(scope.options.from), 56 | to: !scope.options.round ? parseInt(scope.options.to, 10) : parseFloat(scope.options.to), 57 | step: scope.options.step, 58 | smooth: scope.options.smooth, 59 | limits: scope.options.limits, 60 | round: scope.options.round || false, 61 | value: value || ngModel.$viewValue, 62 | dimension: '', 63 | scale: scope.options.scale, 64 | modelLabels: scope.options.modelLabels, 65 | vertical: scope.options.vertical, 66 | css: scope.options.css, 67 | className: scope.options.className, 68 | realtime: scope.options.realtime, 69 | cb: forceApply, 70 | threshold: scope.options.threshold, 71 | heterogeneity: scope.options.heterogeneity, 72 | logScale: scope.options.logScale 73 | }; 74 | 75 | OPTIONS.calculate = scope.options.calculate || undefined; 76 | OPTIONS.onstatechange = scope.options.onstatechange || undefined; 77 | 78 | // slider 79 | scope.slider = !scope.slider ? slidering(element, scope.tmplElt, OPTIONS) : scope.slider.init(element, scope.tmplElt, OPTIONS); 80 | 81 | if (!initialized) { 82 | initListener(); 83 | } 84 | 85 | // scale 86 | var scaleDiv = scope.tmplElt.find('div')[7]; 87 | angular.element(scaleDiv).html(scope.slider.generateScale()); 88 | scope.slider.drawScale(scaleDiv); 89 | 90 | if (scope.ngDisabled) { 91 | disabler(scope.ngDisabled); 92 | } 93 | 94 | initialized = true; 95 | }; 96 | 97 | function initListener() { 98 | // window resize listener 99 | angular.element(win).bind('resize', function(event) { 100 | scope.slider.onresize(); 101 | }); 102 | } 103 | 104 | // model -> view 105 | ngModel.$render = function () { 106 | //elm.html(ctrl.$viewValue); 107 | var singleValue = false; 108 | 109 | if (!ngModel.$viewValue && ngModel.$viewValue !== 0) { 110 | return; 111 | } 112 | 113 | if (typeof(ngModel.$viewValue) === 'number') { 114 | ngModel.$viewValue = ''+ngModel.$viewValue; 115 | } 116 | 117 | if( !ngModel.$viewValue.split(';')[1]) { 118 | scope.mainSliderClass += ' jslider-single'; 119 | } 120 | else { 121 | scope.mainSliderClass = scope.mainSliderClass.replace(' jslider-single', ''); 122 | } 123 | 124 | if (scope.slider) { 125 | var vals = ngModel.$viewValue.split(";"); 126 | scope.slider.getPointers()[0].set(vals[0], true); 127 | if (vals[1]) { 128 | scope.slider.getPointers()[1].set(vals[1], true); 129 | //if moving left to right with two pointers 130 | //we need to "finish" moving the first 131 | if(parseInt(vals[1]) > parseInt(vals[0])){ 132 | scope.slider.getPointers()[0].set(vals[0], true); 133 | } 134 | } 135 | } 136 | 137 | }; 138 | 139 | scope.$on('slider-value-update', function(e, msg){ 140 | init(msg.value); 141 | timeout(function(){ 142 | scope.slider.redrawPointers(); 143 | }); 144 | }); 145 | 146 | // view -> model 147 | var forceApply = function(value, released) { 148 | if (scope.disabled) 149 | return; 150 | scope.$apply(function() { 151 | ngModel.$setViewValue(value); 152 | }); 153 | if (scope.options.callback){ 154 | scope.options.callback(value, released); 155 | } 156 | }; 157 | 158 | // watch options 159 | scope.$watch('options', function(value) { 160 | timeout(function(){ 161 | init(); 162 | }); 163 | }, scope.watchOptions || true); 164 | 165 | // disabling 166 | var disabler = function(value) { 167 | scope.disabled = value; 168 | if (scope.slider) { 169 | scope.tmplElt.toggleClass('disabled'); 170 | scope.slider.disable(value); 171 | } 172 | }; 173 | 174 | scope.$watch('ngDisabled', function(value) { 175 | disabler(value); 176 | }); 177 | 178 | scope.limitValue = function(value) { 179 | if (scope.options.modelLabels) { 180 | if (angular.isFunction(scope.options.modelLabels)) { 181 | return scope.options.modelLabels(value); 182 | } 183 | return scope.options.modelLabels[value] !== undefined ? scope.options.modelLabels[value] : value; 184 | } 185 | return value; 186 | }; 187 | 188 | var slidering = function( inputElement, element, settings) { 189 | return new Slider( inputElement, element, settings ); 190 | }; 191 | } 192 | }; 193 | }]) 194 | .config(function() {}) 195 | .run(function() {}); 196 | })(angular); 197 | -------------------------------------------------------------------------------- /src/css/less/main.less: -------------------------------------------------------------------------------- 1 | // 2 | // Main slider css rules 3 | // -------------------------------------------------- 4 | 5 | @import "variables.less"; 6 | 7 | /*http://codeguide.co/#css-syntax*/ 8 | 9 | .jslider { 10 | 11 | /* Positioning */ 12 | position: relative; 13 | top: 0.6em; 14 | 15 | /* Box-model */ 16 | cursor: pointer; 17 | display: block; 18 | width: 100%; 19 | height: 1em; 20 | 21 | /* Typography */ 22 | font-family: @font-family-base; 23 | 24 | // disabled 25 | &.disabled { opacity: 0.5; } 26 | 27 | table { 28 | border-collapse: collapse; 29 | border: 0; 30 | width: 100%; 31 | td, th { 32 | width: 100%; 33 | vertical-align: top; 34 | border: 0; 35 | padding: 0; 36 | text-align: left; 37 | vertical-align: top; 38 | } 39 | } 40 | 41 | // RANGES 42 | div.jslider-bg i, div.jslider-pointer { 43 | background: url(../img/jslider.png) no-repeat 0 0; 44 | } 45 | 46 | div.jslider-bg { 47 | position: relative; 48 | i { 49 | position: absolute; 50 | top: 0; 51 | height: 5px; 52 | 53 | &.left { 54 | left: 0; 55 | width: 50%; 56 | background-position: 0 0; 57 | } 58 | 59 | &.right { 60 | left: 50%; 61 | width: 50%; 62 | background-position: right 0; 63 | } 64 | 65 | &.range { 66 | position: absolute; 67 | top: 0; 68 | left: 20%; 69 | width: 60%; 70 | height: 5px; 71 | z-index: 1; 72 | background-repeat: repeat-x; 73 | background-position: 0 -40px; 74 | } 75 | 76 | &.default { 77 | left: 0; 78 | width: 1px; 79 | z-index: 1; 80 | background-color: @color-pointers-default-value; 81 | } 82 | 83 | } 84 | } 85 | // END RANGES 86 | 87 | // POINTERS 88 | // single value hide to 89 | &.jslider-single { 90 | div.jslider-pointer-to, 91 | div.jslider-value-to, 92 | div.jslider-bg .v, 93 | .jslider-limitless .jslider-label { 94 | display: none; 95 | } 96 | } 97 | 98 | div.jslider-pointer { 99 | position: absolute; 100 | top: -4px; 101 | left: 20%; 102 | z-index: 2; 103 | width: 15px; 104 | height: 15px; 105 | background-position: 2px -60px; 106 | margin-left: -8px; 107 | cursor: pointer; 108 | cursor: hand; 109 | 110 | &.jslider-pointer-to { 111 | left: 80%; 112 | } 113 | 114 | &.jslider-pointer-hover { 115 | background-position: -18px -60px; 116 | } 117 | } 118 | // END POINTERS 119 | 120 | // LABELS 121 | div.jslider-label small, 122 | div.jslider-value small { 123 | position: relative; 124 | top: -0.4em; 125 | } 126 | 127 | // limits 128 | div.jslider-label { 129 | position: absolute; 130 | top: -18px; 131 | left: 0px; 132 | padding: 0px 2px; 133 | opacity: 0.4; 134 | color: @color-pointers-label; 135 | font-size: @font-size-pointers-label; 136 | line-height: @line-height-pointers-label; 137 | white-space: nowrap; 138 | 139 | &.jslider-label-to { 140 | left: auto; 141 | right: 0; 142 | } 143 | } 144 | // END LABELS 145 | 146 | // POINTERS VALUE 147 | div.jslider-value { 148 | position: absolute; 149 | top: -19px; 150 | left: 0; 151 | padding: 1px 2px 0; 152 | background: white; 153 | font-size: @font-size-pointers-value; 154 | line-height: @line-height-pointers-value; 155 | white-space: nowrap; 156 | -moz-border-radius: 2px; 157 | -webkit-border-radius: 2px; 158 | -o-border-radius: 2px; 159 | border-radius: 2px; 160 | &.jslider-value-to { 161 | left: 80%; 162 | } 163 | } 164 | // END POINTERS VALUE 165 | 166 | // SCALE 167 | div.jslider-scale { 168 | position: relative; 169 | top: 9px; 170 | span { 171 | position: absolute; 172 | height: 5px; 173 | border-left: 1px solid #999; 174 | font-size: 0; 175 | } 176 | ins { 177 | position: absolute; 178 | top: 5px; 179 | left: 0px; 180 | font-size: 9px; 181 | text-decoration: none; 182 | color: #999; } 183 | } 184 | // END SCALE 185 | 186 | // VERTICAL 187 | &.vertical { 188 | display: block; 189 | width: 17px; 190 | height: 100%; 191 | position: relative; 192 | top: 0.6em; 193 | font-family: Arial, sans-serif; 194 | table { 195 | height: 100%; 196 | } 197 | 198 | &.sliderCSS .jslider-bg i, &.jslider-pointer { 199 | background-color: silver; 200 | background-image: none; 201 | } 202 | 203 | // RANGES 204 | div.jslider-bg i,.jslider-pointer { 205 | background: url(../img/jslider.vertical.png) no-repeat 0 0; 206 | } 207 | 208 | div.jslider-bg { 209 | position: relative; 210 | height:100%; 211 | 212 | i { 213 | position: absolute; 214 | top: 0; 215 | width: 5px; 216 | font-size: 0; 217 | 218 | &.before { 219 | left: 50%; 220 | background: none 221 | } 222 | 223 | &.left { 224 | top: 0; 225 | left: 50%; 226 | height: 50%; 227 | background-position: right 0; 228 | background-repeat: repeat-y 229 | } 230 | 231 | &.right { 232 | top: 50%; 233 | left: 50%; 234 | height: 50%; 235 | background-position: right 0; 236 | background-repeat: repeat-y 237 | } 238 | 239 | &.range { 240 | position: absolute; 241 | top: 0; 242 | left: 50%; 243 | width: 60%; 244 | height: 100%; 245 | z-index: 1; 246 | background-repeat: repeat-y; 247 | background-position: -36px 0px; 248 | } 249 | 250 | &.default { 251 | left: 50%; 252 | width: 5px; 253 | height:1px; 254 | z-index: 1; 255 | background-color: @color-pointers-default-value; 256 | } 257 | 258 | } 259 | } 260 | // END RANGES 261 | 262 | // POINTERS 263 | div.jslider-pointer { 264 | left: 62%; 265 | background-position: -7px -1px; 266 | 267 | &.jslider-pointer-hover { 268 | background-position: -7px -21px; 269 | } 270 | 271 | &.jslider-pointer-to { 272 | left: 62%; 273 | } 274 | 275 | &.jslider-pointer-to.jslider-pointer-hover { 276 | background-position: -7px -21px; 277 | } 278 | } 279 | // END POINTERS 280 | 281 | // LABELS 282 | div.jslider-label { 283 | top: -5px; 284 | margin-left: 22px; 285 | 286 | &.jslider-label-to { 287 | top:100%; 288 | left: inherit; 289 | right: inherit; 290 | margin-top: -5px; 291 | } 292 | } 293 | // END LABELS 294 | 295 | 296 | // POINTERS VALUE 297 | div.jslider-value { 298 | top: 0; 299 | left: 0; 300 | } 301 | 302 | div.jslider-value-to { 303 | top: 80%; 304 | left: 0; 305 | } 306 | // END POINTERS VALUE 307 | 308 | // SCALES 309 | div.jslider-scale { 310 | position: inherit; 311 | span { 312 | position: absolute; 313 | width: 5px; 314 | height: 1px; 315 | border-left: none; 316 | font-size: 0; 317 | border-top: 1px solid #999; 318 | } 319 | ins { 320 | position: absolute; 321 | left: 0px; 322 | top: 5px; 323 | font-size: 9px; 324 | text-decoration: none; 325 | color: @color-scale; 326 | } 327 | } 328 | 329 | } 330 | // END VERTICAL 331 | 332 | 333 | // SKINS 334 | @import "skin-css.less"; 335 | @import "skin-round.less"; 336 | @import "skin-blue.less"; 337 | @import "skin-plastic.less"; 338 | } 339 | 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | angular-awesome-slider [![NPM version](https://badge.fury.io/js/angular-awesome-slider.png)](http://badge.fury.io/js/angular-awesome-slider) [![Build Status](https://travis-ci.org/darul75/angular-awesome-slider.png?branch=master)](https://travis-ci.org/darul75/angular-awesome-slider) [![Join the chat at https://gitter.im/darul75/angular-awesome-slider](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/darul75/angular-awesome-slider?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | ===================== 3 | 4 | Angular directive slider control. 5 | 6 | **No JQUERY dependency needed anymore** 7 | 8 | **Skins available** 9 | 10 | Why 11 | ------------- 12 | 13 | Original implementation provides very nice features but too much for my needs, this one just simplified. 14 | 15 | Source files were divided in several files, and not angular integrated. 16 | 17 | Screenshot 18 | ------------- 19 | 20 | ![angular slider demo](http://darul75.github.io/angular-awesome-slider/images/slider3.png "angular slider demo screenshot") 21 | 22 | Demo 23 | ------------- 24 | http://darul75.github.io/angular-awesome-slider/ 25 | 26 | http://jsfiddle.net/darul75/g9e9n8xc/ 27 | 28 | How to use it 29 | ------------- 30 | 31 | You should already have script required for Angular. 32 | 33 | ```html 34 | 35 | ``` 36 | 37 | to the list above, you should add: 38 | 39 | ```html 40 | 41 | ``` 42 | 43 | ```html 44 | 45 | ``` 46 | in case you want to use your own template, omit the last line and instead add some template code 47 | to your project: 48 | ```html 49 | 52 | ``` 53 | 54 | Then, inject `angularAwesomeSlider` in your application module: 55 | 56 | ```javascript 57 | angular.module('myApp', ['angularAwesomeSlider']); 58 | ``` 59 | 60 | and then just add an `input` with `slider` directive name attribute, `value` and `options` scope variable attribute. 61 | 62 | ```html 63 | 64 | ``` 65 | 66 | 'value' your slider scope end value, as string. 67 | 'options' slider scope options value as json. 68 | 'ng-disabled' angular common attribute. 69 | 70 | ```javascript 71 | $scope.value = "10"; 72 | // $scope.value = "10;15"; FOR DOUBLE VIEW 73 | ``` 74 | 75 | ### Options 76 | 77 | Options for your slider in json format {from:.....} 78 | 79 | * `from`: start value 80 | * `to`: end value 81 | * `step`: step value 82 | * `dimension`: string, example " $" 83 | * `scale`: array for scale 84 | * `round`: how many numbers allowed after comma 85 | * `smooth`: true/false; false snaps the button to value 86 | * `vertical`: true/false; vertical slider, default false 87 | * `skin`: empty or 'blue' 'plastic' 'round' 88 | * `css`: hash object, do not mix with 'skin' ! 89 | * `className`: custom class added to root slider DOM 90 | * `realtime`: triggers changes and model update on every moves 91 | * `threshold`: minimum distance allowed between 2 pointers, default both pointers overlap 92 | * `limits`: true/false; toggles bounds labels visibility 93 | * `modelLabels`: custom model for pointers labels based on pointer value 94 | * `watchOptions`: default is 'true', watch this options changes by [equals](https://docs.angularjs.org/api/ng/function/angular.equals) 95 | * `heterogeneity`: array [percentage of point on slider]/[value in that point] 96 | * `logScale`: true/false; uses a log scale so that a greater proportion is given to the lower end of the scale. Useful for price sliders. Default false 97 | 98 | ![angular slider css](http://darul75.github.io/angular-awesome-slider/images/slider2.png "angular slider css explained") 99 | ``` 100 | css: { 101 | background: {"background-color": "silver"}, 102 | before: {"background-color": "purple"},// zone before default value 103 | default: {"background-color": "white"}, // default value: 1px 104 | after: {"background-color": "green"}, // zone after default value 105 | pointer: {"background-color": "red"} // circle pointer 106 | range: {"background-color": "red"} // use it if double value 107 | } 108 | ```` 109 | * `callback` : function triggering current value, can be useful 110 | 111 | ```javascript 112 | // example 113 | callback: function(value, released) { 114 | // useful when combined with 'realtime' option 115 | // released it triggered when mouse up 116 | console.log(value + " " + released); 117 | } 118 | ``` 119 | 120 | * `scale` : model for slide scale 121 | 122 | ```javascript 123 | // divide slider into parts 124 | scale: [0, '|', 10, '|', 20, '|' , 30, '|', 40] 125 | 126 | // or with some custom labels 127 | scale: [{val:10, label:'low'}, {val:25, label:'middle'}, {val:30, label:'high'}] 128 | ``` 129 | 130 | * `modelLabels` : model for pointers labels by object or function 131 | 132 | ```javascript 133 | // overrides default value label displayed combined with 'dimension' by an arbitrary label model 134 | modelLabels: {1: 'top', 2: 'middle', 3: 'bottom'}; 135 | 136 | // or dynamicaly based 137 | modelLabels: function(value) { 138 | return 'my value is' + value; // momentjs external library call... 139 | } 140 | ``` 141 | 142 | * `heterogeneity` : repartition of possible values 143 | ```javascript 144 | // example here, first value is percentage of slider length, second is value 145 | heterogeneity: ['50/100', '75/250'] // 50% value is 100, 75% value must be 250 146 | ``` 147 | 148 | Installation 149 | ------------ 150 | 151 | Using npm: 152 | 153 | ``` 154 | npm install angular-awesome-slider 155 | ``` 156 | 157 | Using bower: 158 | 159 | ``` 160 | bower install angular-awesome-slider 161 | ``` 162 | 163 | RELEASE 164 | ------------- 165 | 166 | * 2.4.5: LogScale option, thanks @gareththackeray 167 | * 2.4.4: move by grabbing the label 168 | * 2.4.3: fix label + switch from range <=> one value 169 | * 2.4.2: update angular version + fix for programmatic movement of slider (double value) 170 | * 2.4.1: non-minified version added + bower update 171 | * 2.4.0: fix while updating both range values from code 172 | * 2.3.9: callback not fired in case slider is on threshold values 173 | * 2.3.8: bind to touch AND non touch events 174 | * 2.3.7: heterogeneity option 175 | * 2.3.6: watch options, fix threshold and click handler + date display testing. 176 | * 2.3.5: do not remember 177 | * 2.3.4: fix css regressions + modelLabels with function 178 | * 2.3.3: details for modelLabels options + merge showLabels option 179 | * 2.3.2: fix css pointer position + hover sking pointers background positions 180 | * 2.3.1: fix from and to in floating values 181 | * 2.3.0: new module name, no more ng-sorry-prefix, classname option, sass/scss support, scale object option 182 | * 2.2.6: refactoring classnames 183 | * 2.2.5: skin availables + less all css 184 | * 2.2.4: fix when 2 pointers overlap on limits 185 | * 2.2.3: mouse up event indicator in callback 186 | * 2.2.2: default indicator display + visibility and move events 187 | * 2.2.1: fix disable+default position css+decimal value on init value 188 | * 2.2.0: handle from greater than to + gap pointer threshold option 189 | * 2.1.9: fix labels positions while gluing, gap was too big + options changed watch by value 190 | * 2.1.8: fix labels positions while gluing + realtime model changes option + ngDisable option fix 191 | * 2.1.7: fix pointer position on click for double value 192 | * 2.1.6: starting mocha tests 193 | * 2.1.5: directive refactoring 194 | * 2.1.4: fix overlap on labels 195 | * 2.1.3: bug fixes, refactoring, inline options param 196 | * 2.1.2: bug fixes, changes in z-index via CSS and not js 197 | * 2.1.1: override css, colors... 198 | * 2.1.0: bug fixes 199 | * 2.0.0: no JQuery 200 | 201 | ### Build 202 | 203 | You can run the tests by running 204 | 205 | ``` 206 | npm install 207 | ``` 208 | or 209 | ``` 210 | npm test 211 | ``` 212 | 213 | assuming you already have `grunt` installed, otherwise you also need to do: 214 | 215 | ``` 216 | npm install -g grunt-cli 217 | ``` 218 | 219 | ### Issue 220 | 221 | To help me on reproducing any issues, please feel free to modify/fork this fiddle: http://jsfiddle.net/darul75/b09m7183/ 222 | 223 | ## Metrics 224 | 225 | [![NPM](https://nodei.co/npm/ng-slider.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/ng-slider/) 226 | 227 | ## who's who 228 | 229 | Who use it ? feel free add issue or edit readme with PR, to see how you use it and give some ideas, thx 230 | 231 | [openenergygroup](https://www.openenergygroup.com/) 232 | 233 | [google?](https://www.google.com) 234 | 235 | ## License 236 | 237 | The MIT License (MIT) 238 | 239 | Copyright (c) 2013 Julien Valéry 240 | 241 | Permission is hereby granted, free of charge, to any person obtaining a copy 242 | of this software and associated documentation files (the "Software"), to deal 243 | in the Software without restriction, including without limitation the rights 244 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 245 | copies of the Software, and to permit persons to whom the Software is 246 | furnished to do so, subject to the following conditions: 247 | 248 | The above copyright notice and this permission notice shall be included in 249 | all copies or substantial portions of the Software. 250 | 251 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 252 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 253 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 254 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 255 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 256 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 257 | THE SOFTWARE. 258 | 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /dist/css/angular-awesome-slider.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @license angular-awesome-slider - v2.4.4 3 | * (c) 2013 Julien VALERY https://github.com/darul75/angular-awesome-slider 4 | * License: MIT 5 | **/ 6 | 7 | .jslider{position:relative;top:.6em;cursor:pointer;display:block;width:100%;height:1em;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.jslider.disabled{opacity:.5}.jslider table{border-collapse:collapse;border:0;width:100%}.jslider table td,.jslider table th{width:100%;border:0;padding:0;text-align:left;vertical-align:top}.jslider div.jslider-bg i,.jslider div.jslider-pointer{background:url(../img/jslider.png) no-repeat 0 0}.jslider div.jslider-bg{position:relative}.jslider div.jslider-bg i{position:absolute;top:0;height:5px}.jslider div.jslider-bg i.left{left:0;width:50%;background-position:0 0}.jslider div.jslider-bg i.right{left:50%;width:50%;background-position:right 0}.jslider div.jslider-bg i.range{position:absolute;top:0;left:20%;width:60%;height:5px;z-index:1;background-repeat:repeat-x;background-position:0 -40px}.jslider div.jslider-bg i.default{left:0;width:1px;z-index:1;background-color:#185f83}.jslider.jslider-single div.jslider-pointer-to,.jslider.jslider-single div.jslider-value-to,.jslider.jslider-single div.jslider-bg .v,.jslider.jslider-single .jslider-limitless .jslider-label{display:none}.jslider div.jslider-pointer{position:absolute;top:-4px;left:20%;z-index:2;width:15px;height:15px;background-position:2px -60px;margin-left:-8px;cursor:pointer;cursor:hand}.jslider div.jslider-pointer.jslider-pointer-to{left:80%}.jslider div.jslider-pointer.jslider-pointer-hover{background-position:-18px -60px}.jslider div.jslider-label small,.jslider div.jslider-value small{position:relative;top:-.4em}.jslider div.jslider-label{position:absolute;top:-18px;left:0;padding:0 2px;opacity:.4;color:#000;font-size:9px;line-height:12px;white-space:nowrap}.jslider div.jslider-label.jslider-label-to{left:auto;right:0}.jslider div.jslider-value{position:absolute;top:-19px;left:0;padding:1px 2px 0;background:#fff;font-size:9px;line-height:12px;white-space:nowrap;-moz-border-radius:2px;-webkit-border-radius:2px;-o-border-radius:2px;border-radius:2px}.jslider div.jslider-value.jslider-value-to{left:80%}.jslider div.jslider-scale{position:relative;top:9px}.jslider div.jslider-scale span{position:absolute;height:5px;border-left:1px solid #999;font-size:0}.jslider div.jslider-scale ins{position:absolute;top:5px;left:0;font-size:9px;text-decoration:none;color:#999}.jslider.vertical{display:block;width:17px;height:100%;position:relative;top:.6em;font-family:Arial,sans-serif}.jslider.vertical table{height:100%}.jslider.vertical.sliderCSS .jslider-bg i,.jslider.vertical.jslider-pointer{background-color:silver;background-image:none}.jslider.vertical div.jslider-bg i,.jslider.vertical .jslider-pointer{background:url(../img/jslider.vertical.png) no-repeat 0 0}.jslider.vertical div.jslider-bg{position:relative;height:100%}.jslider.vertical div.jslider-bg i{position:absolute;top:0;width:5px;font-size:0}.jslider.vertical div.jslider-bg i.before{left:50%;background:0 0}.jslider.vertical div.jslider-bg i.left{top:0;left:50%;height:50%;background-position:right 0;background-repeat:repeat-y}.jslider.vertical div.jslider-bg i.right{top:50%;left:50%;height:50%;background-position:right 0;background-repeat:repeat-y}.jslider.vertical div.jslider-bg i.range{position:absolute;top:0;left:50%;width:60%;height:100%;z-index:1;background-repeat:repeat-y;background-position:-36px 0}.jslider.vertical div.jslider-bg i.default{left:50%;width:5px;height:1px;z-index:1;background-color:#185f83}.jslider.vertical div.jslider-pointer{left:62%;background-position:-7px -1px}.jslider.vertical div.jslider-pointer.jslider-pointer-hover{background-position:-7px -21px}.jslider.vertical div.jslider-pointer.jslider-pointer-to{left:62%}.jslider.vertical div.jslider-pointer.jslider-pointer-to.jslider-pointer-hover{background-position:-7px -21px}.jslider.vertical div.jslider-label{top:-5px;margin-left:22px}.jslider.vertical div.jslider-label.jslider-label-to{top:100%;left:inherit;right:inherit;margin-top:-5px}.jslider.vertical div.jslider-value{top:0;left:0}.jslider.vertical div.jslider-value-to{top:80%;left:0}.jslider.vertical div.jslider-scale{position:inherit}.jslider.vertical div.jslider-scale span{position:absolute;width:5px;height:1px;border-left:0;font-size:0;border-top:1px solid #999}.jslider.vertical div.jslider-scale ins{position:absolute;left:0;top:5px;font-size:9px;text-decoration:none;color:#999}.jslider.sliderCSS div.jslider-bg i.left{left:0;width:50%;background-color:silver;background-image:none}.jslider.sliderCSS div.jslider-bg i.right{width:50%;left:50%;background-color:silver;background-image:none}.jslider.sliderCSS div.jslider-bg i.before{left:0;width:1px;background-color:rgba(92,98,203,.89);background-image:none}.jslider.sliderCSS div.jslider-bg i.default{left:0;width:1px;z-index:1;background-color:#fff;background-image:none}.jslider.sliderCSS div.jslider-bg i.after{left:0;background-color:#0e1773;background-image:none}.jslider.sliderCSS div.jslider-bg i.range{position:absolute;top:0;left:20%;width:60%;height:5px;z-index:1;background-image:none;background-color:#777575}.jslider.sliderCSS div.jslider-pointer{top:-3px;left:15px;width:10px;height:10px;margin-left:-5px;background-color:silver;background-color:#615959;border-radius:50%}.jslider.sliderCSS div.jslider-bg i,.jslider.sliderCSS div.jslider-pointer{background:0 0}.jslider.sliderCSS.vertical td{height:100%}.jslider.sliderCSS.vertical div.jslider-bg i{left:50%;width:5px}.jslider.sliderCSS.vertical div.jslider-bg i.left{top:0;height:50%;background-color:silver;background-image:none}.jslider.sliderCSS.vertical div.jslider-bg i.right{height:50%;top:50%;background-color:silver;background-image:none}.jslider.sliderCSS.vertical div.jslider-bg i.range{height:100%;z-index:1;background-color:#777575;background-image:none}.jslider.sliderCSS.vertical div.jslider-bg i.before{background-color:rgba(92,98,203,.89);background-image:none}.jslider.sliderCSS.vertical div.jslider-bg i.default{height:1px;background-color:#fff;background-image:none;z-index:2}.jslider.sliderCSS.vertical div.jslider-bg i.after{background-color:#0e1773;background-image:none}.jslider.sliderCSS.vertical div.jslider-bg i,.jslider.sliderCSS.vertical div.jslider-pointer{background:0 0}.jslider.sliderCSS.vertical div.jslider-pointer{left:50%;width:10px;height:10px;background-color:#615959;border-radius:50%;margin-left:-3px}.jslider.sliderCSS.vertical div.jslider-pointer.jslider-pointer-to{left:50%}.jslider.jslider_round div.jslider-bg i,.jslider.jslider_round div.jslider-pointer{background:url(../img/jslider.round.png) no-repeat 0 0}.jslider.jslider_round div.jslider-bg i{background-position:0 -20px}.jslider.jslider_round div.jslider-bg i.default{background-color:#C2C7CA}.jslider.jslider_round div.jslider-bg i.range{z-index:1;background-position:0 -40px}.jslider.jslider_round div.jslider-pointer{top:-6px;width:20px;height:17px;background-position:0 -60px;z-index:2}.jslider.jslider_round div.jslider-pointer.jslider-pointer-hover{background-position:-20px -60px}.jslider.jslider_round.vertical div.jslider-bg i,.jslider.jslider_round.vertical div.jslider-pointer{background:url(../img/jslider.round.vertical.png) no-repeat 0 0}.jslider.jslider_round.vertical div.jslider-bg i{background-position:right 0}.jslider.jslider_round.vertical div.jslider-bg i.range{background-position:-37px 0}.jslider.jslider_round.vertical div.jslider-bg i.before,.jslider.jslider_round.vertical div.jslider-bg i.after{background:0 0}.jslider.jslider_round.vertical div.jslider-bg i.default{background-color:#c2c7ca}.jslider.jslider_round.vertical div.jslider-pointer{top:-6px;width:20px;height:17px;background-position:-4px -3px}.jslider.jslider_round.vertical div.jslider-pointer.jslider-pointer-hover{background-position:-4px -23px}.jslider.jslider_round.vertical div.jslider-pointer.jslider-value-to{left:80%}.jslider.jslider_round.vertical div.jslider-value{left:0}.jslider.jslider_blue .jslider-bg i,.jslider.jslider_blue .jslider-pointer{background:url(../img/jslider.blue.png) no-repeat 0 0}.jslider.jslider_blue .jslider-bg i{background-position:2px -20px}.jslider.jslider_blue .jslider-bg i.default{background-color:#c2c7ca}.jslider.jslider_blue .jslider-bg i.range{z-index:1;background-position:0 -40px}.jslider.jslider_blue div.jslider-pointer{top:-6px;width:20px;height:17px;background-position:2px -60px;z-index:2}.jslider.jslider_blue div.jslider-pointer.jslider-pointer-hover{background-position:-20px -60px}.jslider.jslider_blue.vertical div.jslider-bg i,.jslider.jslider_blue.vertical div.jslider-pointer{background:url(../img/jslider.blue.vertical.png) no-repeat 0 0}.jslider.jslider_blue.vertical div.jslider-bg i{background-position:right 0}.jslider.jslider_blue.vertical div.jslider-bg i.range{background-position:-37px 0}.jslider.jslider_blue.vertical div.jslider-bg i.before,.jslider.jslider_blue.vertical div.jslider-bg i.after{background:0 0}.jslider.jslider_blue.vertical div.jslider-bg i.default{background-color:#c2c7ca}.jslider.jslider_blue.vertical div.jslider-pointer{top:-6px;width:20px;height:17px;background-position:-7px 0}.jslider.jslider_blue.vertical div.jslider-pointer.jslider-pointer-hover{background-position:-7px -20px}.jslider.jslider_blue.vertical div.jslider-value{left:0}.jslider.jslider_plastic .jslider-bg i,.jslider.jslider_plastic .jslider-pointer{background:url(../img/jslider.plastic.png) no-repeat 0 0}.jslider.jslider_plastic .jslider-bg i{background-position:2px -20px}.jslider.jslider_plastic .jslider-bg i.default{background-color:#c2c7ca}.jslider.jslider_plastic .jslider-bg i.range{z-index:1;background-position:0 -40px}.jslider.jslider_plastic .jslider-pointer{z-index:2;width:20px;height:17px;top:-4px;background-position:2px -60px}.jslider.jslider_plastic .jslider-pointer.jslider-pointer-hover{background-position:-18px -60px}.jslider.jslider_plastic.vertical div.jslider-bg i,.jslider.jslider_plastic.vertical div.jslider-pointer{background:url(../img/jslider.plastic.vertical.png) no-repeat 0 0}.jslider.jslider_plastic.vertical div.jslider-bg i{background-position:right 0}.jslider.jslider_plastic.vertical div.jslider-bg i.range{background-position:-35px 0}.jslider.jslider_plastic.vertical div.jslider-bg i.before,.jslider.jslider_plastic.vertical div.jslider-bg i.after{background:0 0}.jslider.jslider_plastic.vertical div.jslider-bg i.default{background-color:#c2c7ca}.jslider.jslider_plastic.vertical div.jslider-pointer{top:-6px;margin-left:-6px;width:20px;height:17px;background-position:-7px -1px}.jslider.jslider_plastic.vertical div.jslider-pointer.jslider-pointer-hover{background-position:-7px -21px} -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 | 57 |
58 |
59 | Current value is: {{value3bis}} 60 |
61 |
62 |
63 | sdsdqsdsqd 64 |
65 |
66 | Current value is: {{value}} 67 |
68 |
69 | 70 |
--> 71 |
72 | Current value is: {{valueDate}} 73 |
74 |
75 | sdsdqsdsqd 76 |
77 |
78 | Current value is: {{value}} 79 |
80 |
81 | 82 |
83 |
84 | Current value is: {{valueVisibility}} 85 |
86 | 87 |
88 |
89 |
90 | 91 |
92 |
93 |
94 | Current value is: {{data.quote.coverages.coverageA}} 95 |
96 |
97 |
98 |
99 | 100 |
101 |
102 | Current value is: {{value2}} 103 |
104 |
105 | 106 |
107 |
108 | Current value is: {{value4}} 109 |
110 |
111 | 112 | 113 | 114 |
115 |
116 | 117 | 118 | 119 | 120 |
121 | 122 |
123 | 124 | 390 | 391 | 392 | -------------------------------------------------------------------------------- /src/css/angular-awesome-slider.css: -------------------------------------------------------------------------------- 1 | /*http://codeguide.co/#css-syntax*/ 2 | .jslider { 3 | /* Positioning */ 4 | 5 | position: relative; 6 | top: 0.6em; 7 | /* Box-model */ 8 | 9 | cursor: pointer; 10 | display: block; 11 | width: 100%; 12 | height: 1em; 13 | /* Typography */ 14 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 15 | } 16 | .jslider.disabled { 17 | opacity: 0.5; 18 | } 19 | .jslider table { 20 | border-collapse: collapse; 21 | border: 0; 22 | width: 100%; 23 | } 24 | .jslider table td, 25 | .jslider table th { 26 | width: 100%; 27 | border: 0; 28 | padding: 0; 29 | text-align: left; 30 | vertical-align: top; 31 | } 32 | .jslider div.jslider-bg i, 33 | .jslider div.jslider-pointer { 34 | background: url(../img/jslider.png) no-repeat 0 0; 35 | } 36 | .jslider div.jslider-bg { 37 | position: relative; 38 | } 39 | .jslider div.jslider-bg i { 40 | position: absolute; 41 | top: 0; 42 | height: 5px; 43 | } 44 | .jslider div.jslider-bg i.left { 45 | left: 0; 46 | width: 50%; 47 | background-position: 0 0; 48 | } 49 | .jslider div.jslider-bg i.right { 50 | left: 50%; 51 | width: 50%; 52 | background-position: right 0; 53 | } 54 | .jslider div.jslider-bg i.range { 55 | position: absolute; 56 | top: 0; 57 | left: 20%; 58 | width: 60%; 59 | height: 5px; 60 | z-index: 1; 61 | background-repeat: repeat-x; 62 | background-position: 0 -40px; 63 | } 64 | .jslider div.jslider-bg i.default { 65 | left: 0; 66 | width: 1px; 67 | z-index: 1; 68 | background-color: #185f83; 69 | } 70 | .jslider.jslider-single div.jslider-pointer-to, 71 | .jslider.jslider-single div.jslider-value-to, 72 | .jslider.jslider-single div.jslider-bg .v, 73 | .jslider.jslider-single .jslider-limitless .jslider-label { 74 | display: none; 75 | } 76 | .jslider div.jslider-pointer { 77 | position: absolute; 78 | top: -4px; 79 | left: 20%; 80 | z-index: 2; 81 | width: 15px; 82 | height: 15px; 83 | background-position: 2px -60px; 84 | margin-left: -8px; 85 | cursor: pointer; 86 | cursor: hand; 87 | } 88 | .jslider div.jslider-pointer.jslider-pointer-to { 89 | left: 80%; 90 | } 91 | .jslider div.jslider-pointer.jslider-pointer-hover { 92 | background-position: -18px -60px; 93 | } 94 | .jslider div.jslider-label small, 95 | .jslider div.jslider-value small { 96 | position: relative; 97 | top: -0.4em; 98 | } 99 | .jslider div.jslider-label { 100 | position: absolute; 101 | top: -18px; 102 | left: 0px; 103 | padding: 0px 2px; 104 | opacity: 0.4; 105 | color: #000000; 106 | font-size: 9px; 107 | line-height: 12px; 108 | white-space: nowrap; 109 | } 110 | .jslider div.jslider-label.jslider-label-to { 111 | left: auto; 112 | right: 0; 113 | } 114 | .jslider div.jslider-value { 115 | position: absolute; 116 | top: -19px; 117 | left: 0; 118 | padding: 1px 2px 0; 119 | background: white; 120 | font-size: 9px; 121 | line-height: 12px; 122 | white-space: nowrap; 123 | -moz-border-radius: 2px; 124 | -webkit-border-radius: 2px; 125 | -o-border-radius: 2px; 126 | border-radius: 2px; 127 | } 128 | .jslider div.jslider-value.jslider-value-to { 129 | left: 80%; 130 | } 131 | .jslider div.jslider-scale { 132 | position: relative; 133 | top: 9px; 134 | } 135 | .jslider div.jslider-scale span { 136 | position: absolute; 137 | height: 5px; 138 | border-left: 1px solid #999; 139 | font-size: 0; 140 | } 141 | .jslider div.jslider-scale ins { 142 | position: absolute; 143 | top: 5px; 144 | left: 0px; 145 | font-size: 9px; 146 | text-decoration: none; 147 | color: #999; 148 | } 149 | .jslider.vertical { 150 | display: block; 151 | width: 17px; 152 | height: 100%; 153 | position: relative; 154 | top: 0.6em; 155 | font-family: Arial, sans-serif; 156 | } 157 | .jslider.vertical table { 158 | height: 100%; 159 | } 160 | .jslider.vertical.sliderCSS .jslider-bg i, 161 | .jslider.vertical.jslider-pointer { 162 | background-color: silver; 163 | background-image: none; 164 | } 165 | .jslider.vertical div.jslider-bg i, 166 | .jslider.vertical .jslider-pointer { 167 | background: url(../img/jslider.vertical.png) no-repeat 0 0; 168 | } 169 | .jslider.vertical div.jslider-bg { 170 | position: relative; 171 | height: 100%; 172 | } 173 | .jslider.vertical div.jslider-bg i { 174 | position: absolute; 175 | top: 0; 176 | width: 5px; 177 | font-size: 0; 178 | } 179 | .jslider.vertical div.jslider-bg i.before { 180 | left: 50%; 181 | background: none; 182 | } 183 | .jslider.vertical div.jslider-bg i.left { 184 | top: 0; 185 | left: 50%; 186 | height: 50%; 187 | background-position: right 0; 188 | background-repeat: repeat-y; 189 | } 190 | .jslider.vertical div.jslider-bg i.right { 191 | top: 50%; 192 | left: 50%; 193 | height: 50%; 194 | background-position: right 0; 195 | background-repeat: repeat-y; 196 | } 197 | .jslider.vertical div.jslider-bg i.range { 198 | position: absolute; 199 | top: 0; 200 | left: 50%; 201 | width: 60%; 202 | height: 100%; 203 | z-index: 1; 204 | background-repeat: repeat-y; 205 | background-position: -36px 0px; 206 | } 207 | .jslider.vertical div.jslider-bg i.default { 208 | left: 50%; 209 | width: 5px; 210 | height: 1px; 211 | z-index: 1; 212 | background-color: #185f83; 213 | } 214 | .jslider.vertical div.jslider-pointer { 215 | left: 62%; 216 | background-position: -7px -1px; 217 | } 218 | .jslider.vertical div.jslider-pointer.jslider-pointer-hover { 219 | background-position: -7px -21px; 220 | } 221 | .jslider.vertical div.jslider-pointer.jslider-pointer-to { 222 | left: 62%; 223 | } 224 | .jslider.vertical div.jslider-pointer.jslider-pointer-to.jslider-pointer-hover { 225 | background-position: -7px -21px; 226 | } 227 | .jslider.vertical div.jslider-label { 228 | top: -5px; 229 | margin-left: 22px; 230 | } 231 | .jslider.vertical div.jslider-label.jslider-label-to { 232 | top: 100%; 233 | left: inherit; 234 | right: inherit; 235 | margin-top: -5px; 236 | } 237 | .jslider.vertical div.jslider-value { 238 | top: 0; 239 | left: 0; 240 | } 241 | .jslider.vertical div.jslider-value-to { 242 | top: 80%; 243 | left: 0; 244 | } 245 | .jslider.vertical div.jslider-scale { 246 | position: inherit; 247 | } 248 | .jslider.vertical div.jslider-scale span { 249 | position: absolute; 250 | width: 5px; 251 | height: 1px; 252 | border-left: none; 253 | font-size: 0; 254 | border-top: 1px solid #999; 255 | } 256 | .jslider.vertical div.jslider-scale ins { 257 | position: absolute; 258 | left: 0px; 259 | top: 5px; 260 | font-size: 9px; 261 | text-decoration: none; 262 | color: #999999; 263 | } 264 | .jslider.sliderCSS div.jslider-bg i.left { 265 | left: 0; 266 | width: 50%; 267 | background-color: #c0c0c0; 268 | background-image: none; 269 | } 270 | .jslider.sliderCSS div.jslider-bg i.right { 271 | width: 50%; 272 | left: 50%; 273 | background-color: #c0c0c0; 274 | background-image: none; 275 | } 276 | .jslider.sliderCSS div.jslider-bg i.before { 277 | left: 0; 278 | width: 1px; 279 | background-color: rgba(92, 98, 203, 0.89); 280 | background-image: none; 281 | } 282 | .jslider.sliderCSS div.jslider-bg i.default { 283 | left: 0; 284 | width: 1px; 285 | z-index: 1; 286 | background-color: #ffffff; 287 | background-image: none; 288 | } 289 | .jslider.sliderCSS div.jslider-bg i.after { 290 | left: 0; 291 | background-color: #0e1773; 292 | background-image: none; 293 | } 294 | .jslider.sliderCSS div.jslider-bg i.range { 295 | position: absolute; 296 | top: 0; 297 | left: 20%; 298 | width: 60%; 299 | height: 5px; 300 | z-index: 1; 301 | background-image: none; 302 | background-color: #777575; 303 | } 304 | .jslider.sliderCSS div.jslider-pointer { 305 | top: -3px; 306 | left: 15px; 307 | width: 10px; 308 | height: 10px; 309 | margin-left: -5px; 310 | background-color: silver; 311 | background-color: #615959; 312 | border-radius: 50%; 313 | } 314 | .jslider.sliderCSS div.jslider-bg i, 315 | .jslider.sliderCSS div.jslider-pointer { 316 | background: none; 317 | } 318 | .jslider.sliderCSS.vertical td { 319 | height: 100%; 320 | } 321 | .jslider.sliderCSS.vertical div.jslider-bg i { 322 | left: 50%; 323 | width: 5px; 324 | } 325 | .jslider.sliderCSS.vertical div.jslider-bg i.left { 326 | top: 0; 327 | height: 50%; 328 | background-color: #c0c0c0; 329 | background-image: none; 330 | } 331 | .jslider.sliderCSS.vertical div.jslider-bg i.right { 332 | height: 50%; 333 | top: 50%; 334 | background-color: #c0c0c0; 335 | background-image: none; 336 | } 337 | .jslider.sliderCSS.vertical div.jslider-bg i.range { 338 | height: 100%; 339 | z-index: 1; 340 | background-color: #777575; 341 | background-image: none; 342 | } 343 | .jslider.sliderCSS.vertical div.jslider-bg i.before { 344 | background-color: rgba(92, 98, 203, 0.89); 345 | background-image: none; 346 | } 347 | .jslider.sliderCSS.vertical div.jslider-bg i.default { 348 | height: 1px; 349 | background-color: #ffffff; 350 | background-image: none; 351 | z-index: 2; 352 | } 353 | .jslider.sliderCSS.vertical div.jslider-bg i.after { 354 | background-color: #0e1773; 355 | background-image: none; 356 | } 357 | .jslider.sliderCSS.vertical div.jslider-bg i, 358 | .jslider.sliderCSS.vertical div.jslider-pointer { 359 | background: none; 360 | } 361 | .jslider.sliderCSS.vertical div.jslider-pointer { 362 | left: 50%; 363 | width: 10px; 364 | height: 10px; 365 | background-color: #615959; 366 | border-radius: 50%; 367 | margin-left: -3px; 368 | } 369 | .jslider.sliderCSS.vertical div.jslider-pointer.jslider-pointer-to { 370 | left: 50%; 371 | } 372 | .jslider.jslider_round div.jslider-bg i, 373 | .jslider.jslider_round div.jslider-pointer { 374 | background: url(../img/jslider.round.png) no-repeat 0 0; 375 | } 376 | .jslider.jslider_round div.jslider-bg i { 377 | background-position: 0 -20px; 378 | } 379 | .jslider.jslider_round div.jslider-bg i.default { 380 | background-color: #C2C7CA; 381 | } 382 | .jslider.jslider_round div.jslider-bg i.range { 383 | z-index: 1; 384 | background-position: 0 -40px; 385 | } 386 | .jslider.jslider_round div.jslider-pointer { 387 | top: -6px; 388 | width: 20px; 389 | height: 17px; 390 | background-position: 0 -60px; 391 | z-index: 2; 392 | } 393 | .jslider.jslider_round div.jslider-pointer.jslider-pointer-hover { 394 | background-position: -20px -60px; 395 | } 396 | .jslider.jslider_round.vertical div.jslider-bg i, 397 | .jslider.jslider_round.vertical div.jslider-pointer { 398 | background: url(../img/jslider.round.vertical.png) no-repeat 0 0; 399 | } 400 | .jslider.jslider_round.vertical div.jslider-bg i { 401 | background-position: right 0; 402 | } 403 | .jslider.jslider_round.vertical div.jslider-bg i.range { 404 | background-position: -37px 0; 405 | } 406 | .jslider.jslider_round.vertical div.jslider-bg i.before, 407 | .jslider.jslider_round.vertical div.jslider-bg i.after { 408 | background: none; 409 | } 410 | .jslider.jslider_round.vertical div.jslider-bg i.default { 411 | background-color: #c2c7ca; 412 | } 413 | .jslider.jslider_round.vertical div.jslider-pointer { 414 | top: -6px; 415 | width: 20px; 416 | height: 17px; 417 | background-position: -4px -3px; 418 | } 419 | .jslider.jslider_round.vertical div.jslider-pointer.jslider-pointer-hover { 420 | background-position: -4px -23px; 421 | } 422 | .jslider.jslider_round.vertical div.jslider-pointer.jslider-value-to { 423 | left: 80%; 424 | } 425 | .jslider.jslider_round.vertical div.jslider-value { 426 | left: 0; 427 | } 428 | .jslider.jslider_blue .jslider-bg i, 429 | .jslider.jslider_blue .jslider-pointer { 430 | background: url(../img/jslider.blue.png) no-repeat 0 0; 431 | } 432 | .jslider.jslider_blue .jslider-bg i { 433 | background-position: 2px -20px; 434 | } 435 | .jslider.jslider_blue .jslider-bg i.default { 436 | background-color: #c2c7ca; 437 | } 438 | .jslider.jslider_blue .jslider-bg i.range { 439 | z-index: 1; 440 | background-position: 0 -40px; 441 | } 442 | .jslider.jslider_blue div.jslider-pointer { 443 | top: -6px; 444 | width: 20px; 445 | height: 17px; 446 | background-position: 2px -60px; 447 | z-index: 2; 448 | } 449 | .jslider.jslider_blue div.jslider-pointer.jslider-pointer-hover { 450 | background-position: -20px -60px; 451 | } 452 | .jslider.jslider_blue.vertical div.jslider-bg i, 453 | .jslider.jslider_blue.vertical div.jslider-pointer { 454 | background: url(../img/jslider.blue.vertical.png) no-repeat 0 0; 455 | } 456 | .jslider.jslider_blue.vertical div.jslider-bg i { 457 | background-position: right 0; 458 | } 459 | .jslider.jslider_blue.vertical div.jslider-bg i.range { 460 | background-position: -37px 0; 461 | } 462 | .jslider.jslider_blue.vertical div.jslider-bg i.before, 463 | .jslider.jslider_blue.vertical div.jslider-bg i.after { 464 | background: none; 465 | } 466 | .jslider.jslider_blue.vertical div.jslider-bg i.default { 467 | background-color: #c2c7ca; 468 | } 469 | .jslider.jslider_blue.vertical div.jslider-pointer { 470 | top: -6px; 471 | width: 20px; 472 | height: 17px; 473 | background-position: -7px 0; 474 | } 475 | .jslider.jslider_blue.vertical div.jslider-pointer.jslider-pointer-hover { 476 | background-position: -7px -20px; 477 | } 478 | .jslider.jslider_blue.vertical div.jslider-value { 479 | left: 0; 480 | } 481 | .jslider.jslider_plastic .jslider-bg i, 482 | .jslider.jslider_plastic .jslider-pointer { 483 | background: url(../img/jslider.plastic.png) no-repeat 0 0; 484 | } 485 | .jslider.jslider_plastic .jslider-bg i { 486 | background-position: 2px -20px; 487 | } 488 | .jslider.jslider_plastic .jslider-bg i.default { 489 | background-color: #c2c7ca; 490 | } 491 | .jslider.jslider_plastic .jslider-bg i.range { 492 | z-index: 1; 493 | background-position: 0 -40px; 494 | } 495 | .jslider.jslider_plastic .jslider-pointer { 496 | z-index: 2; 497 | width: 20px; 498 | height: 17px; 499 | top: -4px; 500 | background-position: 2px -60px; 501 | } 502 | .jslider.jslider_plastic .jslider-pointer.jslider-pointer-hover { 503 | background-position: -18px -60px; 504 | } 505 | .jslider.jslider_plastic.vertical div.jslider-bg i, 506 | .jslider.jslider_plastic.vertical div.jslider-pointer { 507 | background: url(../img/jslider.plastic.vertical.png) no-repeat 0 0; 508 | } 509 | .jslider.jslider_plastic.vertical div.jslider-bg i { 510 | background-position: right 0; 511 | } 512 | .jslider.jslider_plastic.vertical div.jslider-bg i.range { 513 | background-position: -35px 0; 514 | } 515 | .jslider.jslider_plastic.vertical div.jslider-bg i.before, 516 | .jslider.jslider_plastic.vertical div.jslider-bg i.after { 517 | background: none; 518 | } 519 | .jslider.jslider_plastic.vertical div.jslider-bg i.default { 520 | background-color: #c2c7ca; 521 | } 522 | .jslider.jslider_plastic.vertical div.jslider-pointer { 523 | top: -6px; 524 | margin-left: -6px; 525 | width: 20px; 526 | height: 17px; 527 | background-position: -7px -1px; 528 | } 529 | .jslider.jslider_plastic.vertical div.jslider-pointer.jslider-pointer-hover { 530 | background-position: -7px -21px; 531 | } 532 | -------------------------------------------------------------------------------- /src/jquery.slider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.slider - Slider ui control in jQuery 3 | * 4 | * Written by 5 | * Egor Khmelev (hmelyoff@gmail.com) 6 | * 7 | * Licensed under the MIT (MIT-LICENSE.txt). 8 | * 9 | * @author Egor Khmelev 10 | * @version 1.1.0-RELEASE ($Id$) 11 | * 12 | * Dependencies 13 | * 14 | * jQuery (http://jquery.com) 15 | * jquery.numberformatter (http://code.google.com/p/jquery-numberformatter/) 16 | * tmpl (http://ejohn.org/blog/javascript-micro-templating/) 17 | * jquery.dependClass 18 | * draggable 19 | * 20 | **/ 21 | 22 | (function( $ ) { 23 | 24 | function isArray( value ){ 25 | if( typeof value == "undefined" ) return false; 26 | 27 | if (value instanceof Array || (!(value instanceof Object) && 28 | (Object.prototype.toString.call((value)) == '[object Array]') || 29 | typeof value.length == 'number' && 30 | typeof value.splice != 'undefined' && 31 | typeof value.propertyIsEnumerable != 'undefined' && 32 | !value.propertyIsEnumerable('splice') 33 | )) { 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | 40 | $.slider = function( node, settings ){ 41 | var jNode = $(node); 42 | if( !jNode.data( "jslider" ) ) 43 | jNode.data( "jslider", new jSlider( node, settings ) ); 44 | 45 | return jNode.data( "jslider" ); 46 | }; 47 | 48 | $.fn.slider = function( action, opt_value ){ 49 | var returnValue, args = arguments; 50 | 51 | function isDef( val ){ 52 | return val !== undefined; 53 | }; 54 | 55 | function isDefAndNotNull( val ){ 56 | return val != null; 57 | }; 58 | 59 | this.each(function(){ 60 | var self = $.slider( this, action ); 61 | 62 | // do actions 63 | if( typeof action == "string" ){ 64 | switch( action ){ 65 | case "value": 66 | if( isDef( args[ 1 ] ) && isDef( args[ 2 ] ) ){ 67 | var pointers = self.getPointers(); 68 | if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){ 69 | pointers[0].set( args[ 1 ] ); 70 | pointers[0].setIndexOver(); 71 | } 72 | 73 | if( isDefAndNotNull( pointers[1] ) && isDefAndNotNull( args[2] ) ){ 74 | pointers[1].set( args[ 2 ] ); 75 | pointers[1].setIndexOver(); 76 | } 77 | } 78 | 79 | else if( isDef( args[ 1 ] ) ){ 80 | var pointers = self.getPointers(); 81 | if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){ 82 | pointers[0].set( args[ 1 ] ); 83 | pointers[0].setIndexOver(); 84 | } 85 | } 86 | 87 | else 88 | returnValue = self.getValue(); 89 | 90 | break; 91 | 92 | case "prc": 93 | if( isDef( args[ 1 ] ) && isDef( args[ 2 ] ) ){ 94 | var pointers = self.getPointers(); 95 | if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){ 96 | pointers[0]._set( args[ 1 ] ); 97 | pointers[0].setIndexOver(); 98 | } 99 | 100 | if( isDefAndNotNull( pointers[1] ) && isDefAndNotNull( args[2] ) ){ 101 | pointers[1]._set( args[ 2 ] ); 102 | pointers[1].setIndexOver(); 103 | } 104 | } 105 | 106 | else if( isDef( args[ 1 ] ) ){ 107 | var pointers = self.getPointers(); 108 | if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){ 109 | pointers[0]._set( args[ 1 ] ); 110 | pointers[0].setIndexOver(); 111 | } 112 | } 113 | 114 | else 115 | returnValue = self.getPrcValue(); 116 | 117 | break; 118 | 119 | case "calculatedValue": 120 | var value = self.getValue().split(";"); 121 | returnValue = ""; 122 | for (var i=0; i < value.length; i++) { 123 | returnValue += (i > 0 ? ";" : "") + self.nice( value[i] ); 124 | }; 125 | 126 | break; 127 | 128 | case "skin": 129 | self.setSkin( args[1] ); 130 | 131 | break; 132 | }; 133 | 134 | } 135 | 136 | // return actual object 137 | else if( !action && !opt_value ){ 138 | if( !isArray( returnValue ) ) 139 | returnValue = []; 140 | 141 | returnValue.push( self ); 142 | } 143 | }); 144 | 145 | // flatten array just with one slider 146 | if( isArray( returnValue ) && returnValue.length == 1 ) 147 | returnValue = returnValue[ 0 ]; 148 | 149 | return returnValue || this; 150 | }; 151 | 152 | var OPTIONS = { 153 | 154 | settings: { 155 | from: 1, 156 | to: 10, 157 | step: 1, 158 | smooth: true, 159 | limits: true, 160 | round: 0, 161 | format: { format: "#,##0.##" }, 162 | value: "5;7", 163 | dimension: "" 164 | }, 165 | 166 | className: "jslider", 167 | selector: ".jslider-", 168 | 169 | template: tmpl( 170 | '' + 171 | '
' + 172 | '
' + 173 | '' + 174 | '' + 175 | '
' + 176 | 177 | '
' + 178 | '
' + 179 | 180 | '
<%=settings.from%>
' + 181 | '
<%=settings.to%><%=settings.dimension%>
' + 182 | 183 | '
<%=settings.dimension%>
' + 184 | '
<%=settings.dimension%>
' + 185 | 186 | '
<%=scale%>
'+ 187 | 188 | '
' + 189 | '
' 190 | ) 191 | 192 | }; 193 | 194 | function jSlider(){ 195 | return this.init.apply( this, arguments ); 196 | }; 197 | 198 | jSlider.prototype.init = function( node, settings ){ 199 | this.settings = $.extend(true, {}, OPTIONS.settings, settings ? settings : {}); 200 | 201 | // obj.sliderHandler = this; 202 | this.inputNode = $( node ).hide(); 203 | 204 | this.settings.interval = this.settings.to-this.settings.from; 205 | this.settings.value = this.inputNode.attr("value"); 206 | 207 | if( this.settings.calculate && $.isFunction( this.settings.calculate ) ) 208 | this.nice = this.settings.calculate; 209 | 210 | if( this.settings.onstatechange && $.isFunction( this.settings.onstatechange ) ) 211 | this.onstatechange = this.settings.onstatechange; 212 | 213 | this.is = { 214 | init: false 215 | }; 216 | this.o = {}; 217 | 218 | this.create(); 219 | }; 220 | 221 | jSlider.prototype.onstatechange = function(){ 222 | 223 | }; 224 | 225 | jSlider.prototype.create = function(){ 226 | var $this = this; 227 | 228 | this.domNode = $( OPTIONS.template({ 229 | className: OPTIONS.className, 230 | settings: { 231 | from: this.nice( this.settings.from ), 232 | to: this.nice( this.settings.to ), 233 | dimension: this.settings.dimension 234 | }, 235 | scale: this.generateScale() 236 | }) ); 237 | 238 | this.inputNode.after( this.domNode ); 239 | this.drawScale(); 240 | 241 | // set skin class 242 | if( this.settings.skin && this.settings.skin.length > 0 ) 243 | this.setSkin( this.settings.skin ); 244 | 245 | this.sizes = { 246 | domWidth: this.domNode.width(), 247 | domOffset: this.domNode.offset() 248 | }; 249 | 250 | // find some objects 251 | $.extend(this.o, { 252 | pointers: {}, 253 | labels: { 254 | 0: { 255 | o: this.domNode.find(OPTIONS.selector + "value").not(OPTIONS.selector + "value-to") 256 | }, 257 | 1: { 258 | o: this.domNode.find(OPTIONS.selector + "value").filter(OPTIONS.selector + "value-to") 259 | } 260 | }, 261 | limits: { 262 | 0: this.domNode.find(OPTIONS.selector + "label").not(OPTIONS.selector + "label-to"), 263 | 1: this.domNode.find(OPTIONS.selector + "label").filter(OPTIONS.selector + "label-to") 264 | } 265 | }); 266 | 267 | $.extend(this.o.labels[0], { 268 | value: this.o.labels[0].o.find("span") 269 | }); 270 | 271 | $.extend(this.o.labels[1], { 272 | value: this.o.labels[1].o.find("span") 273 | }); 274 | 275 | 276 | if( !$this.settings.value.split(";")[1] ){ 277 | this.settings.single = true; 278 | this.domNode.addDependClass("single"); 279 | } 280 | 281 | if( !$this.settings.limits ) 282 | this.domNode.addDependClass("limitless"); 283 | 284 | this.domNode.find(OPTIONS.selector + "pointer").each(function( i ){ 285 | var value = $this.settings.value.split(";")[i]; 286 | if( value ){ 287 | $this.o.pointers[i] = new jSliderPointer( this, i, $this ); 288 | 289 | var prev = $this.settings.value.split(";")[i-1]; 290 | if( prev && new Number(value) < new Number(prev) ) value = prev; 291 | 292 | value = value < $this.settings.from ? $this.settings.from : value; 293 | value = value > $this.settings.to ? $this.settings.to : value; 294 | 295 | $this.o.pointers[i].set( value, true ); 296 | } 297 | }); 298 | 299 | this.o.value = this.domNode.find(".v"); 300 | this.is.init = true; 301 | 302 | $.each(this.o.pointers, function(i){ 303 | $this.redraw(this); 304 | }); 305 | 306 | (function(self){ 307 | $(window).resize(function(){ 308 | self.onresize(); 309 | }); 310 | })(this); 311 | 312 | }; 313 | 314 | jSlider.prototype.setSkin = function( skin ){ 315 | if( this.skin_ ) 316 | this.domNode.removeDependClass( this.skin_, "_" ); 317 | 318 | this.domNode.addDependClass( this.skin_ = skin, "_" ); 319 | }; 320 | 321 | jSlider.prototype.setPointersIndex = function( i ){ 322 | $.each(this.getPointers(), function(i){ 323 | this.index( i ); 324 | }); 325 | }; 326 | 327 | jSlider.prototype.getPointers = function(){ 328 | return this.o.pointers; 329 | }; 330 | 331 | jSlider.prototype.generateScale = function(){ 332 | if( this.settings.scale && this.settings.scale.length > 0 ){ 333 | var str = ""; 334 | var s = this.settings.scale; 335 | var prc = Math.round((100/(s.length-1))*10)/10; 336 | for( var i=0; i < s.length; i++ ){ 337 | str += '' + ( s[i] != '|' ? '' + s[i] + '' : '' ) + ''; 338 | }; 339 | return str; 340 | } else return ""; 341 | 342 | return ""; 343 | }; 344 | 345 | jSlider.prototype.drawScale = function(){ 346 | this.domNode.find(OPTIONS.selector + "scale span ins").each(function(){ 347 | $(this).css({ marginLeft: -$(this).outerWidth()/2 }); 348 | }); 349 | }; 350 | 351 | jSlider.prototype.onresize = function(){ 352 | var self = this; 353 | this.sizes = { 354 | domWidth: this.domNode.width(), 355 | domOffset: this.domNode.offset() 356 | }; 357 | 358 | $.each(this.o.pointers, function(i){ 359 | self.redraw(this); 360 | }); 361 | }; 362 | 363 | jSlider.prototype.update = function(){ 364 | this.onresize(); 365 | this.drawScale(); 366 | }; 367 | 368 | jSlider.prototype.limits = function( x, pointer ){ 369 | // smooth 370 | if( !this.settings.smooth ){ 371 | var step = this.settings.step*100 / ( this.settings.interval ); 372 | x = Math.round( x/step ) * step; 373 | } 374 | 375 | var another = this.o.pointers[1-pointer.uid]; 376 | if( another && pointer.uid && x < another.value.prc ) x = another.value.prc; 377 | if( another && !pointer.uid && x > another.value.prc ) x = another.value.prc; 378 | 379 | // base limit 380 | if( x < 0 ) x = 0; 381 | if( x > 100 ) x = 100; 382 | 383 | return Math.round( x*10 ) / 10; 384 | }; 385 | 386 | jSlider.prototype.redraw = function( pointer ){ 387 | if( !this.is.init ) return false; 388 | 389 | this.setValue(); 390 | 391 | // redraw range line 392 | if( this.o.pointers[0] && this.o.pointers[1] ) 393 | this.o.value.css({ left: this.o.pointers[0].value.prc + "%", width: ( this.o.pointers[1].value.prc - this.o.pointers[0].value.prc ) + "%" }); 394 | 395 | this.o.labels[pointer.uid].value.html( 396 | this.nice( 397 | pointer.value.origin 398 | ) 399 | ); 400 | 401 | // redraw position of labels 402 | this.redrawLabels( pointer ); 403 | 404 | }; 405 | 406 | jSlider.prototype.redrawLabels = function( pointer ){ 407 | 408 | function setPosition( label, sizes, prc ){ 409 | sizes.margin = -sizes.label/2; 410 | 411 | // left limit 412 | label_left = sizes.border + sizes.margin; 413 | if( label_left < 0 ) 414 | sizes.margin -= label_left; 415 | 416 | // right limit 417 | if( sizes.border+sizes.label / 2 > self.sizes.domWidth ){ 418 | sizes.margin = 0; 419 | sizes.right = true; 420 | } else 421 | sizes.right = false; 422 | 423 | label.o.css({ left: prc + "%", marginLeft: sizes.margin, right: "auto" }); 424 | if( sizes.right ) label.o.css({ left: "auto", right: 0 }); 425 | return sizes; 426 | } 427 | 428 | var self = this; 429 | var label = this.o.labels[pointer.uid]; 430 | var prc = pointer.value.prc; 431 | 432 | var sizes = { 433 | label: label.o.outerWidth(), 434 | right: false, 435 | border: ( prc * this.sizes.domWidth ) / 100 436 | }; 437 | 438 | if( !this.settings.single ){ 439 | // glue if near; 440 | var another = this.o.pointers[1-pointer.uid]; 441 | var another_label = this.o.labels[another.uid]; 442 | 443 | switch( pointer.uid ){ 444 | case 0: 445 | if( sizes.border+sizes.label / 2 > another_label.o.offset().left-this.sizes.domOffset.left ){ 446 | another_label.o.css({ visibility: "hidden" }); 447 | another_label.value.html( this.nice( another.value.origin ) ); 448 | 449 | label.o.css({ visibility: "visible" }); 450 | 451 | prc = ( another.value.prc - prc ) / 2 + prc; 452 | if( another.value.prc != pointer.value.prc ){ 453 | label.value.html( this.nice(pointer.value.origin) + " – " + this.nice(another.value.origin) ); 454 | sizes.label = label.o.outerWidth(); 455 | sizes.border = ( prc * this.sizes.domWidth ) / 100; 456 | } 457 | } else { 458 | another_label.o.css({ visibility: "visible" }); 459 | } 460 | break; 461 | 462 | case 1: 463 | if( sizes.border - sizes.label / 2 < another_label.o.offset().left - this.sizes.domOffset.left + another_label.o.outerWidth() ){ 464 | another_label.o.css({ visibility: "hidden" }); 465 | another_label.value.html( this.nice(another.value.origin) ); 466 | 467 | label.o.css({ visibility: "visible" }); 468 | 469 | prc = ( prc - another.value.prc ) / 2 + another.value.prc; 470 | if( another.value.prc != pointer.value.prc ){ 471 | label.value.html( this.nice(another.value.origin) + " – " + this.nice(pointer.value.origin) ); 472 | sizes.label = label.o.outerWidth(); 473 | sizes.border = ( prc * this.sizes.domWidth ) / 100; 474 | } 475 | } else { 476 | another_label.o.css({ visibility: "visible" }); 477 | } 478 | break; 479 | } 480 | } 481 | 482 | sizes = setPosition( label, sizes, prc ); 483 | 484 | /* draw second label */ 485 | if( another_label ){ 486 | var sizes = { 487 | label: another_label.o.outerWidth(), 488 | right: false, 489 | border: ( another.value.prc * this.sizes.domWidth ) / 100 490 | }; 491 | sizes = setPosition( another_label, sizes, another.value.prc ); 492 | } 493 | 494 | this.redrawLimits(); 495 | }; 496 | 497 | jSlider.prototype.redrawLimits = function(){ 498 | if( this.settings.limits ){ 499 | 500 | var limits = [ true, true ]; 501 | 502 | for( key in this.o.pointers ){ 503 | 504 | if( !this.settings.single || key == 0 ){ 505 | 506 | var pointer = this.o.pointers[key]; 507 | var label = this.o.labels[pointer.uid]; 508 | var label_left = label.o.offset().left - this.sizes.domOffset.left; 509 | 510 | var limit = this.o.limits[0]; 511 | if( label_left < limit.outerWidth() ) 512 | limits[0] = false; 513 | 514 | var limit = this.o.limits[1]; 515 | if( label_left + label.o.outerWidth() > this.sizes.domWidth - limit.outerWidth() ) 516 | limits[1] = false; 517 | } 518 | 519 | }; 520 | 521 | for( var i=0; i < limits.length; i++ ){ 522 | if( limits[i] ) 523 | this.o.limits[i].fadeIn("fast"); 524 | else 525 | this.o.limits[i].fadeOut("fast"); 526 | }; 527 | 528 | } 529 | }; 530 | 531 | jSlider.prototype.setValue = function(){ 532 | var value = this.getValue(); 533 | this.inputNode.attr( "value", value ); 534 | this.onstatechange.call( this, value ); 535 | }; 536 | 537 | jSlider.prototype.getValue = function(){ 538 | if(!this.is.init) return false; 539 | var $this = this; 540 | 541 | var value = ""; 542 | $.each( this.o.pointers, function(i){ 543 | if( this.value.prc != undefined && !isNaN(this.value.prc) ) value += (i > 0 ? ";" : "") + $this.prcToValue( this.value.prc ); 544 | }); 545 | return value; 546 | }; 547 | 548 | jSlider.prototype.getPrcValue = function(){ 549 | if(!this.is.init) return false; 550 | var $this = this; 551 | 552 | var value = ""; 553 | $.each( this.o.pointers, function(i){ 554 | if( this.value.prc != undefined && !isNaN(this.value.prc) ) value += (i > 0 ? ";" : "") + this.value.prc; 555 | }); 556 | return value; 557 | }; 558 | 559 | jSlider.prototype.prcToValue = function( prc ){ 560 | 561 | if( this.settings.heterogeneity && this.settings.heterogeneity.length > 0 ){ 562 | var h = this.settings.heterogeneity; 563 | 564 | var _start = 0; 565 | var _from = this.settings.from; 566 | 567 | for( var i=0; i <= h.length; i++ ){ 568 | if( h[i] ) var v = h[i].split("/"); 569 | else var v = [100, this.settings.to]; 570 | 571 | v[0] = new Number(v[0]); 572 | v[1] = new Number(v[1]); 573 | 574 | if( prc >= _start && prc <= v[0] ) { 575 | var value = _from + ( (prc-_start) * (v[1]-_from) ) / (v[0]-_start); 576 | } 577 | 578 | _start = v[0]; 579 | _from = v[1]; 580 | }; 581 | 582 | } else { 583 | var value = this.settings.from + ( prc * this.settings.interval ) / 100; 584 | } 585 | 586 | return this.round( value ); 587 | }; 588 | 589 | jSlider.prototype.valueToPrc = function( value, pointer ){ 590 | if( this.settings.heterogeneity && this.settings.heterogeneity.length > 0 ){ 591 | var h = this.settings.heterogeneity; 592 | 593 | var _start = 0; 594 | var _from = this.settings.from; 595 | 596 | for (var i=0; i <= h.length; i++) { 597 | if(h[i]) var v = h[i].split("/"); 598 | else var v = [100, this.settings.to]; 599 | v[0] = new Number(v[0]); v[1] = new Number(v[1]); 600 | 601 | if(value >= _from && value <= v[1]){ 602 | var prc = pointer.limits(_start + (value-_from)*(v[0]-_start)/(v[1]-_from)); 603 | } 604 | 605 | _start = v[0]; _from = v[1]; 606 | }; 607 | 608 | } else { 609 | var prc = pointer.limits((value-this.settings.from)*100/this.settings.interval); 610 | } 611 | 612 | return prc; 613 | }; 614 | 615 | jSlider.prototype.round = function( value ){ 616 | value = Math.round( value / this.settings.step ) * this.settings.step; 617 | if( this.settings.round ) value = Math.round( value * Math.pow(10, this.settings.round) ) / Math.pow(10, this.settings.round); 618 | else value = Math.round( value ); 619 | return value; 620 | }; 621 | 622 | jSlider.prototype.nice = function( value ){ 623 | value = value.toString().replace(/,/gi, ".").replace(/ /gi, "");; 624 | 625 | if( $.formatNumber ){ 626 | return $.formatNumber( new Number(value), this.settings.format || {} ).replace( /-/gi, "−" ); 627 | } 628 | 629 | else { 630 | return new Number(value); 631 | } 632 | }; 633 | 634 | 635 | function jSliderPointer(){ 636 | Draggable.apply( this, arguments ); 637 | } 638 | jSliderPointer.prototype = new Draggable(); 639 | 640 | jSliderPointer.prototype.oninit = function( ptr, id, _constructor ){ 641 | this.uid = id; 642 | this.parent = _constructor; 643 | this.value = {}; 644 | this.settings = this.parent.settings; 645 | }; 646 | 647 | jSliderPointer.prototype.onmousedown = function(evt){ 648 | this._parent = { 649 | offset: this.parent.domNode.offset(), 650 | width: this.parent.domNode.width() 651 | }; 652 | this.ptr.addDependClass("hover"); 653 | this.setIndexOver(); 654 | }; 655 | 656 | jSliderPointer.prototype.onmousemove = function( evt, x ){ 657 | var coords = this._getPageCoords( evt ); 658 | this._set( this.calc( coords.x ) ); 659 | }; 660 | 661 | jSliderPointer.prototype.onmouseup = function( evt ){ 662 | if( this.parent.settings.callback && $.isFunction(this.parent.settings.callback) ) 663 | this.parent.settings.callback.call( this.parent, this.parent.getValue() ); 664 | 665 | this.ptr.removeDependClass("hover"); 666 | }; 667 | 668 | jSliderPointer.prototype.setIndexOver = function(){ 669 | this.parent.setPointersIndex( 1 ); 670 | this.index( 2 ); 671 | }; 672 | 673 | jSliderPointer.prototype.index = function( i ){ 674 | this.ptr.css({ zIndex: i }); 675 | }; 676 | 677 | jSliderPointer.prototype.limits = function( x ){ 678 | return this.parent.limits( x, this ); 679 | }; 680 | 681 | jSliderPointer.prototype.calc = function(coords){ 682 | var x = this.limits(((coords-this._parent.offset.left)*100)/this._parent.width); 683 | return x; 684 | }; 685 | 686 | jSliderPointer.prototype.set = function( value, opt_origin ){ 687 | this.value.origin = this.parent.round(value); 688 | this._set( this.parent.valueToPrc( value, this ), opt_origin ); 689 | }; 690 | 691 | jSliderPointer.prototype._set = function( prc, opt_origin ){ 692 | if( !opt_origin ) 693 | this.value.origin = this.parent.prcToValue(prc); 694 | 695 | this.value.prc = prc; 696 | this.ptr.css({ left: prc + "%" }); 697 | this.parent.redraw(this); 698 | }; 699 | 700 | })(jQuery); 701 | -------------------------------------------------------------------------------- /dist/angular-awesome-slider.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license angular-awesome-slider - v2.4.4 3 | * (c) 2013 Julien VALERY https://github.com/darul75/angular-awesome-slider 4 | * License: MIT 5 | **/ 6 | !function(a){"use strict";a.module("angularAwesomeSlider",[]).directive("slider",["$compile","$templateCache","$timeout","$window","slider",function(b,c,d,e,f){return{restrict:"AE",require:"?ngModel",scope:{options:"=",ngDisabled:"="},priority:1,link:function(g,h,i,j){function k(){ 7 | // window resize listener 8 | a.element(e).bind("resize",function(a){g.slider.onresize()})}if(j){if(!g.options)throw new Error('You must provide a value for "options" attribute.');a.injector(); 9 | // options as inline variable 10 | a.isString(g.options)&&(g.options=a.toJson(g.options)),g.mainSliderClass="jslider",g.mainSliderClass+=g.options.skin?" jslider_"+g.options.skin:" ",g.mainSliderClass+=g.options.vertical?" vertical ":"",g.mainSliderClass+=g.options.css?" sliderCSS":"",g.mainSliderClass+=g.options.className?" "+g.options.className:"", 11 | // handle limit labels visibility 12 | g.options.limits=a.isDefined(g.options.limits)?g.options.limits:!0, 13 | // compile template 14 | h.after(b(c.get("ng-slider/slider-bar.tmpl.html"))(g,function(a,b){b.tmplElt=a})); 15 | // init 16 | var l=!1,m=function(b){g.from=""+g.options.from,g.to=""+g.options.to,g.options.calculate&&a.isFunction(g.options.calculate)&&(g.from=g.options.calculate(g.from),g.to=g.options.calculate(g.to));var c={from:g.options.round?parseFloat(g.options.from):parseInt(g.options.from,10),to:g.options.round?parseFloat(g.options.to):parseInt(g.options.to,10),step:g.options.step,smooth:g.options.smooth,limits:g.options.limits,round:g.options.round||!1,value:b||j.$viewValue,dimension:"",scale:g.options.scale,modelLabels:g.options.modelLabels,vertical:g.options.vertical,css:g.options.css,className:g.options.className,realtime:g.options.realtime,cb:n,threshold:g.options.threshold,heterogeneity:g.options.heterogeneity,logScale:g.options.logScale};c.calculate=g.options.calculate||void 0,c.onstatechange=g.options.onstatechange||void 0, 17 | // slider 18 | g.slider=g.slider?g.slider.init(h,g.tmplElt,c):p(h,g.tmplElt,c),l||k(); 19 | // scale 20 | var d=g.tmplElt.find("div")[7];a.element(d).html(g.slider.generateScale()),g.slider.drawScale(d),g.ngDisabled&&o(g.ngDisabled),l=!0}; 21 | // model -> view 22 | j.$render=function(){if((j.$viewValue||0===j.$viewValue)&&("number"==typeof j.$viewValue&&(j.$viewValue=""+j.$viewValue),j.$viewValue.split(";")[1]?g.mainSliderClass=g.mainSliderClass.replace(" jslider-single",""):g.mainSliderClass+=" jslider-single",g.slider)){var a=j.$viewValue.split(";");g.slider.getPointers()[0].set(a[0],!0),a[1]&&(g.slider.getPointers()[1].set(a[1],!0), 23 | //if moving left to right with two pointers 24 | //we need to "finish" moving the first 25 | parseInt(a[1])>parseInt(a[0])&&g.slider.getPointers()[0].set(a[0],!0))}},g.$on("slider-value-update",function(a,b){m(b.value),d(function(){g.slider.redrawPointers()})}); 26 | // view -> model 27 | var n=function(a,b){g.disabled||(g.$apply(function(){j.$setViewValue(a)}),g.options.callback&&g.options.callback(a,b))}; 28 | // watch options 29 | g.$watch("options",function(a){d(function(){m()})},g.watchOptions||!0); 30 | // disabling 31 | var o=function(a){g.disabled=a,g.slider&&(g.tmplElt.toggleClass("disabled"),g.slider.disable(a))};g.$watch("ngDisabled",function(a){o(a)}),g.limitValue=function(b){return g.options.modelLabels?a.isFunction(g.options.modelLabels)?g.options.modelLabels(b):void 0!==g.options.modelLabels[b]?g.options.modelLabels[b]:b:b};var p=function(a,b,c){return new f(a,b,c)}}}}}]).config(function(){}).run(function(){})}(angular),function(a){"use strict";a.module("angularAwesomeSlider").constant("sliderConstants",{SLIDER:{settings:{from:1,to:40,step:1,smooth:!0,limits:!1,round:!1,value:"3",dimension:"",vertical:!1,calculate:!1,onstatechange:!1,callback:!1,realtime:!1},className:"jslider",selector:".jslider-",css:{visible:{visibility:"visible"},hidden:{visibility:"hidden"}}},EVENTS:{}})}(angular),function(a){"use strict";a.module("angularAwesomeSlider").factory("sliderUtils",["$window",function(a){return{offset:function(a){ 32 | // try {return elm.offset();} catch(e) {} 33 | var b=a[0],c=0,d=0,e=document.documentElement||document.body,f=window.pageXOffset||e.scrollLeft,g=window.pageYOffset||e.scrollTop;return c=b.getBoundingClientRect().left+f,d=b.getBoundingClientRect().top+g,{left:c,top:d}},browser:function(){ 34 | // TODO finish browser detection and this case 35 | var b=a.navigator.userAgent,c={mozilla:/mozilla/i,chrome:/chrome/i,safari:/safari/i,firefox:/firefox/i,ie:/internet explorer/i};for(var d in c)if(c[d].test(b))return d;return"unknown"}}}])}(angular),function(a){"use strict";a.module("angularAwesomeSlider").factory("sliderDraggable",["sliderUtils",function(b){function c(){this._init.apply(this,arguments)}return c.prototype.oninit=function(){},c.prototype.events=function(){},c.prototype.onmousedown=function(){this.ptr.css({position:"absolute"})},c.prototype.onmousemove=function(a,b,c){this.ptr.css({left:b,top:c})},c.prototype.onmouseup=function(){},c.prototype.isDefault={drag:!1,clicked:!1,toclick:!0,mouseup:!1},c.prototype._init=function(){if(arguments.length>0){if(this.ptr=arguments[0],this.label=arguments[3],this.parent=arguments[2],!this.ptr)return; 36 | //this.outer = $(".draggable-outer"); 37 | this.is={},a.extend(this.is,this.isDefault);var c=b.offset(this.ptr);this.d={left:c.left,top:c.top,width:this.ptr[0].clientWidth,height:this.ptr[0].clientHeight},this.oninit.apply(this,arguments),this._events()}},c.prototype._getPageCoords=function(a){return a.targetTouches&&a.targetTouches[0]?{x:a.targetTouches[0].pageX,y:a.targetTouches[0].pageY}:{x:a.pageX,y:a.pageY}},c.prototype._bindEvent=function(a,b,c){ 38 | // PS need to bind to touch and non-touch events for devices which support both 39 | this.supportTouches_&&a[0].addEventListener(this.events_[b].touch,c,!1),a.bind(this.events_[b].nonTouch,c)},c.prototype._events=function(){var b=this;this.supportTouches_="ontouchend"in document,this.events_={click:{touch:"touchstart",nonTouch:"click"},down:{touch:"touchstart",nonTouch:"mousedown"},move:{touch:"touchmove",nonTouch:"mousemove"},up:{touch:"touchend",nonTouch:"mouseup"},mousedown:{touch:"mousedown",nonTouch:"mousedown"}};var c=a.element(window.document);this._bindEvent(c,"move",function(a){b.is.drag&&(a.stopPropagation(),a.preventDefault(),b.parent.disabled||b._mousemove(a))}),this._bindEvent(c,"down",function(a){b.is.drag&&(a.stopPropagation(),a.preventDefault())}),this._bindEvent(c,"up",function(a){b._mouseup(a)}),this._bindEvent(this.label,"down",function(a){return b._mousedown(a),!1}),this._bindEvent(this.label,"up",function(a){b._mouseup(a)}),this._bindEvent(this.ptr,"down",function(a){return b._mousedown(a),!1}),this._bindEvent(this.ptr,"up",function(a){b._mouseup(a)}), 40 | // TODO see if needed 41 | this.events()},c.prototype._mousedown=function(b){this.is.drag=!0,this.is.clicked=!1,this.is.mouseup=!1;var c=this._getPageCoords(b);this.cx=c.x-this.ptr[0].offsetLeft,this.cy=c.y-this.ptr[0].offsetTop,a.extend(this.d,{left:c.x,top:c.y,width:this.ptr[0].clientWidth,height:this.ptr[0].clientHeight}),this.outer&&this.outer.get(0)&&this.outer.css({height:Math.max(this.outer.height(),$(document.body).height()),overflow:"hidden"}),this.onmousedown(b)},c.prototype._mousemove=function(a){this.is.toclick=!1;var b=this._getPageCoords(a);this.onmousemove(a,b.x-this.cx,b.y-this.cy)},c.prototype._mouseup=function(a){if(this.is.drag){this.is.drag=!1;var c=b.browser();this.outer&&this.outer.get(0)&&("mozilla"===c?this.outer.css({overflow:"hidden"}):this.outer.css({overflow:"visible"}), 42 | // TODO finish browser detection and this case, remove following line 43 | this.outer.css({height:"auto"})),this.onmouseup(a)}},c}])}(angular),function(a){"use strict";a.module("angularAwesomeSlider").factory("sliderPointer",["sliderDraggable","sliderUtils",function(b,c){function d(){b.apply(this,arguments)}return d.prototype=new b,d.prototype.oninit=function(b,c,d,e,f){this.uid=c,this.parent=f,this.value={},this.vertical=d,this.settings=a.copy(f.settings),this.threshold=this.settings.threshold},d.prototype.onmousedown=function(a){var b=c.offset(this.parent.domNode),d={left:b.left,top:b.top,width:this.parent.domNode[0].clientWidth,height:this.parent.domNode[0].clientHeight};this._parent={offset:d,width:d.width,height:d.height},this.ptr.addClass("jslider-pointer-hover")},d.prototype.onmousemove=function(b,c,d){var e=this._getPageCoords(b);this._set(this.vertical?this.calc(e.y):this.calc(e.x)),this.settings.realtime&&this.settings.cb&&a.isFunction(this.settings.cb)&&this.settings.cb.call(this.parent,this.parent.getValue(),!this.is.drag)},d.prototype.onmouseup=function(b){this.settings.cb&&a.isFunction(this.settings.cb)&&this.settings.cb.call(this.parent,this.parent.getValue(),!this.is.drag),this.is.drag||this.ptr.removeClass("jslider-pointer-hover")},d.prototype.limits=function(a){return this.parent.limits(a,this)},d.prototype.calc=function(a){return this.vertical?this.limits(100*(a-this._parent.offset.top)/this._parent.height):this.limits(100*(a-this._parent.offset.left)/this._parent.width)},d.prototype.set=function(a,b){this.value.origin=this.parent.round(a),this._set(this.parent.valueToPrc(a,this),b)},d.prototype._set=function(a,b){this.allowed=!0;var c=this.value.origin,d=this.value.prc; 44 | // check threshold 45 | if(this.value.origin=this.parent.prcToValue(a),this.value.prc=a,this.threshold&&this.parent.o.pointers[1]){var e=this.value.origin,f=this.parent.o.pointers[0===this.uid?1:0].value.origin;this.allowed=Math.abs(f-e)>=this.threshold,this.allowed||void 0===c||void 0===d||(this.value.origin=c,this.value.prc=d)}this.vertical?this.ptr.css({top:this.value.prc+"%",marginTop:-5}):this.ptr.css({left:this.value.prc+"%"}),this.parent.redraw(this)},d}])}(angular),function(a){"use strict";a.module("angularAwesomeSlider").factory("slider",["sliderPointer","sliderConstants","sliderUtils",function(b,c,d){function e(){return this.init.apply(this,arguments)}return e.prototype.init=function(b,d,e){return this.settings=e,this.inputNode=b,this.inputNode.addClass("ng-hide"),this.settings.interval=this.settings.to-this.settings.from,this.settings.calculate&&a.isFunction(this.settings.calculate)&&(this.nice=this.settings.calculate),this.settings.onstatechange&&a.isFunction(this.settings.onstatechange)&&(this.onstatechange=this.settings.onstatechange),this.css=c.SLIDER.css,this.is={init:!1},this.o={},this.initValue={},this.isAsc=e.from 0 ) 48 | // this.setSkin( this.settings.skin ); 49 | var e=this;this.domNode=c;var f=this.domNode.find("div"),g=this.domNode.find("i"),h=a.element,i=a.extend,j=a.forEach,k=h(f[1]),l=h(f[2]),m=h(f[5]),n=h(f[6]),o=h(g[0]),p=h(g[1]),q=h(g[2]),r=h(g[3]),s=h(g[4]),t=h(g[5]),u=h(g[6]),v=[m,n],w=[k,l],x=d.offset(this.domNode),y={left:x.left,top:x.top,width:this.domNode[0].clientWidth,height:this.domNode[0].clientHeight},z=e.settings.value.split(";");this.sizes={domWidth:this.domNode[0].clientWidth,domHeight:this.domNode[0].clientHeight,domOffset:y}, 50 | // find some objects 51 | i(this.o,{pointers:{},labels:{0:{o:m},1:{o:n}},limits:{0:a.element(f[3]),1:a.element(f[4])},indicators:{0:r,1:s,2:t,3:u}}),i(this.o.labels[0],{value:this.o.labels[0].o.find("span")}),i(this.o.labels[1],{value:this.o.labels[1].o.find("span")}), 52 | // single pointer 53 | this.settings.single=!e.settings.value.split(";")[1],this.settings.single?q.addClass("ng-hide"):q.removeClass("ng-hide"),j(w,function(c,f){e.settings=a.copy(e.settings);var g,h,i,j,k,l=z[f];l&&(e.o.pointers[f]=new b(c,f,e.settings.vertical,v[f],e),g=z[f-1],h=g?parseInt(g,10):void 0,l=e.settings.round?parseFloat(l):parseInt(l,10),(g&&e.isAsc?h>l:l>h)&&(l=g),i=e.isAsc?l>e.settings.to:l=q||l>=q-r;s&&(o=j)}o._parent={offset:n,width:n.width,height:n.height};var t=i._getPageCoords(e);return o.cx=t.x-o.d.left,o.cy=t.y-o.d.top,o.onmousemove(e,t.x,t.y),o.onmouseup(),a.extend(o.d,{left:t.x,top:t.y}),b.redraw(o),!1}}},e.prototype.disable=function(a){this.disabled=a},e.prototype.nice=function(a){return a},e.prototype.onstatechange=function(){},e.prototype.limits=function(a,b){ 56 | // smooth 57 | if(!this.settings.smooth){var c=100*this.settings.step/this.settings.interval;a=Math.round(a/c)*c}if(b){var d=this.o.pointers[1-b.uid];d&&b.uid&&ad.value.prc&&(a=d.value.prc)} 58 | // base limit 59 | return 0>a&&(a=0),a>100&&(a=100),Math.round(10*a)/10},e.prototype.getPointers=function(){return this.o.pointers},e.prototype.generateScale=function(){if(this.settings.scale&&this.settings.scale.length>0){for(var 60 | // FIX Big Scale Failure #34 61 | // var prc = Math.round((100/(s.length-1))*10)/10; 62 | b,c,d="",e=this.settings.scale,f={},g=this.settings.vertical?"top":"left",h=0;h'+("|"!=e[h]?""+e[h]+"":"")+""),e[h].val<=this.settings.to&&e[h].val>=this.settings.from&&!f[e[h].val]&&(f[e[h].val]=!0,b=this.valueToPrc(e[h].val),c=e[h].label?e[h].label:e[h].val,d+=''+c+"");return d}return""},e.prototype.onresize=function(){this.sizes={domWidth:this.domNode[0].clientWidth,domHeight:this.domNode[0].clientHeight,domOffset:{left:this.domNode[0].offsetLeft,top:this.domNode[0].offsetTop,width:this.domNode[0].clientWidth,height:this.domNode[0].clientHeight}},this.redrawPointers()},e.prototype.update=function(){this.onresize(),this.drawScale()},e.prototype.drawScale=function(b){a.forEach(a.element(b).find("ins"),function(a,b){a.style.marginLeft=-a.clientWidth/2})},e.prototype.redrawPointers=function(){a.forEach(this.o.pointers,function(a){this.redraw(a)},this)},e.prototype.redraw=function(b){if(!this.is.init) 63 | // this.settings.single 64 | return this.o.pointers[0]&&!this.o.pointers[1]?(this.originValue=this.o.pointers[0].value.prc,this.o.indicators[0].css(this.settings.vertical?{top:0,height:this.o.pointers[0].value.prc+"%"}:{left:0,width:this.o.pointers[0].value.prc+"%"}),this.o.indicators[1].css(this.settings.vertical?{top:this.o.pointers[0].value.prc+"%"}:{left:this.o.pointers[0].value.prc+"%"}),this.o.indicators[3].css(this.settings.vertical?{top:this.o.pointers[0].value.prc+"%"}:{left:this.o.pointers[0].value.prc+"%"})):(this.o.indicators[2].css(this.settings.vertical?{top:this.o.pointers[1].value.prc+"%"}:{left:this.o.pointers[1].value.prc+"%"}),this.o.indicators[0].css(this.settings.vertical?{top:0,height:"0"}:{left:0,width:"0"}),this.o.indicators[3].css(this.settings.vertical?{top:"0",height:"0"}:{left:"0",width:"0"})),!1;this.setValue();var c,d; 65 | // redraw range line 66 | this.o.pointers[0]&&this.o.pointers[1]&&(c=this.settings.vertical?{top:this.o.pointers[0].value.prc+"%",height:this.o.pointers[1].value.prc-this.o.pointers[0].value.prc+"%"}:{left:this.o.pointers[0].value.prc+"%",width:this.o.pointers[1].value.prc-this.o.pointers[0].value.prc+"%"},this.o.value.css(c),this.o.pointers[0].value.prc===this.o.pointers[1].value.prc&&this.o.pointers[1].ptr.css("z-index",0===this.o.pointers[0].value.prc?"3":"1")),this.o.pointers[0]&&!this.o.pointers[1]&&(d=this.o.pointers[0].value.prc-this.originValue,d>=0?this.o.indicators[3].css(this.settings.vertical?{height:d+"%"}:{width:d+"%"}):this.o.indicators[3].css(this.settings.vertical?{height:0}:{width:0}),this.o.pointers[0].value.prcf&&(b.margin-=f), 71 | // right limit 72 | c.sizes.domWidth>0&&b.border+b.label/2>e?(b.margin=0,b.right=!0):b.right=!1}return c.settings.vertical?a.o.css({top:d+"%",marginLeft:"20px",marginTop:b.margin,bottom:"auto"}):a.o.css({left:d+"%",marginLeft:b.margin+"px",right:"auto"}),b.right&&c.sizes.domWidth>0&&(c.settings.vertical?a.o.css({top:"auto",bottom:0}):a.o.css({left:"auto",right:0})),b}var c=this,d=this.o.labels[a.uid],e=a.value.prc, 73 | // case hidden 74 | f=0===d.o[0].offsetWidth?7*d.o[0].textContent.length:d.o[0].offsetWidth;this.sizes.domWidth=this.domNode[0].clientWidth,this.sizes.domHeight=this.domNode[0].clientHeight;var g,h,i={label:c.settings.vertical?d.o[0].offsetHeight:f,right:!1,border:e*(c.settings.vertical?this.sizes.domHeight:this.sizes.domWidth)/100},j=0===a.uid?1:0;if(!this.settings.single&&!this.settings.vertical){ 75 | // glue if near; 76 | g=this.o.labels[j],h=this.o.pointers[j];var k=this.o.labels[0],l=this.o.labels[1],m=this.o.pointers[0],n=this.o.pointers[1],o=n.ptr[0].offsetLeft-m.ptr[0].offsetLeft,p=this.nice(h.value.origin);if(k.o.css(this.css.visible),l.o.css(this.css.visible),p=this.getLabelValue(p),o+10