├── .gitattributes
├── .gitignore
├── .jscsrc
├── .jshintrc
├── README.md
├── bower.json
├── dist
├── jquery-ui-slider-pips.css
├── jquery-ui-slider-pips.js
├── jquery-ui-slider-pips.min.css
└── jquery-ui-slider-pips.min.js
├── gulpfile.js
├── package.json
└── src
├── css
└── jquery-ui-slider-pips.scss
└── js
└── jquery-ui-slider-pips.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 |
33 |
34 |
35 | #################
36 | ## Visual Studio
37 | #################
38 |
39 | ## Ignore Visual Studio temporary files, build results, and
40 | ## files generated by popular Visual Studio add-ons.
41 |
42 | # User-specific files
43 | *.suo
44 | *.user
45 | *.sln.docstates
46 |
47 | # Build results
48 | [Dd]ebug/
49 | [Rr]elease/
50 | *_i.c
51 | *_p.c
52 | *.ilk
53 | *.meta
54 | *.obj
55 | *.pch
56 | *.pdb
57 | *.pgc
58 | *.pgd
59 | *.rsp
60 | *.sbr
61 | *.tlb
62 | *.tli
63 | *.tlh
64 | *.tmp
65 | *.vspscc
66 | .builds
67 | *.dotCover
68 |
69 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
70 | #packages/
71 |
72 | # Visual C++ cache files
73 | ipch/
74 | *.aps
75 | *.ncb
76 | *.opensdf
77 | *.sdf
78 |
79 | # Visual Studio profiler
80 | *.psess
81 | *.vsp
82 |
83 | # ReSharper is a .NET coding add-in
84 | _ReSharper*
85 |
86 | # Installshield output folder
87 | [Ee]xpress
88 |
89 | # DocProject is a documentation generator add-in
90 | DocProject/buildhelp/
91 | DocProject/Help/*.HxT
92 | DocProject/Help/*.HxC
93 | DocProject/Help/*.hhc
94 | DocProject/Help/*.hhk
95 | DocProject/Help/*.hhp
96 | DocProject/Help/Html2
97 | DocProject/Help/html
98 |
99 | # Click-Once directory
100 | publish
101 |
102 | # Others
103 | [Bb]in
104 | [Oo]bj
105 | sql
106 | TestResults
107 | *.Cache
108 | ClientBin
109 | stylecop.*
110 | ~$*
111 | *.dbmdl
112 | Generated_Code #added for RIA/Silverlight projects
113 |
114 | # Backup & report files from converting an old project file to a newer
115 | # Visual Studio version. Backup files are not needed, because we have git ;-)
116 | _UpgradeReport_Files/
117 | Backup*/
118 | UpgradeLog*.XML
119 |
120 |
121 |
122 |
123 | ############
124 | ## Windows / OSX
125 | ############
126 |
127 | # Image file caches
128 | Thumbs.db
129 | .DS_Store
130 |
131 | # Folder config file
132 | Desktop.ini
133 |
134 |
135 | #############
136 | ## Python
137 | #############
138 |
139 | *.py[co]
140 |
141 | # Packages
142 | *.egg
143 | *.egg-info
144 | build
145 | eggs
146 | parts
147 | bin
148 | var
149 | sdist
150 | develop-eggs
151 | .installed.cfg
152 |
153 | # Installer logs
154 | pip-log.txt
155 |
156 | # Unit test / coverage reports
157 | .coverage
158 | .tox
159 |
160 | #Translations
161 | *.mo
162 |
163 | #Mr Developer
164 | .mr.developer.cfg
165 |
166 |
167 |
168 | ############
169 | ## Node
170 | ############
171 | node_modules/
172 |
173 |
174 | ############
175 | ## Bower
176 | ############
177 | bower_components
178 |
179 |
180 | ############
181 | ## Sass
182 | ############
183 | .sass-cache
184 |
185 |
186 |
187 | #########################################
188 |
189 | demo.html
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "maximumLineLength": 120,
4 |
5 | "disallowCapitalizedComments": true,
6 | "disallowDanglingUnderscores": { "allExcept": [
7 | "_this",
8 | "_data",
9 | "_valueMin",
10 | "_valueMax",
11 | "_value",
12 | "_values",
13 | "_lastChangedValue",
14 | "_change",
15 | "_trimAlignValue",
16 | "_refreshValue"] },
17 | "disallowEmptyBlocks": true,
18 | "disallowImplicitTypeConversion": [ "string", "number" ],
19 | "disallowKeywordsOnNewLine": [ "else", "catch", "while" ],
20 | "disallowKeywords": [ "with" ],
21 | "disallowMixedSpacesAndTabs": true,
22 | "disallowMultipleLineStrings": true,
23 | "disallowMultipleSpaces": true,
24 | "disallowNamedUnassignedFunctions": true,
25 | "disallowNewlineBeforeBlockStatements": true,
26 | "disallowOperatorBeforeLineBreak": ["."],
27 | "disallowQuotedKeysInObjects": "allButReserved",
28 | "disallowSpaceAfterKeywords": ["function"],
29 | "disallowSpaceAfterObjectKeys": true,
30 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
31 | "disallowSpacesInCallExpression": true,
32 | "disallowTrailingComma": true,
33 | "disallowTrailingWhitespace": true,
34 | "disallowYodaConditions": true,
35 |
36 | "requireAlignedObjectValues": false,
37 | "requireAnonymousFunctions": true,
38 | "requireBlocksOnNewline": 1,
39 | "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
40 | "requireCapitalizedConstructors": true,
41 | "requireCommaBeforeLineBreak": true,
42 | "requireCurlyBraces": true,
43 | "requireDollarBeforejQueryAssignment": true,
44 | "requireDotNotation": true,
45 | "requireLineBreakAfterVariableAssignment": true,
46 | "requireLineFeedAtFileEnd": true,
47 | "requireMultipleVarDecl": true,
48 | "requireOperatorBeforeLineBreak": true,
49 | "requirePaddingNewLinesAfterUseStrict": true,
50 | "requirePaddingNewLinesBeforeExport": true,
51 | "requirePaddingNewlinesBeforeKeywords": ["do", "for", "if", "switch", "try", "void", "while", "return"],
52 | "requirePaddingNewLinesBeforeLineComments": { "allExcept": "firstAfterCurly" },
53 | "requirePaddingNewlinesInBlocks": 1,
54 | "requireParenthesesAroundIIFE": true,
55 | "requireSpaceAfterBinaryOperators": true,
56 | "requireSpaceAfterKeywords": ["do", "for", "if", "else", "switch", "try", "catch", "void", "while", "return", "typeof"],
57 | "requireSpaceAfterLineComment": true,
58 | "requireSpaceBeforeBinaryOperators": true,
59 | "requireSpaceBeforeBlockStatements": true,
60 | "requireSpaceBetweenArguments": true,
61 | "requireSpacesInAnonymousFunctionExpression": {
62 | "beforeOpeningCurlyBrace": true
63 | },
64 | "requireSpacesInConditionalExpression": true,
65 | "requireSpacesInForStatement": true,
66 | "requireSpacesInFunction": {
67 | "beforeOpeningCurlyBrace": true
68 | },
69 | "requireSpacesInFunctionDeclaration": {
70 | "beforeOpeningCurlyBrace": true
71 | },
72 | "requireSpacesInFunctionExpression": {
73 | "beforeOpeningCurlyBrace": true
74 | },
75 | "requireSpacesInNamedFunctionExpression": {
76 | "beforeOpeningCurlyBrace": true
77 | },
78 | //"requireSpacesInsideArrayBrackets": "all",
79 | //"requireSpacesInsideObjectBrackets": "allButNested",
80 | //"requireSpacesInsideParentheses": "allButNested",
81 | "safeContextKeyword": ["_this", "$this", "slider"],
82 | "validateIndentation": 4,
83 | "validateParameterSeparator": ", ",
84 | "validateQuoteMarks": true
85 | }
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | // JSHint Default Configuration File (as on JSHint website)
3 | // See http://jshint.com/docs/ for more details
4 |
5 | "maxerr" : 50, // {int} Maximum error before stopping
6 |
7 | // Enforcing
8 | "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
9 | "camelcase" : true, // true: Identifiers must be in camelCase
10 | "curly" : true, // true: Require {} for every new block or scope
11 | "eqeqeq" : true, // true: Require triple equals (===) for comparison
12 | "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
13 | "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc.
14 | "immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
15 | "indent" : 4, // {int} Number of spaces to use for indentation
16 | "latedef" : true, // true: Require variables/functions to be defined before being used
17 | "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
18 | "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
19 | "noempty" : true, // true: Prohibit use of empty blocks
20 | "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters.
21 | "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
22 | "plusplus" : false, // true: Prohibit use of `++` & `--`
23 | "quotmark" : true, // Quotation mark consistency:
24 | // false : do nothing (default)
25 | // true : ensure whatever is used is consistent
26 | // "single" : require single quotes
27 | // "double" : require double quotes
28 | "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
29 | "unused" : true, // Unused variables:
30 | // true : all variables, last function parameter
31 | // "vars" : all variables only
32 | // "strict" : all variables, all function parameters
33 | "strict" : true, // true: Requires all functions run in ES5 Strict Mode
34 | "maxparams" : 3, // {int} Max number of formal params allowed per function
35 | "maxdepth" : false, // {int} Max depth of nested blocks (within functions)
36 | "maxstatements" : false, // {int} Max number statements per function
37 | "maxcomplexity" : false, // {int} Max cyclomatic complexity per function
38 | "maxlen" : 120, // {int} Max number of characters per line
39 | "varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed.
40 |
41 | // Relaxing
42 | "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
43 | "boss" : false, // true: Tolerate assignments where comparisons would be expected
44 | "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
45 | "eqnull" : false, // true: Tolerate use of `== null`
46 | "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
47 | "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
48 | "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
49 | // (ex: `for each`, multiple try/catch, function expression…)
50 | "evil" : false, // true: Tolerate use of `eval` and `new Function()`
51 | "expr" : false, // true: Tolerate `ExpressionStatement` as Programs
52 | "funcscope" : false, // true: Tolerate defining variables inside control statements
53 | "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
54 | "iterator" : false, // true: Tolerate using the `__iterator__` property
55 | "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
56 | "laxbreak" : false, // true: Tolerate possibly unsafe line breakings
57 | "laxcomma" : false, // true: Tolerate comma-first style coding
58 | "loopfunc" : false, // true: Tolerate functions being defined in loops
59 | "multistr" : false, // true: Tolerate multi-line strings
60 | "noyield" : false, // true: Tolerate generator functions with no yield statement in them.
61 | "notypeof" : false, // true: Tolerate invalid typeof operator values
62 | "proto" : false, // true: Tolerate using the `__proto__` property
63 | "scripturl" : false, // true: Tolerate script-targeted URLs
64 | "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
65 | "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
66 | "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
67 | "validthis" : false, // true: Tolerate using this in a non-constructor function
68 |
69 | // Environments
70 | "browser" : true, // Web Browser (window, document, etc)
71 | "browserify" : false, // Browserify (node.js code in the browser)
72 | "couch" : false, // CouchDB
73 | "devel" : true, // Development/debugging (alert, confirm, etc)
74 | "dojo" : false, // Dojo Toolkit
75 | "jasmine" : false, // Jasmine
76 | "jquery" : true, // jQuery
77 | "mocha" : false, // Mocha
78 | "mootools" : false, // MooTools
79 | "node" : true, // Node.js
80 | "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
81 | "phantom" : false, // PhantomJS
82 | "prototypejs" : false, // Prototype and Scriptaculous
83 | "qunit" : false, // QUnit
84 | "rhino" : false, // Rhino
85 | "shelljs" : false, // ShellJS
86 | "typed" : false, // Globals for typed array constructions
87 | "worker" : false, // Web Workers
88 | "wsh" : false, // Windows Scripting Host
89 | "yui" : false, // Yahoo User Interface
90 |
91 | // Custom Globals
92 | "globals" : {} // additional predefined global variables
93 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > ## ⚠ **Unmaintained / Deprecated**
2 | > [Use `svelte-range-slider-pips` instead! 🔗](https://github.com/simeydotme/svelte-range-slider-pips)
3 | >
4 | > _While this plugin should still function (if you're using an older version of jQueryUI) I don't think it's good enough for modern use and goes against some newer ideals (low dependency, low kb, less opinions on style) ... therefore I'd suggest moving away from this, and jQueryUI, and perhaps [look at using the newer **svelte-range-slider-pips**](https://github.com/simeydotme/svelte-range-slider-pips) module which should work in all environments!_
5 | >
6 |
7 | # jQuery UI Slider Pips
8 | #### Plugin to add "pips" or "floats" to a JQUI Slider.
9 |
10 | [](https://gitter.im/simeydotme/jQuery-ui-Slider-Pips?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
11 |
12 |
13 | This plugin **extends** the [jQuery UI Slider widget](http://jqueryui.com/slider/).
14 | Use it for creating a nicely-styled slider like shown below
15 | [Documentation, Demos and Examples here](http://simeydotme.github.io/jQuery-ui-Slider-Pips/)
16 |
17 | ---
18 |
19 | #### Want to contribute?:
20 | Please make sure to create a JSFiddle to demonstrate any problems, or pull requests, with this as a base: http://jsfiddle.net/simeydotme/Lh6pygef/ (press **fork** on the toolbar)
21 |
22 | ---
23 |
24 | 
25 | 
26 |
27 | ### Install
28 | If you're using [Bower](http://bower.io) you can install this plugin quickly from the command-line! :)
29 | ```bash
30 | bower install jquery-ui-slider-pips --save
31 | ```
32 |
33 | Otherwise, you may download the files in the `/dist/` folder.
34 |
35 | ------------------------------------
36 |
37 | ### Requirements:
38 | - jQuery (1.9+)
39 | - jQuery UI (1.10+)
40 |
41 | ------------------------------------
42 |
43 | ### Usage:
44 | Include the plugin javascript file __after__ jQuery & jQuery-ui.
45 | Include the CSS file; edit as you please.
46 | _Below methods are chainable, I've shown them separate for clarity_
47 |
48 | #### Default usage:
49 |
50 | ```html
51 |
54 |
55 | ```
56 |
57 | ```javascript
58 | // if you just want the defaults, copy & paste this code.
59 | $('.element').slider().slider('pips').slider('float');
60 | ```
61 |
62 | #### Advanced usage with options:
63 | ```javascript
64 |
65 | // First of all attach a slider to an element.
66 | // If you want to set values, you do it in the initialization.
67 | $('.element').slider({
68 | min: 20,
69 | max: 65,
70 | values: [30, 40, 50]
71 | });
72 |
73 | // Then you can give it pips and labels!
74 | $('.element').slider('pips', {
75 | first: 'label',
76 | last: 'label',
77 | rest: 'pip',
78 | labels: ['label1', 'label2', ...],
79 | prefix: "",
80 | suffix: ""
81 | });
82 |
83 | // And finally can add floaty numbers (if desired)
84 | $('.element').slider('float', {
85 | handle: true,
86 | pips: true,
87 | labels: ['label1', 'label2', ...],
88 | prefix: "",
89 | suffix: ""
90 | });
91 | ```
92 |
93 | #### Options for pips:
94 | **first:** `"pip"` or `"label"` or `false`
95 | **last:** `"pip"` or `"label"` or `false`
96 | **rest:** `"pip"` or `"label"` or `false`
97 | **labels:** `[]` or `{first: "", last: "", rest: [] }` or `false`
98 | **prefix:** `"string"`
99 | **suffix:** `"string"`
100 | **formatLabel:** `function(val){ return this.prefix + val + this.suffix }`
101 |
102 | ####Options for float:
103 | **handle:** `true` or `false`
104 | **pips:** `true` or `false`
105 | **labels:** `[]` or `{first: "", last: "", rest: [] }` or `false`
106 | **prefix:** `"string"`
107 | **suffix:** `"string"`
108 | **formatLabel:** `function(val){ return this.prefix + val + this.suffix }`
109 |
110 |
111 |
112 |
113 | ------------------------------------
114 |
115 | ### Style Customisation:
116 | All customisation should be done to the CSS file, or in your own CSS.
117 | The base styles I've provided do a decent job in the Demo,
118 | but they may need tweaking to suit your needs and UI theme.
119 | For some inspiration and help with styling, [go to the styling section of the documentation.](http://simeydotme.github.io/jQuery-ui-Slider-Pips/#styling)
120 |
121 | ------------------------------------
122 |
123 | ### Compatibility:
124 | Modern Browsers, IE7+
125 | _(To really support IE7 you will need to do some CSS changes.)_
126 |
127 | ------------------------------------
128 |
129 | ### License:
130 | Open Source MIT.
131 | http://opensource.org/licenses/MIT
132 |
133 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jQuery-ui-Slider-Pips",
3 | "version": "1.11.4",
4 | "description": "A plugin to add little \"pips\" to the jQuery UI Slider widget",
5 | "main": [
6 | "dist/jquery-ui-slider-pips.css",
7 | "dist/jquery-ui-slider-pips.js"
8 | ],
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/simeydotme/jQuery-ui-Slider-Pips.git"
12 | },
13 | "license": "MIT",
14 | "keywords": [
15 | "jquery",
16 | "ui",
17 | "slider",
18 | "widget",
19 | "pips",
20 | "points",
21 | "labels",
22 | "floats",
23 | "markers",
24 | "waypoints"
25 | ],
26 | "authors": [
27 | "Simon Goellner "
28 | ],
29 | "ignore": [
30 | ".gitattributes",
31 | ".gitignore",
32 | "gulpfile.js",
33 | "*.json",
34 | "*.md",
35 | "*.txt",
36 | "*.html",
37 | "src",
38 | "node_modules"
39 | ],
40 | "dependencies": {
41 | "jquery": ">=1.10.2",
42 | "jquery-ui": ">=1.9.2"
43 | },
44 | "devDependencies": {}
45 | }
46 |
--------------------------------------------------------------------------------
/dist/jquery-ui-slider-pips.css:
--------------------------------------------------------------------------------
1 | /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
2 | * Copyright (c) 2016 Simon Goellner ; Licensed MIT */
3 |
4 | /* HORIZONTAL */
5 | /* increase bottom margin to fit the pips */
6 | .ui-slider-horizontal.ui-slider-pips {
7 | margin-bottom: 1.4em;
8 | }
9 |
10 | /* default hide the labels and pips that arnt visible */
11 | /* we just use css to hide incase we want to show certain */
12 | /* labels/pips individually later */
13 | .ui-slider-pips .ui-slider-label,
14 | .ui-slider-pips .ui-slider-pip-hide {
15 | display: none;
16 | }
17 |
18 | /* now we show any labels that we've set to show in the options */
19 | .ui-slider-pips .ui-slider-pip-label .ui-slider-label {
20 | display: block;
21 | }
22 |
23 | /* PIP/LABEL WRAPPER */
24 | /* position each pip absolutely just below the default slider */
25 | /* and also prevent accidental selection */
26 | .ui-slider-pips .ui-slider-pip {
27 | width: 2em;
28 | height: 1em;
29 | line-height: 1em;
30 | position: absolute;
31 | font-size: 0.8em;
32 | color: #999;
33 | overflow: visible;
34 | text-align: center;
35 | top: 20px;
36 | left: 20px;
37 | margin-left: -1em;
38 | cursor: pointer;
39 | -webkit-touch-callout: none;
40 | -webkit-user-select: none;
41 | -moz-user-select: none;
42 | -ms-user-select: none;
43 | user-select: none;
44 | }
45 |
46 | .ui-state-disabled.ui-slider-pips .ui-slider-pip {
47 | cursor: default;
48 | }
49 |
50 | /* little pip/line position & size */
51 | .ui-slider-pips .ui-slider-line {
52 | background: #999;
53 | width: 1px;
54 | height: 3px;
55 | position: absolute;
56 | left: 50%;
57 | }
58 |
59 | /* the text label postion & size */
60 | /* it overflows so no need for width to be accurate */
61 | .ui-slider-pips .ui-slider-label {
62 | position: absolute;
63 | top: 5px;
64 | left: 50%;
65 | margin-left: -1em;
66 | width: 2em;
67 | }
68 |
69 | /* make it easy to see when we hover a label */
70 | .ui-slider-pips:not(.ui-slider-disabled) .ui-slider-pip:hover .ui-slider-label {
71 | color: black;
72 | font-weight: bold;
73 | }
74 |
75 | /* VERTICAL */
76 | /* vertical slider needs right-margin, not bottom */
77 | .ui-slider-vertical.ui-slider-pips {
78 | margin-bottom: 1em;
79 | margin-right: 2em;
80 | }
81 |
82 | /* align vertical pips left and to right of the slider */
83 | .ui-slider-vertical.ui-slider-pips .ui-slider-pip {
84 | text-align: left;
85 | top: auto;
86 | left: 20px;
87 | margin-left: 0;
88 | margin-bottom: -0.5em;
89 | }
90 |
91 | /* vertical line/pip should be horizontal instead */
92 | .ui-slider-vertical.ui-slider-pips .ui-slider-line {
93 | width: 3px;
94 | height: 1px;
95 | position: absolute;
96 | top: 50%;
97 | left: 0;
98 | }
99 |
100 | .ui-slider-vertical.ui-slider-pips .ui-slider-label {
101 | top: 50%;
102 | left: 0.5em;
103 | margin-left: 0;
104 | margin-top: -0.5em;
105 | width: 2em;
106 | }
107 |
108 | /* FLOATING HORIZTONAL TOOLTIPS */
109 | /* remove the godawful looking focus outline on handle and float */
110 | .ui-slider-float .ui-slider-handle:focus,
111 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,
112 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
113 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,
114 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip-label
115 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label {
116 | outline: none;
117 | }
118 |
119 | /* style tooltips on handles and on labels */
120 | /* also has a nice transition */
121 | .ui-slider-float .ui-slider-tip,
122 | .ui-slider-float .ui-slider-tip-label {
123 | position: absolute;
124 | visibility: hidden;
125 | top: -40px;
126 | display: block;
127 | width: 34px;
128 | margin-left: -18px;
129 | left: 50%;
130 | height: 20px;
131 | line-height: 20px;
132 | background: white;
133 | border-radius: 3px;
134 | border: 1px solid #888;
135 | text-align: center;
136 | font-size: 12px;
137 | opacity: 0;
138 | color: #333;
139 | -webkit-transition-property: opacity, top, visibility;
140 | transition-property: opacity, top, visibility;
141 | -webkit-transition-timing-function: ease-in;
142 | transition-timing-function: ease-in;
143 | -webkit-transition-duration: 200ms, 200ms, 0ms;
144 | transition-duration: 200ms, 200ms, 0ms;
145 | -webkit-transition-delay: 0ms, 0ms, 200ms;
146 | transition-delay: 0ms, 0ms, 200ms;
147 | }
148 |
149 | /* show the tooltip on hover or focus */
150 | /* also switch transition delay around */
151 | .ui-slider-float .ui-slider-handle:hover .ui-slider-tip,
152 | .ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,
153 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
154 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,
155 | .ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,
156 | .ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
157 | opacity: 1;
158 | top: -30px;
159 | visibility: visible;
160 | -webkit-transition-timing-function: ease-out;
161 | transition-timing-function: ease-out;
162 | -webkit-transition-delay: 200ms, 200ms, 0ms;
163 | transition-delay: 200ms, 200ms, 0ms;
164 | }
165 |
166 | /* put label tooltips below slider */
167 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label {
168 | top: 42px;
169 | }
170 |
171 | .ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
172 | top: 32px;
173 | font-weight: normal;
174 | }
175 |
176 | /* give the tooltip a css triangle arrow */
177 | .ui-slider-float .ui-slider-tip:after,
178 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
179 | content: " ";
180 | width: 0;
181 | height: 0;
182 | border: 5px solid rgba(255, 255, 255, 0);
183 | border-top-color: white;
184 | position: absolute;
185 | bottom: -10px;
186 | left: 50%;
187 | margin-left: -5px;
188 | }
189 |
190 | /* put a 1px border on the tooltip arrow to match tooltip border */
191 | .ui-slider-float .ui-slider-tip:before,
192 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
193 | content: " ";
194 | width: 0;
195 | height: 0;
196 | border: 5px solid rgba(255, 255, 255, 0);
197 | border-top-color: #888;
198 | position: absolute;
199 | bottom: -11px;
200 | left: 50%;
201 | margin-left: -5px;
202 | }
203 |
204 | /* switch the arrow to top on labels */
205 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
206 | border: 5px solid rgba(255, 255, 255, 0);
207 | border-bottom-color: white;
208 | top: -10px;
209 | }
210 |
211 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
212 | border: 5px solid rgba(255, 255, 255, 0);
213 | border-bottom-color: #888;
214 | top: -11px;
215 | }
216 |
217 | /* FLOATING VERTICAL TOOLTIPS */
218 | /* tooltip floats to left of handle */
219 | .ui-slider-vertical.ui-slider-float .ui-slider-tip,
220 | .ui-slider-vertical.ui-slider-float .ui-slider-tip-label {
221 | top: 50%;
222 | margin-top: -11px;
223 | width: 34px;
224 | margin-left: 0px;
225 | left: -60px;
226 | color: #333;
227 | -webkit-transition-duration: 200ms, 200ms, 0;
228 | transition-duration: 200ms, 200ms, 0;
229 | -webkit-transition-property: opacity, left, visibility;
230 | transition-property: opacity, left, visibility;
231 | -webkit-transition-delay: 0, 0, 200ms;
232 | transition-delay: 0, 0, 200ms;
233 | }
234 |
235 | .ui-slider-vertical.ui-slider-float .ui-slider-handle:hover .ui-slider-tip,
236 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,
237 | .ui-slider-vertical.ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
238 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,
239 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,
240 | .ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
241 | top: 50%;
242 | margin-top: -11px;
243 | left: -50px;
244 | }
245 |
246 | /* put label tooltips to right of slider */
247 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label {
248 | left: 47px;
249 | }
250 |
251 | .ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
252 | left: 37px;
253 | }
254 |
255 | /* give the tooltip a css triangle arrow */
256 | .ui-slider-vertical.ui-slider-float .ui-slider-tip:after,
257 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
258 | border: 5px solid rgba(255, 255, 255, 0);
259 | border-left-color: white;
260 | border-top-color: transparent;
261 | position: absolute;
262 | bottom: 50%;
263 | margin-bottom: -5px;
264 | right: -10px;
265 | margin-left: 0;
266 | top: auto;
267 | left: auto;
268 | }
269 |
270 | .ui-slider-vertical.ui-slider-float .ui-slider-tip:before,
271 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
272 | border: 5px solid rgba(255, 255, 255, 0);
273 | border-left-color: #888;
274 | border-top-color: transparent;
275 | position: absolute;
276 | bottom: 50%;
277 | margin-bottom: -5px;
278 | right: -11px;
279 | margin-left: 0;
280 | top: auto;
281 | left: auto;
282 | }
283 |
284 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
285 | border: 5px solid rgba(255, 255, 255, 0);
286 | border-right-color: white;
287 | right: auto;
288 | left: -10px;
289 | }
290 |
291 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
292 | border: 5px solid rgba(255, 255, 255, 0);
293 | border-right-color: #888;
294 | right: auto;
295 | left: -11px;
296 | }
297 |
298 | /* SELECTED STATES */
299 | /* Comment out this chuck of code if you don't want to have
300 | the new label colours shown */
301 | .ui-slider-pips [class*=ui-slider-pip-initial] {
302 | font-weight: bold;
303 | color: #14CA82;
304 | }
305 |
306 | .ui-slider-pips .ui-slider-pip-initial-2 {
307 | color: #1897C9;
308 | }
309 |
310 | .ui-slider-pips [class*=ui-slider-pip-selected] {
311 | font-weight: bold;
312 | color: #FF7A00;
313 | }
314 |
315 | .ui-slider-pips .ui-slider-pip-inrange {
316 | color: black;
317 | }
318 |
319 | .ui-slider-pips .ui-slider-pip-selected-2 {
320 | color: #E70081;
321 | }
322 |
323 | .ui-slider-pips [class*=ui-slider-pip-selected] .ui-slider-line,
324 | .ui-slider-pips .ui-slider-pip-inrange .ui-slider-line {
325 | background: black;
326 | }
327 |
--------------------------------------------------------------------------------
/dist/jquery-ui-slider-pips.js:
--------------------------------------------------------------------------------
1 | /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
2 | * Copyright (c) 2016 Simon Goellner ; Licensed MIT */
3 |
4 | (function($) {
5 |
6 | "use strict";
7 |
8 | var extensionMethods = {
9 |
10 |
11 |
12 |
13 |
14 | // pips
15 |
16 | pips: function( settings ) {
17 |
18 | var slider = this,
19 | i, j, p,
20 | collection = "",
21 | mousedownHandlers,
22 | min = slider._valueMin(),
23 | max = slider._valueMax(),
24 | pips = ( max - min ) / slider.options.step,
25 | $handles = slider.element.find(".ui-slider-handle"),
26 | $pips;
27 |
28 | var options = {
29 |
30 | first: "label",
31 | /* "label", "pip", false */
32 |
33 | last: "label",
34 | /* "label", "pip", false */
35 |
36 | rest: "pip",
37 | /* "label", "pip", false */
38 |
39 | labels: false,
40 | /* [array], { first: "string", rest: [array], last: "string" }, false */
41 |
42 | prefix: "",
43 | /* "", string */
44 |
45 | suffix: "",
46 | /* "", string */
47 |
48 | step: ( pips > 100 ) ? Math.floor( pips * 0.05 ) : 1,
49 | /* number */
50 |
51 | formatLabel: function(value) {
52 | return this.prefix + value + this.suffix;
53 | }
54 | /* function
55 | must return a value to display in the pip labels */
56 |
57 | };
58 |
59 | if ( $.type( settings ) === "object" || $.type( settings ) === "undefined" ) {
60 |
61 | $.extend( options, settings );
62 | slider.element.data("pips-options", options );
63 |
64 | } else {
65 |
66 | if ( settings === "destroy" ) {
67 |
68 | destroy();
69 |
70 | } else if ( settings === "refresh" ) {
71 |
72 | slider.element.slider( "pips", slider.element.data("pips-options") );
73 |
74 | }
75 |
76 | return;
77 |
78 | }
79 |
80 |
81 | // we don't want the step ever to be a floating point or negative
82 | // (or 0 actually, so we'll set it to 1 in that case).
83 | slider.options.pipStep = Math.abs( Math.round( options.step ) ) || 1;
84 |
85 | // get rid of all pips that might already exist.
86 | slider.element
87 | .off( ".selectPip" )
88 | .addClass("ui-slider-pips")
89 | .find(".ui-slider-pip")
90 | .remove();
91 |
92 | // small object with functions for marking pips as selected.
93 |
94 | var selectPip = {
95 |
96 | single: function(value) {
97 |
98 | this.resetClasses();
99 |
100 | $pips
101 | .filter(".ui-slider-pip-" + this.classLabel(value) )
102 | .addClass("ui-slider-pip-selected");
103 |
104 | if ( slider.options.range ) {
105 |
106 | $pips.each(function(k, v) {
107 |
108 | var pipVal = $(v).children(".ui-slider-label").data("value");
109 |
110 | if (( slider.options.range === "min" && pipVal < value ) ||
111 | ( slider.options.range === "max" && pipVal > value )) {
112 |
113 | $(v).addClass("ui-slider-pip-inrange");
114 |
115 | }
116 |
117 | });
118 |
119 | }
120 |
121 | },
122 |
123 | range: function(values) {
124 |
125 | this.resetClasses();
126 |
127 | for ( i = 0; i < values.length; i++ ) {
128 |
129 | $pips
130 | .filter(".ui-slider-pip-" + this.classLabel(values[i]) )
131 | .addClass("ui-slider-pip-selected-" + ( i + 1 ) );
132 |
133 | }
134 |
135 | if ( slider.options.range ) {
136 |
137 | $pips.each(function(k, v) {
138 |
139 | var pipVal = $(v).children(".ui-slider-label").data("value");
140 |
141 | if ( pipVal > values[0] && pipVal < values[1] ) {
142 |
143 | $(v).addClass("ui-slider-pip-inrange");
144 |
145 | }
146 |
147 | });
148 |
149 | }
150 |
151 | },
152 |
153 | classLabel: function(value) {
154 |
155 | return value.toString().replace(".", "-");
156 |
157 | },
158 |
159 | resetClasses: function() {
160 |
161 | var regex = /(^|\s*)(ui-slider-pip-selected|ui-slider-pip-inrange)(-{1,2}\d+|\s|$)/gi;
162 |
163 | $pips.removeClass( function(index, css) {
164 | return ( css.match(regex) || [] ).join(" ");
165 | });
166 |
167 | }
168 |
169 | };
170 |
171 | function getClosestHandle( val ) {
172 |
173 | var h, k,
174 | sliderVals,
175 | comparedVals,
176 | closestVal,
177 | tempHandles = [],
178 | closestHandle = 0;
179 |
180 | if ( slider.values() && slider.values().length ) {
181 |
182 | // get the current values of the slider handles
183 | sliderVals = slider.values();
184 |
185 | // find the offset value from the `val` for each
186 | // handle, and store it in a new array
187 | comparedVals = $.map( sliderVals, function(v) {
188 | return Math.abs( v - val );
189 | });
190 |
191 | // figure out the closest handles to the value
192 | closestVal = Math.min.apply( Math, comparedVals );
193 |
194 | // if a comparedVal is the closestVal, then
195 | // set the value accordingly, and set the closest handle.
196 | for ( h = 0; h < comparedVals.length; h++ ) {
197 | if ( comparedVals[h] === closestVal ) {
198 | tempHandles.push(h);
199 | }
200 | }
201 |
202 | // set the closest handle to the first handle in array,
203 | // just incase we have no _lastChangedValue to compare to.
204 | closestHandle = tempHandles[0];
205 |
206 | // now we want to find out if any of the closest handles were
207 | // the last changed handle, if so we specify that handle to change
208 | for ( k = 0; k < tempHandles.length; k++ ) {
209 | if ( slider._lastChangedValue === tempHandles[k] ) {
210 | closestHandle = tempHandles[k];
211 | }
212 | }
213 |
214 | if ( slider.options.range && tempHandles.length === 2 ) {
215 |
216 | if ( val > sliderVals[1] ) {
217 |
218 | closestHandle = tempHandles[1];
219 |
220 | } else if ( val < sliderVals[0] ) {
221 |
222 | closestHandle = tempHandles[0];
223 |
224 | }
225 |
226 | }
227 |
228 | }
229 |
230 | return closestHandle;
231 |
232 | }
233 |
234 | function destroy() {
235 |
236 | slider.element
237 | .off(".selectPip")
238 | .on("mousedown.slider", slider.element.data("mousedown-original") )
239 | .removeClass("ui-slider-pips")
240 | .find(".ui-slider-pip")
241 | .remove();
242 |
243 | }
244 |
245 | // when we click on a label, we want to make sure the
246 | // slider's handle actually goes to that label!
247 | // so we check all the handles and see which one is closest
248 | // to the label we clicked. If 2 handles are equidistant then
249 | // we move both of them. We also want to trigger focus on the
250 | // handle.
251 |
252 | // without this method the label is just treated like a part
253 | // of the slider and there's no accuracy in the selected value
254 |
255 | function labelClick( label, e ) {
256 |
257 | if (slider.option("disabled")) {
258 | return;
259 | }
260 |
261 | var val = $(label).data("value"),
262 | indexToChange = getClosestHandle( val );
263 |
264 | if ( slider.values() && slider.values().length ) {
265 |
266 | slider.options.values[ indexToChange ] = slider._trimAlignValue( val );
267 |
268 | } else {
269 |
270 | slider.options.value = slider._trimAlignValue( val );
271 |
272 | }
273 |
274 | slider._refreshValue();
275 | slider._change( e, indexToChange );
276 |
277 | }
278 |
279 | // method for creating a pip. We loop this for creating all
280 | // the pips.
281 |
282 | function createPip( which ) {
283 |
284 | var label,
285 | percent,
286 | number = which,
287 | classes = "ui-slider-pip",
288 | css = "",
289 | value = slider.value(),
290 | values = slider.values(),
291 | labelValue,
292 | classLabel,
293 | labelIndex;
294 |
295 | if ( which === "first" ) {
296 |
297 | number = 0;
298 |
299 | } else if ( which === "last" ) {
300 |
301 | number = pips;
302 |
303 | }
304 |
305 | // labelValue is the actual value of the pip based on the min/step
306 | labelValue = min + ( slider.options.step * number );
307 |
308 | // classLabel replaces any decimals with hyphens
309 | classLabel = labelValue.toString().replace(".", "-");
310 |
311 | // get the index needed for selecting labels out of the array
312 | labelIndex = ( number + min ) - min;
313 |
314 | // we need to set the human-readable label to either the
315 | // corresponding element in the array, or the appropriate
316 | // item in the object... or an empty string.
317 |
318 | if ( $.type(options.labels) === "array" ) {
319 |
320 | label = options.labels[ labelIndex ] || "";
321 |
322 | } else if ( $.type( options.labels ) === "object" ) {
323 |
324 | if ( which === "first" ) {
325 |
326 | // set first label
327 | label = options.labels.first || "";
328 |
329 | } else if ( which === "last" ) {
330 |
331 | // set last label
332 | label = options.labels.last || "";
333 |
334 | } else if ( $.type( options.labels.rest ) === "array" ) {
335 |
336 | // set other labels, but our index should start at -1
337 | // because of the first pip.
338 | label = options.labels.rest[ labelIndex - 1 ] || "";
339 |
340 | } else {
341 |
342 | // urrggh, the options must be f**ked, just show nothing.
343 | label = labelValue;
344 |
345 | }
346 |
347 | } else {
348 |
349 | label = labelValue;
350 |
351 | }
352 |
353 |
354 |
355 |
356 | if ( which === "first" ) {
357 |
358 | // first Pip on the Slider
359 | percent = "0%";
360 |
361 | classes += " ui-slider-pip-first";
362 | classes += ( options.first === "label" ) ? " ui-slider-pip-label" : "";
363 | classes += ( options.first === false ) ? " ui-slider-pip-hide" : "";
364 |
365 | } else if ( which === "last" ) {
366 |
367 | // last Pip on the Slider
368 | percent = "100%";
369 |
370 | classes += " ui-slider-pip-last";
371 | classes += ( options.last === "label" ) ? " ui-slider-pip-label" : "";
372 | classes += ( options.last === false ) ? " ui-slider-pip-hide" : "";
373 |
374 | } else {
375 |
376 | // all other Pips
377 | percent = (( 100 / pips ) * which ).toFixed(4) + "%";
378 |
379 | classes += ( options.rest === "label" ) ? " ui-slider-pip-label" : "";
380 | classes += ( options.rest === false ) ? " ui-slider-pip-hide" : "";
381 |
382 | }
383 |
384 | classes += " ui-slider-pip-" + classLabel;
385 |
386 |
387 | // add classes for the initial-selected values.
388 | if ( values && values.length ) {
389 |
390 | for ( i = 0; i < values.length; i++ ) {
391 |
392 | if ( labelValue === values[i] ) {
393 |
394 | classes += " ui-slider-pip-initial-" + ( i + 1 );
395 | classes += " ui-slider-pip-selected-" + ( i + 1 );
396 |
397 | }
398 |
399 | }
400 |
401 | if ( slider.options.range ) {
402 |
403 | if ( labelValue > values[0] &&
404 | labelValue < values[1] ) {
405 |
406 | classes += " ui-slider-pip-inrange";
407 |
408 | }
409 |
410 | }
411 |
412 | } else {
413 |
414 | if ( labelValue === value ) {
415 |
416 | classes += " ui-slider-pip-initial";
417 | classes += " ui-slider-pip-selected";
418 |
419 | }
420 |
421 | if ( slider.options.range ) {
422 |
423 | if (( slider.options.range === "min" && labelValue < value ) ||
424 | ( slider.options.range === "max" && labelValue > value )) {
425 |
426 | classes += " ui-slider-pip-inrange";
427 |
428 | }
429 |
430 | }
431 |
432 | }
433 |
434 |
435 |
436 | css = ( slider.options.orientation === "horizontal" ) ?
437 | "left: " + percent :
438 | "bottom: " + percent;
439 |
440 |
441 | // add this current pip to the collection
442 | return "" +
443 | "" +
444 | "" + options.formatLabel(label) + "" +
446 | "";
447 |
448 | }
449 |
450 | // create our first pip
451 | collection += createPip("first");
452 |
453 | // for every stop in the slider where we need a pip; create one.
454 | for ( p = slider.options.pipStep; p < pips; p += slider.options.pipStep ) {
455 | collection += createPip( p );
456 | }
457 |
458 | // create our last pip
459 | collection += createPip("last");
460 |
461 | // append the collection of pips.
462 | slider.element.append( collection );
463 |
464 | // store the pips for setting classes later.
465 | $pips = slider.element.find(".ui-slider-pip");
466 |
467 |
468 |
469 | // store the mousedown handlers for later, just in case we reset
470 | // the slider, the handler would be lost!
471 |
472 | if ( $._data( slider.element.get(0), "events").mousedown &&
473 | $._data( slider.element.get(0), "events").mousedown.length ) {
474 |
475 | mousedownHandlers = $._data( slider.element.get(0), "events").mousedown;
476 |
477 | } else {
478 |
479 | mousedownHandlers = slider.element.data("mousedown-handlers");
480 |
481 | }
482 |
483 | slider.element.data("mousedown-handlers", mousedownHandlers.slice() );
484 |
485 | // loop through all the mousedown handlers on the slider,
486 | // and store the original namespaced (.slider) event handler so
487 | // we can trigger it later.
488 | for ( j = 0; j < mousedownHandlers.length; j++ ) {
489 | if ( mousedownHandlers[j].namespace === "slider" ) {
490 | slider.element.data("mousedown-original", mousedownHandlers[j].handler );
491 | }
492 | }
493 |
494 | // unbind the mousedown.slider event, because it interferes with
495 | // the labelClick() method (stops smooth animation), and decide
496 | // if we want to trigger the original event based on which element
497 | // was clicked.
498 | slider.element
499 | .off("mousedown.slider")
500 | .on("mousedown.selectPip", function(e) {
501 |
502 | var $target = $(e.target),
503 | closest = getClosestHandle( $target.data("value") ),
504 | $handle = $handles.eq( closest );
505 |
506 | $handle.addClass("ui-state-active");
507 |
508 | if ( $target.is(".ui-slider-label") ) {
509 |
510 | labelClick( $target, e );
511 |
512 | slider.element
513 | .one("mouseup.selectPip", function() {
514 |
515 | $handle
516 | .removeClass("ui-state-active")
517 | .focus();
518 |
519 | });
520 |
521 | } else {
522 |
523 | var originalMousedown = slider.element.data("mousedown-original");
524 | originalMousedown(e);
525 |
526 | }
527 |
528 | });
529 |
530 |
531 |
532 |
533 | slider.element.on( "slide.selectPip slidechange.selectPip", function(e, ui) {
534 |
535 | var $slider = $(this),
536 | value = $slider.slider("value"),
537 | values = $slider.slider("values");
538 |
539 | if ( ui ) {
540 |
541 | value = ui.value;
542 | values = ui.values;
543 |
544 | }
545 |
546 | if ( slider.values() && slider.values().length ) {
547 |
548 | selectPip.range( values );
549 |
550 | } else {
551 |
552 | selectPip.single( value );
553 |
554 | }
555 |
556 | });
557 |
558 |
559 |
560 |
561 | },
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 | // floats
571 |
572 | float: function( settings ) {
573 |
574 | var i,
575 | slider = this,
576 | min = slider._valueMin(),
577 | max = slider._valueMax(),
578 | value = slider._value(),
579 | values = slider._values(),
580 | tipValues = [],
581 | $handles = slider.element.find(".ui-slider-handle");
582 |
583 | var options = {
584 |
585 | handle: true,
586 | /* false */
587 |
588 | pips: false,
589 | /* true */
590 |
591 | labels: false,
592 | /* [array], { first: "string", rest: [array], last: "string" }, false */
593 |
594 | prefix: "",
595 | /* "", string */
596 |
597 | suffix: "",
598 | /* "", string */
599 |
600 | event: "slidechange slide",
601 | /* "slidechange", "slide", "slidechange slide" */
602 |
603 | formatLabel: function(value) {
604 | return this.prefix + value + this.suffix;
605 | }
606 | /* function
607 | must return a value to display in the floats */
608 |
609 | };
610 |
611 | if ( $.type( settings ) === "object" || $.type( settings ) === "undefined" ) {
612 |
613 | $.extend( options, settings );
614 | slider.element.data("float-options", options );
615 |
616 | } else {
617 |
618 | if ( settings === "destroy" ) {
619 |
620 | destroy();
621 |
622 | } else if ( settings === "refresh" ) {
623 |
624 | slider.element.slider( "float", slider.element.data("float-options") );
625 |
626 | }
627 |
628 | return;
629 |
630 | }
631 |
632 |
633 |
634 |
635 | if ( value < min ) {
636 | value = min;
637 | }
638 |
639 | if ( value > max ) {
640 | value = max;
641 | }
642 |
643 | if ( values && values.length ) {
644 |
645 | for ( i = 0; i < values.length; i++ ) {
646 |
647 | if ( values[i] < min ) {
648 | values[i] = min;
649 | }
650 |
651 | if ( values[i] > max ) {
652 | values[i] = max;
653 | }
654 |
655 | }
656 |
657 | }
658 |
659 | // add a class for the CSS
660 | slider.element
661 | .addClass("ui-slider-float")
662 | .find(".ui-slider-tip, .ui-slider-tip-label")
663 | .remove();
664 |
665 |
666 |
667 | function destroy() {
668 |
669 | slider.element
670 | .off(".sliderFloat")
671 | .removeClass("ui-slider-float")
672 | .find(".ui-slider-tip, .ui-slider-tip-label")
673 | .remove();
674 |
675 | }
676 |
677 |
678 | function getPipLabels( values ) {
679 |
680 | // when checking the array we need to divide
681 | // by the step option, so we store those values here.
682 |
683 | var vals = [],
684 | steppedVals = $.map( values, function(v) {
685 | return Math.ceil(( v - min ) / slider.options.step);
686 | });
687 |
688 | // now we just get the values we need to return
689 | // by looping through the values array and assigning the
690 | // label if it exists.
691 |
692 | if ( $.type( options.labels ) === "array" ) {
693 |
694 | for ( i = 0; i < values.length; i++ ) {
695 |
696 | vals[i] = options.labels[ steppedVals[i] ] || values[i];
697 |
698 | }
699 |
700 | } else if ( $.type( options.labels ) === "object" ) {
701 |
702 | for ( i = 0; i < values.length; i++ ) {
703 |
704 | if ( values[i] === min ) {
705 |
706 | vals[i] = options.labels.first || min;
707 |
708 | } else if ( values[i] === max ) {
709 |
710 | vals[i] = options.labels.last || max;
711 |
712 | } else if ( $.type( options.labels.rest ) === "array" ) {
713 |
714 | vals[i] = options.labels.rest[ steppedVals[i] - 1 ] || values[i];
715 |
716 | } else {
717 |
718 | vals[i] = values[i];
719 |
720 | }
721 |
722 | }
723 |
724 | } else {
725 |
726 | for ( i = 0; i < values.length; i++ ) {
727 |
728 | vals[i] = values[i];
729 |
730 | }
731 |
732 | }
733 |
734 | return vals;
735 |
736 | }
737 |
738 | // apply handle tip if settings allows.
739 | if ( options.handle ) {
740 |
741 | // we need to set the human-readable label to either the
742 | // corresponding element in the array, or the appropriate
743 | // item in the object... or an empty string.
744 |
745 | tipValues = ( slider.values() && slider.values().length ) ?
746 | getPipLabels( values ) :
747 | getPipLabels( [ value ] );
748 |
749 | for ( i = 0; i < tipValues.length; i++ ) {
750 |
751 | $handles
752 | .eq( i )
753 | .append( $(""+ options.formatLabel(tipValues[i]) +"") );
754 |
755 | }
756 |
757 | }
758 |
759 | if ( options.pips ) {
760 |
761 | // if this slider also has pip-labels, we make those into tips, too.
762 | slider.element.find(".ui-slider-label").each(function(k, v) {
763 |
764 | var $this = $(v),
765 | val = [ $this.data("value") ],
766 | label,
767 | $tip;
768 |
769 |
770 | label = options.formatLabel( getPipLabels( val )[0] );
771 |
772 | // create a tip element
773 | $tip =
774 | $("" + label + "")
775 | .insertAfter( $this );
776 |
777 | });
778 |
779 | }
780 |
781 | // check that the event option is actually valid against our
782 | // own list of the slider's events.
783 | if ( options.event !== "slide" &&
784 | options.event !== "slidechange" &&
785 | options.event !== "slide slidechange" &&
786 | options.event !== "slidechange slide" ) {
787 |
788 | options.event = "slidechange slide";
789 |
790 | }
791 |
792 | // when slider changes, update handle tip label.
793 | slider.element
794 | .off(".sliderFloat")
795 | .on( options.event + ".sliderFloat", function( e, ui ) {
796 |
797 | var uiValue = ( $.type( ui.value ) === "array" ) ? ui.value : [ ui.value ],
798 | val = options.formatLabel( getPipLabels( uiValue )[0] );
799 |
800 | $(ui.handle)
801 | .find(".ui-slider-tip")
802 | .html( val );
803 |
804 | });
805 |
806 | }
807 |
808 | };
809 |
810 | $.extend(true, $.ui.slider.prototype, extensionMethods);
811 |
812 | })(jQuery);
813 |
--------------------------------------------------------------------------------
/dist/jquery-ui-slider-pips.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
2 | * Copyright (c) 2016 Simon Goellner ; Licensed MIT */
3 |
4 | .ui-slider-horizontal.ui-slider-pips{margin-bottom:1.4em}.ui-slider-pips .ui-slider-label,.ui-slider-pips .ui-slider-pip-hide{display:none}.ui-slider-pips .ui-slider-pip-label .ui-slider-label{display:block}.ui-slider-pips .ui-slider-pip{width:2em;height:1em;line-height:1em;position:absolute;font-size:0.8em;color:#999;overflow:visible;text-align:center;top:20px;left:20px;margin-left:-1em;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ui-state-disabled.ui-slider-pips .ui-slider-pip{cursor:default}.ui-slider-pips .ui-slider-line{background:#999;width:1px;height:3px;position:absolute;left:50%}.ui-slider-pips .ui-slider-label{position:absolute;top:5px;left:50%;margin-left:-1em;width:2em}.ui-slider-pips:not(.ui-slider-disabled) .ui-slider-pip:hover .ui-slider-label{color:black;font-weight:bold}.ui-slider-vertical.ui-slider-pips{margin-bottom:1em;margin-right:2em}.ui-slider-vertical.ui-slider-pips .ui-slider-pip{text-align:left;top:auto;left:20px;margin-left:0;margin-bottom:-0.5em}.ui-slider-vertical.ui-slider-pips .ui-slider-line{width:3px;height:1px;position:absolute;top:50%;left:0}.ui-slider-vertical.ui-slider-pips .ui-slider-label{top:50%;left:0.5em;margin-left:0;margin-top:-0.5em;width:2em}.ui-slider-float .ui-slider-handle:focus,.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,.ui-slider-float .ui-slider-handle:focus .ui-slider-tip,.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,.ui-slider-float .ui-slider-handle:focus .ui-slider-tip-label .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label{outline:none}.ui-slider-float .ui-slider-tip,.ui-slider-float .ui-slider-tip-label{position:absolute;visibility:hidden;top:-40px;display:block;width:34px;margin-left:-18px;left:50%;height:20px;line-height:20px;background:white;border-radius:3px;border:1px solid #888;text-align:center;font-size:12px;opacity:0;color:#333;-webkit-transition-property:opacity, top, visibility;transition-property:opacity, top, visibility;-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-duration:200ms, 200ms, 0ms;transition-duration:200ms, 200ms, 0ms;-webkit-transition-delay:0ms, 0ms, 200ms;transition-delay:0ms, 0ms, 200ms}.ui-slider-float .ui-slider-handle:hover .ui-slider-tip,.ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,.ui-slider-float .ui-slider-handle:focus .ui-slider-tip,.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,.ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label{opacity:1;top:-30px;visibility:visible;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;-webkit-transition-delay:200ms, 200ms, 0ms;transition-delay:200ms, 200ms, 0ms}.ui-slider-float .ui-slider-pip .ui-slider-tip-label{top:42px}.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label{top:32px;font-weight:normal}.ui-slider-float .ui-slider-tip:after,.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after{content:" ";width:0;height:0;border:5px solid rgba(255,255,255,0);border-top-color:#fff;position:absolute;bottom:-10px;left:50%;margin-left:-5px}.ui-slider-float .ui-slider-tip:before,.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before{content:" ";width:0;height:0;border:5px solid rgba(255,255,255,0);border-top-color:#888;position:absolute;bottom:-11px;left:50%;margin-left:-5px}.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after{border:5px solid rgba(255,255,255,0);border-bottom-color:#fff;top:-10px}.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before{border:5px solid rgba(255,255,255,0);border-bottom-color:#888;top:-11px}.ui-slider-vertical.ui-slider-float .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-tip-label{top:50%;margin-top:-11px;width:34px;margin-left:0px;left:-60px;color:#333;-webkit-transition-duration:200ms, 200ms, 0;transition-duration:200ms, 200ms, 0;-webkit-transition-property:opacity, left, visibility;transition-property:opacity, left, visibility;-webkit-transition-delay:0, 0, 200ms;transition-delay:0, 0, 200ms}.ui-slider-vertical.ui-slider-float .ui-slider-handle:hover .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-handle:focus .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,.ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label{top:50%;margin-top:-11px;left:-50px}.ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label{left:47px}.ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label{left:37px}.ui-slider-vertical.ui-slider-float .ui-slider-tip:after,.ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after{border:5px solid rgba(255,255,255,0);border-left-color:#fff;border-top-color:transparent;position:absolute;bottom:50%;margin-bottom:-5px;right:-10px;margin-left:0;top:auto;left:auto}.ui-slider-vertical.ui-slider-float .ui-slider-tip:before,.ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before{border:5px solid rgba(255,255,255,0);border-left-color:#888;border-top-color:transparent;position:absolute;bottom:50%;margin-bottom:-5px;right:-11px;margin-left:0;top:auto;left:auto}.ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after{border:5px solid rgba(255,255,255,0);border-right-color:#fff;right:auto;left:-10px}.ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before{border:5px solid rgba(255,255,255,0);border-right-color:#888;right:auto;left:-11px}.ui-slider-pips [class*=ui-slider-pip-initial]{font-weight:bold;color:#14CA82}.ui-slider-pips .ui-slider-pip-initial-2{color:#1897C9}.ui-slider-pips [class*=ui-slider-pip-selected]{font-weight:bold;color:#FF7A00}.ui-slider-pips .ui-slider-pip-inrange{color:black}.ui-slider-pips .ui-slider-pip-selected-2{color:#E70081}.ui-slider-pips [class*=ui-slider-pip-selected] .ui-slider-line,.ui-slider-pips .ui-slider-pip-inrange .ui-slider-line{background:black}
5 |
--------------------------------------------------------------------------------
/dist/jquery-ui-slider-pips.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
2 | * Copyright (c) 2016 Simon Goellner ; Licensed MIT */
3 |
4 | !function(e){"use strict";var i={pips:function(i){function l(i){var l,s,t,a,n,r=[],o=0;if(u.values()&&u.values().length){for(t=u.values(),a=e.map(t,function(e){return Math.abs(e-i)}),n=Math.min.apply(Math,a),l=0;lt[1]?o=r[1]:iv[0]&&tt||"max"===u.options.range&&t>f)&&(p+=" ui-slider-pip-inrange");return d="horizontal"===u.options.orientation?"left: "+s:"bottom: "+s,''+g.formatLabel(l)+""}var n,r,o,p,d,u=this,f="",c=u._valueMin(),v=u._valueMax(),h=(v-c)/u.options.step,m=u.element.find(".ui-slider-handle"),g={first:"label",last:"label",rest:"pip",labels:!1,prefix:"",suffix:"",step:h>100?Math.floor(.05*h):1,formatLabel:function(e){return this.prefix+e+this.suffix}};if("object"!==e.type(i)&&"undefined"!==e.type(i))return void("destroy"===i?s():"refresh"===i&&u.element.slider("pips",u.element.data("pips-options")));e.extend(g,i),u.element.data("pips-options",g),u.options.pipStep=Math.abs(Math.round(g.step))||1,u.element.off(".selectPip").addClass("ui-slider-pips").find(".ui-slider-pip").remove();var b={single:function(i){this.resetClasses(),d.filter(".ui-slider-pip-"+this.classLabel(i)).addClass("ui-slider-pip-selected"),u.options.range&&d.each(function(l,s){var t=e(s).children(".ui-slider-label").data("value");("min"===u.options.range&&i>t||"max"===u.options.range&&t>i)&&e(s).addClass("ui-slider-pip-inrange")})},range:function(i){for(this.resetClasses(),n=0;ni[0]&&to;o+=u.options.pipStep)f+=a(o);for(f+=a("last"),u.element.append(f),d=u.element.find(".ui-slider-pip"),p=e._data(u.element.get(0),"events").mousedown&&e._data(u.element.get(0),"events").mousedown.length?e._data(u.element.get(0),"events").mousedown:u.element.data("mousedown-handlers"),u.element.data("mousedown-handlers",p.slice()),r=0;ro&&(o=n),o>r&&(o=r),p&&p.length)for(t=0;tr&&(p[t]=r);if(a.element.addClass("ui-slider-float").find(".ui-slider-tip, .ui-slider-tip-label").remove(),f.handle)for(d=s(a.values()&&a.values().length?p:[o]),t=0;t'+f.formatLabel(d[t])+""));f.pips&&a.element.find(".ui-slider-label").each(function(i,l){var t,a,n=e(l),r=[n.data("value")];t=f.formatLabel(s(r)[0]),a=e(''+t+"").insertAfter(n)}),"slide"!==f.event&&"slidechange"!==f.event&&"slide slidechange"!==f.event&&"slidechange slide"!==f.event&&(f.event="slidechange slide"),a.element.off(".sliderFloat").on(f.event+".sliderFloat",function(i,l){var t="array"===e.type(l.value)?l.value:[l.value],a=f.formatLabel(s(t)[0]);e(l.handle).find(".ui-slider-tip").html(a)})}};e.extend(!0,e.ui.slider.prototype,i)}(jQuery);
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 |
2 | "use strict";
3 |
4 | var gulp = require("gulp-param")( require("gulp"), process.argv ),
5 |
6 | fs = require("fs"),
7 | semver = require("semver"),
8 | dateformat = require("dateformat"),
9 |
10 | git = require("gulp-git"),
11 | sass = require("gulp-sass"),
12 | bump = require("gulp-bump"),
13 | clean = require("gulp-clean"),
14 | uglify = require("gulp-uglify"),
15 | rename = require("gulp-rename"),
16 | header = require("gulp-header"),
17 | autoprefixer = require("gulp-autoprefixer"),
18 |
19 | pack = function() {
20 |
21 | return JSON.parse(fs.readFileSync("./package.json", "utf8"));
22 |
23 | },
24 |
25 | pkg = pack(),
26 |
27 | dates = {
28 |
29 | today: dateformat( new Date() , "yyyy-mm-dd" ),
30 | year: dateformat( new Date() , "yyyy" )
31 |
32 | },
33 |
34 | banner = "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= dates.today %>\n" +
35 | "<%= pkg.homepage ? \"* \" + pkg.homepage + \"\\n\" : \"\" %>" +
36 | "* Copyright (c) <%= dates.year %> <%= pkg.author %>;" +
37 | " Licensed <%= pkg.license %> */\n\n",
38 |
39 | out = {
40 |
41 | js: "jquery-ui-slider-pips",
42 | css: "jquery-ui-slider-pips"
43 |
44 | };
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | /**
56 | * tasks
57 | *
58 | * to release; tasks should be run in the order:
59 | * "gulp bump" -> "gulp assets" -> "gulp release"
60 | *
61 | * for dev; just run
62 | * "gulp"
63 | */
64 |
65 | gulp.task("default", ["assets"], function() {
66 |
67 | return gulp;
68 |
69 | });
70 |
71 | gulp.task("assets", ["clean", "js", "sass"], function() {
72 |
73 | console.log("⭐ >> Finished putting assets to /dist/" );
74 |
75 | return gulp;
76 |
77 | });
78 |
79 | /**
80 | * clean the dist folder (empty it)
81 | */
82 |
83 | gulp.task("clean", function() {
84 |
85 | console.log("⭐ >> All clean and shiny! ");
86 |
87 | return gulp
88 | .src("./dist", { read: false })
89 | .pipe( clean() );
90 |
91 | });
92 |
93 |
94 | /**
95 | * js task is used to clean the dist folder and output
96 | * the minified and non-minified files.
97 | */
98 |
99 | gulp.task("js", ["clean"], function() {
100 |
101 | var pkg = pack();
102 |
103 | return gulp
104 | .src( "./src/js/**/*.js" )
105 |
106 | .pipe( header( banner, { pkg: pkg, dates: dates } ))
107 | .pipe( rename( out.js + ".js" ) )
108 | .pipe( gulp.dest( "./dist" ) )
109 |
110 | .pipe( uglify("combined.js") )
111 | .pipe( header( banner, { pkg: pkg, dates: dates } ))
112 | .pipe( rename( out.js + ".min.js" ) )
113 | .pipe( gulp.dest( "./dist" ) );
114 |
115 | });
116 |
117 |
118 | /**
119 | * sass task is used to clean the dist folder and output
120 | * the minified and non-minified files.
121 | */
122 |
123 | gulp.task("sass", ["clean"], function() {
124 |
125 | var pkg = pack();
126 |
127 | gulp
128 | .src("./src/**/*.scss")
129 | .pipe( sass({ outputStyle: "expanded" }).on("error", sass.logError ) )
130 | .pipe( autoprefixer("last 5 versions") )
131 | .pipe( header( banner, { pkg: pkg, dates: dates } ))
132 | .pipe( rename( out.css + ".css" ))
133 | .pipe( gulp.dest("./dist") );
134 |
135 | return gulp
136 | .src("./src/**/*.scss")
137 | .pipe( sass({ outputStyle: "compressed" }).on("error", sass.logError ) )
138 | .pipe( autoprefixer("last 5 versions") )
139 | .pipe( header( banner, { pkg: pkg, dates: dates } ))
140 | .pipe( rename( out.css + ".min.css" ))
141 | .pipe( gulp.dest("./dist") );
142 |
143 | });
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | /**
152 | * bump task can be used like:
153 | *
154 | * gulp bump --patch
155 | * gulp bump --minor
156 | * gulp bump --major
157 | *
158 | * this task will ONLY bump the version, it will not
159 | * release a tag, commit the code or update the assets.
160 | */
161 |
162 | gulp.task("bump", function( patch, minor, major ) {
163 |
164 | var b =
165 | (patch) ? "patch" :
166 | (minor) ? "minor" :
167 | (major) ? "major" :
168 | null;
169 |
170 | if( b ) {
171 |
172 | var pkg = pack(),
173 | oldv = pkg.version,
174 | newv = semver.inc( oldv , b );
175 |
176 | console.log("⭐ >> Bumping Version to v" + newv );
177 |
178 | return gulp
179 | .src("./*.json")
180 | .pipe( bump({ version: newv }) )
181 | .pipe( gulp.dest("./") );
182 |
183 | } else {
184 |
185 | throw new Error("\n⚠ >> Not Bumping; didn't supply bump type\n\n");
186 |
187 | return false;
188 |
189 | }
190 |
191 | });
192 |
193 |
194 |
195 |
196 | /**
197 | * release task should be used after "bump" and "assets" was run.
198 | * this task will create a commit, and tag it with the version in package.json
199 | */
200 |
201 | gulp.task("release", ["commit", "tag"], function() {
202 | return gulp;
203 | });
204 |
205 |
206 | /**
207 | * commit task is used for creating a cute release icon, and committing dist files
208 | * to the GIT repository; all src files should already be committed.
209 | */
210 |
211 | gulp.task("commit", function() {
212 |
213 | var pkg = pack(),
214 | newv = pkg.version,
215 |
216 | fun = "🐒 🐔 🐧 🐤 🐗 🐝 🐌 🐞 🐜 🕷 🦂 🦀 🐍 🐢 🐟 🐡 🐬 🐋 🐊 🐆 🐅 🐃 🐂 🐄 🐪 🐘 🐐 🐏 🐑 🐎 🐖 🐀 🐁 🐓 🦃 🕊 🐕 🐈 🐇 🐿 🐉 🐲".split(" ");
217 | fun = fun[ Math.floor(Math.random() * fun.length ) ];
218 |
219 | console.log("⭐ >> Committing release v" + newv );
220 |
221 | return gulp
222 | .src([
223 | "./*.json",
224 | "./dist/**/*"
225 | ])
226 | .pipe( git.add() )
227 | .pipe( git.commit("Release v" + newv + " ⚡" + fun + "⚡") );
228 |
229 | });
230 |
231 | /**
232 | * tag task should just tag the last commit in repository
233 | * with the latest version information from package.json.
234 | */
235 |
236 | gulp.task("tag", ["commit"], function() {
237 |
238 | var pkg = pack(),
239 | newv = pkg.version;
240 |
241 | console.log("⭐ >> Creating new tag for v" + newv );
242 |
243 | git.tag("v" + newv, "Version " + newv, function(err) {
244 | if ( err ) { throw err; }
245 | });
246 |
247 | return gulp;
248 |
249 | });
250 |
251 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jQuery-ui-Slider-Pips",
3 | "version": "1.11.4",
4 | "description": "A plugin to add little \"pips\" to the jQuery UI Slider widget",
5 | "main": "dist/jquery-ui-slider-pips.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/simeydotme/jQuery-ui-Slider-Pips.git"
9 | },
10 | "license": "MIT",
11 | "keywords": [
12 | "jquery",
13 | "ui",
14 | "slider",
15 | "widget",
16 | "pips",
17 | "points",
18 | "labels",
19 | "floats",
20 | "markers",
21 | "waypoints"
22 | ],
23 | "author": "Simon Goellner ",
24 | "bugs": {
25 | "url": "https://github.com/simeydotme/jQuery-ui-Slider-Pips/issues"
26 | },
27 | "scripts": {
28 | "test": "echo \"Error: no test specified\" && exit 1"
29 | },
30 | "devDependencies": {
31 | "dateformat": "^1.0.12",
32 | "semver": "^5.1.0",
33 | "fs": "0.0.2",
34 | "gulp": "^3.9.0",
35 | "gulp-autoprefixer": "^3.1.0",
36 | "gulp-clean": "^0.3.1",
37 | "gulp-header": "^1.7.1",
38 | "gulp-rename": "^1.2.2",
39 | "gulp-sass": "^2.1.0",
40 | "gulp-uglify": "^1.5.1",
41 | "gulp-bump": "^1.0.0",
42 | "gulp-git": "^1.6.0",
43 | "gulp-param": "^0.6.4"
44 | },
45 | "dependencies": {
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/css/jquery-ui-slider-pips.scss:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /* HORIZONTAL */
5 |
6 | /* increase bottom margin to fit the pips */
7 | .ui-slider-horizontal.ui-slider-pips {
8 | margin-bottom: 1.4em;
9 | }
10 |
11 | /* default hide the labels and pips that arnt visible */
12 | /* we just use css to hide incase we want to show certain */
13 | /* labels/pips individually later */
14 | .ui-slider-pips .ui-slider-label,
15 | .ui-slider-pips .ui-slider-pip-hide {
16 | display: none;
17 | }
18 |
19 | /* now we show any labels that we've set to show in the options */
20 | .ui-slider-pips .ui-slider-pip-label .ui-slider-label {
21 | display: block;
22 | }
23 |
24 | /* PIP/LABEL WRAPPER */
25 | /* position each pip absolutely just below the default slider */
26 | /* and also prevent accidental selection */
27 | .ui-slider-pips .ui-slider-pip {
28 | width: 2em;
29 | height: 1em;
30 | line-height: 1em;
31 | position: absolute;
32 | font-size: 0.8em;
33 | color: #999;
34 | overflow: visible;
35 | text-align: center;
36 | top: 20px;
37 | left: 20px;
38 | margin-left: -1em;
39 | cursor: pointer;
40 |
41 | -webkit-touch-callout: none;
42 | -webkit-user-select: none;
43 | -khtml-user-select: none;
44 | -moz-user-select: none;
45 | -ms-user-select: none;
46 | user-select: none;
47 | }
48 | .ui-state-disabled.ui-slider-pips .ui-slider-pip {
49 | cursor: default;
50 | }
51 |
52 | /* little pip/line position & size */
53 | .ui-slider-pips .ui-slider-line {
54 | background: #999;
55 | width: 1px;
56 | height: 3px;
57 | position: absolute;
58 | left: 50%;
59 | }
60 |
61 | /* the text label postion & size */
62 | /* it overflows so no need for width to be accurate */
63 | .ui-slider-pips .ui-slider-label {
64 | position: absolute;
65 | top: 5px;
66 | left: 50%;
67 | margin-left: -1em;
68 | width: 2em;
69 | }
70 |
71 | /* make it easy to see when we hover a label */
72 | .ui-slider-pips:not(.ui-slider-disabled) .ui-slider-pip:hover .ui-slider-label {
73 | color: black;
74 | font-weight: bold;
75 | }
76 |
77 |
78 |
79 |
80 | /* VERTICAL */
81 |
82 | /* vertical slider needs right-margin, not bottom */
83 | .ui-slider-vertical.ui-slider-pips {
84 | margin-bottom: 1em;
85 | margin-right: 2em;
86 | }
87 |
88 | /* align vertical pips left and to right of the slider */
89 | .ui-slider-vertical.ui-slider-pips .ui-slider-pip {
90 | text-align: left;
91 | top: auto;
92 | left: 20px;
93 | margin-left: 0;
94 | margin-bottom: -0.5em;
95 | }
96 |
97 | /* vertical line/pip should be horizontal instead */
98 | .ui-slider-vertical.ui-slider-pips .ui-slider-line {
99 | width: 3px;
100 | height: 1px;
101 | position: absolute;
102 | top: 50%;
103 | left: 0;
104 | }
105 |
106 | .ui-slider-vertical.ui-slider-pips .ui-slider-label {
107 | top: 50%;
108 | left: 0.5em;
109 | margin-left: 0;
110 | margin-top: -0.5em;
111 | width: 2em;
112 | }
113 |
114 |
115 |
116 |
117 | /* FLOATING HORIZTONAL TOOLTIPS */
118 |
119 | /* remove the godawful looking focus outline on handle and float */
120 | .ui-slider-float .ui-slider-handle:focus,
121 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,
122 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
123 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label,
124 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip-label
125 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip-label {
126 | outline: none;
127 | }
128 |
129 | /* style tooltips on handles and on labels */
130 | /* also has a nice transition */
131 | .ui-slider-float .ui-slider-tip,
132 | .ui-slider-float .ui-slider-tip-label {
133 |
134 | position: absolute;
135 | visibility: hidden;
136 | top: -40px;
137 | display: block;
138 | width: 34px;
139 | margin-left: -18px;
140 | left: 50%;
141 | height: 20px;
142 | line-height: 20px;
143 | background: white;
144 | border-radius: 3px;
145 | border: 1px solid #888;
146 | text-align: center;
147 | font-size: 12px;
148 | opacity: 0;
149 | color: #333;
150 |
151 | -webkit-transition-property: opacity, top, visibility;
152 | -moz-transition-property: opacity, top, visibility;
153 | -ms-transition-property: opacity, top, visibility;
154 | transition-property: opacity, top, visibility;
155 |
156 | -webkit-transition-timing-function: ease-in;
157 | -moz-transition-timing-function: ease-in;
158 | -ms-transition-timing-function: ease-in;
159 | transition-timing-function: ease-in;
160 |
161 | -webkit-transition-duration: 200ms, 200ms, 0ms;
162 | -moz-transition-duration: 200ms, 200ms, 0ms;
163 | -ms-transition-duration: 200ms, 200ms, 0ms;
164 | transition-duration: 200ms, 200ms, 0ms;
165 |
166 | -webkit-transition-delay: 0ms, 0ms, 200ms;
167 | -moz-transition-delay: 0ms, 0ms, 200ms;
168 | -ms-transition-delay: 0ms, 0ms, 200ms;
169 | transition-delay: 0ms, 0ms, 200ms;
170 | }
171 |
172 | /* show the tooltip on hover or focus */
173 | /* also switch transition delay around */
174 | .ui-slider-float .ui-slider-handle:hover .ui-slider-tip,
175 | .ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,
176 | .ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
177 | .ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,
178 | .ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,
179 | .ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
180 |
181 | opacity: 1;
182 | top: -30px;
183 | visibility: visible;
184 |
185 | -webkit-transition-timing-function: ease-out;
186 | -moz-transition-timing-function: ease-out;
187 | -ms-transition-timing-function: ease-out;
188 | transition-timing-function: ease-out;
189 |
190 | -webkit-transition-delay:200ms, 200ms, 0ms;
191 | -moz-transition-delay:200ms, 200ms, 0ms;
192 | -ms-transition-delay:200ms, 200ms, 0ms;
193 | transition-delay:200ms, 200ms, 0ms;
194 |
195 | }
196 |
197 | /* put label tooltips below slider */
198 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label {
199 | top: 42px;
200 | }
201 |
202 | .ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
203 | top: 32px;
204 | font-weight: normal;
205 | }
206 |
207 | /* give the tooltip a css triangle arrow */
208 | .ui-slider-float .ui-slider-tip:after,
209 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
210 | content: " ";
211 | width: 0;
212 | height: 0;
213 | border: 5px solid rgba(255,255,255,0);
214 | border-top-color: rgba(255,255,255,1);
215 | position: absolute;
216 | bottom: -10px;
217 | left: 50%;
218 | margin-left: -5px;
219 | }
220 |
221 | /* put a 1px border on the tooltip arrow to match tooltip border */
222 | .ui-slider-float .ui-slider-tip:before,
223 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
224 | content: " ";
225 | width: 0;
226 | height: 0;
227 | border: 5px solid rgba(255,255,255,0);
228 | border-top-color: #888;
229 | position: absolute;
230 | bottom: -11px;
231 | left: 50%;
232 | margin-left: -5px;
233 | }
234 |
235 | /* switch the arrow to top on labels */
236 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
237 | border: 5px solid rgba(255,255,255,0);
238 | border-bottom-color: rgba(255,255,255,1);
239 | top: -10px;
240 | }
241 |
242 | .ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
243 | border: 5px solid rgba(255,255,255,0);
244 | border-bottom-color: #888;
245 | top: -11px;
246 | }
247 |
248 |
249 |
250 |
251 | /* FLOATING VERTICAL TOOLTIPS */
252 |
253 | /* tooltip floats to left of handle */
254 | .ui-slider-vertical.ui-slider-float .ui-slider-tip,
255 | .ui-slider-vertical.ui-slider-float .ui-slider-tip-label {
256 |
257 | top: 50%;
258 | margin-top: -11px;
259 | width: 34px;
260 | margin-left: 0px;
261 | left: -60px;
262 | color: #333;
263 |
264 | -webkit-transition-duration: 200ms, 200ms, 0;
265 | -moz-transition-duration: 200ms, 200ms, 0;
266 | -ms-transition-duration: 200ms, 200ms, 0;
267 | transition-duration: 200ms, 200ms, 0;
268 |
269 | -webkit-transition-property: opacity, left, visibility;
270 | -moz-transition-property: opacity, left, visibility;
271 | -ms-transition-property: opacity, left, visibility;
272 | transition-property: opacity, left, visibility;
273 |
274 | -webkit-transition-delay: 0, 0, 200ms;
275 | -moz-transition-delay: 0, 0, 200ms;
276 | -ms-transition-delay: 0, 0, 200ms;
277 | transition-delay: 0, 0, 200ms;
278 |
279 | }
280 |
281 |
282 |
283 | .ui-slider-vertical.ui-slider-float .ui-slider-handle:hover .ui-slider-tip,
284 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-hover .ui-slider-tip,
285 | .ui-slider-vertical.ui-slider-float .ui-slider-handle:focus .ui-slider-tip,
286 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-focus .ui-slider-tip,
287 | .ui-slider-vertical.ui-slider-float .ui-slider-handle.ui-state-active .ui-slider-tip,
288 | .ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
289 | top: 50%;
290 | margin-top: -11px;
291 | left: -50px;
292 | }
293 |
294 | /* put label tooltips to right of slider */
295 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label {
296 | left: 47px;
297 | }
298 |
299 | .ui-slider-vertical.ui-slider-float .ui-slider-pip:hover .ui-slider-tip-label {
300 | left: 37px;
301 | }
302 |
303 | /* give the tooltip a css triangle arrow */
304 | .ui-slider-vertical.ui-slider-float .ui-slider-tip:after,
305 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
306 | border: 5px solid rgba(255,255,255,0);
307 | border-left-color: rgba(255,255,255,1);
308 | border-top-color: transparent;
309 | position: absolute;
310 | bottom: 50%;
311 | margin-bottom: -5px;
312 | right: -10px;
313 | margin-left: 0;
314 | top: auto;
315 | left: auto;
316 | }
317 |
318 | .ui-slider-vertical.ui-slider-float .ui-slider-tip:before,
319 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
320 | border: 5px solid rgba(255,255,255,0);
321 | border-left-color: #888;
322 | border-top-color: transparent;
323 | position: absolute;
324 | bottom: 50%;
325 | margin-bottom: -5px;
326 | right: -11px;
327 | margin-left: 0;
328 | top: auto;
329 | left: auto;
330 | }
331 |
332 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:after {
333 | border: 5px solid rgba(255,255,255,0);
334 | border-right-color: rgba(255,255,255,1);
335 | right: auto;
336 | left: -10px;
337 | }
338 |
339 | .ui-slider-vertical.ui-slider-float .ui-slider-pip .ui-slider-tip-label:before {
340 | border: 5px solid rgba(255,255,255,0);
341 | border-right-color: #888;
342 | right: auto;
343 | left: -11px;
344 | }
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 | /* SELECTED STATES */
360 | /* Comment out this chuck of code if you don't want to have
361 | the new label colours shown */
362 |
363 | .ui-slider-pips [class*=ui-slider-pip-initial] {
364 |
365 | font-weight: bold;
366 | color: #14CA82;
367 |
368 | }
369 |
370 | .ui-slider-pips .ui-slider-pip-initial-1 {
371 |
372 | }
373 |
374 | .ui-slider-pips .ui-slider-pip-initial-2 {
375 | color: #1897C9;
376 | }
377 |
378 |
379 |
380 | .ui-slider-pips [class*=ui-slider-pip-selected] {
381 |
382 | font-weight: bold;
383 | color: #FF7A00;
384 |
385 | }
386 |
387 | .ui-slider-pips .ui-slider-pip-inrange {
388 |
389 | color: black;
390 |
391 | }
392 |
393 | .ui-slider-pips .ui-slider-pip-selected-1 {
394 |
395 | }
396 |
397 | .ui-slider-pips .ui-slider-pip-selected-2 {
398 | color: #E70081;
399 | }
400 |
401 |
402 | .ui-slider-pips [class*=ui-slider-pip-selected] .ui-slider-line,
403 | .ui-slider-pips .ui-slider-pip-inrange .ui-slider-line {
404 |
405 | background: black;
406 |
407 | }
408 |
409 |
410 |
411 |
--------------------------------------------------------------------------------
/src/js/jquery-ui-slider-pips.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 |
3 | "use strict";
4 |
5 | var extensionMethods = {
6 |
7 |
8 |
9 |
10 |
11 | // pips
12 |
13 | pips: function( settings ) {
14 |
15 | var slider = this,
16 | i, j, p,
17 | collection = "",
18 | mousedownHandlers,
19 | min = slider._valueMin(),
20 | max = slider._valueMax(),
21 | pips = ( max - min ) / slider.options.step,
22 | $handles = slider.element.find(".ui-slider-handle"),
23 | $pips;
24 |
25 | var options = {
26 |
27 | first: "label",
28 | /* "label", "pip", false */
29 |
30 | last: "label",
31 | /* "label", "pip", false */
32 |
33 | rest: "pip",
34 | /* "label", "pip", false */
35 |
36 | labels: false,
37 | /* [array], { first: "string", rest: [array], last: "string" }, false */
38 |
39 | prefix: "",
40 | /* "", string */
41 |
42 | suffix: "",
43 | /* "", string */
44 |
45 | step: ( pips > 100 ) ? Math.floor( pips * 0.05 ) : 1,
46 | /* number */
47 |
48 | formatLabel: function(value) {
49 | return this.prefix + value + this.suffix;
50 | }
51 | /* function
52 | must return a value to display in the pip labels */
53 |
54 | };
55 |
56 | if ( $.type( settings ) === "object" || $.type( settings ) === "undefined" ) {
57 |
58 | $.extend( options, settings );
59 | slider.element.data("pips-options", options );
60 |
61 | } else {
62 |
63 | if ( settings === "destroy" ) {
64 |
65 | destroy();
66 |
67 | } else if ( settings === "refresh" ) {
68 |
69 | slider.element.slider( "pips", slider.element.data("pips-options") );
70 |
71 | }
72 |
73 | return;
74 |
75 | }
76 |
77 |
78 | // we don't want the step ever to be a floating point or negative
79 | // (or 0 actually, so we'll set it to 1 in that case).
80 | slider.options.pipStep = Math.abs( Math.round( options.step ) ) || 1;
81 |
82 | // get rid of all pips that might already exist.
83 | slider.element
84 | .off( ".selectPip" )
85 | .addClass("ui-slider-pips")
86 | .find(".ui-slider-pip")
87 | .remove();
88 |
89 | // small object with functions for marking pips as selected.
90 |
91 | var selectPip = {
92 |
93 | single: function(value) {
94 |
95 | this.resetClasses();
96 |
97 | $pips
98 | .filter(".ui-slider-pip-" + this.classLabel(value) )
99 | .addClass("ui-slider-pip-selected");
100 |
101 | if ( slider.options.range ) {
102 |
103 | $pips.each(function(k, v) {
104 |
105 | var pipVal = $(v).children(".ui-slider-label").data("value");
106 |
107 | if (( slider.options.range === "min" && pipVal < value ) ||
108 | ( slider.options.range === "max" && pipVal > value )) {
109 |
110 | $(v).addClass("ui-slider-pip-inrange");
111 |
112 | }
113 |
114 | });
115 |
116 | }
117 |
118 | },
119 |
120 | range: function(values) {
121 |
122 | this.resetClasses();
123 |
124 | for ( i = 0; i < values.length; i++ ) {
125 |
126 | $pips
127 | .filter(".ui-slider-pip-" + this.classLabel(values[i]) )
128 | .addClass("ui-slider-pip-selected-" + ( i + 1 ) );
129 |
130 | }
131 |
132 | if ( slider.options.range ) {
133 |
134 | $pips.each(function(k, v) {
135 |
136 | var pipVal = $(v).children(".ui-slider-label").data("value");
137 |
138 | if ( pipVal > values[0] && pipVal < values[1] ) {
139 |
140 | $(v).addClass("ui-slider-pip-inrange");
141 |
142 | }
143 |
144 | });
145 |
146 | }
147 |
148 | },
149 |
150 | classLabel: function(value) {
151 |
152 | return value.toString().replace(".", "-");
153 |
154 | },
155 |
156 | resetClasses: function() {
157 |
158 | var regex = /(^|\s*)(ui-slider-pip-selected|ui-slider-pip-inrange)(-{1,2}\d+|\s|$)/gi;
159 |
160 | $pips.removeClass( function(index, css) {
161 | return ( css.match(regex) || [] ).join(" ");
162 | });
163 |
164 | }
165 |
166 | };
167 |
168 | function getClosestHandle( val ) {
169 |
170 | var h, k,
171 | sliderVals,
172 | comparedVals,
173 | closestVal,
174 | tempHandles = [],
175 | closestHandle = 0;
176 |
177 | if ( slider.values() && slider.values().length ) {
178 |
179 | // get the current values of the slider handles
180 | sliderVals = slider.values();
181 |
182 | // find the offset value from the `val` for each
183 | // handle, and store it in a new array
184 | comparedVals = $.map( sliderVals, function(v) {
185 | return Math.abs( v - val );
186 | });
187 |
188 | // figure out the closest handles to the value
189 | closestVal = Math.min.apply( Math, comparedVals );
190 |
191 | // if a comparedVal is the closestVal, then
192 | // set the value accordingly, and set the closest handle.
193 | for ( h = 0; h < comparedVals.length; h++ ) {
194 | if ( comparedVals[h] === closestVal ) {
195 | tempHandles.push(h);
196 | }
197 | }
198 |
199 | // set the closest handle to the first handle in array,
200 | // just incase we have no _lastChangedValue to compare to.
201 | closestHandle = tempHandles[0];
202 |
203 | // now we want to find out if any of the closest handles were
204 | // the last changed handle, if so we specify that handle to change
205 | for ( k = 0; k < tempHandles.length; k++ ) {
206 | if ( slider._lastChangedValue === tempHandles[k] ) {
207 | closestHandle = tempHandles[k];
208 | }
209 | }
210 |
211 | if ( slider.options.range && tempHandles.length === 2 ) {
212 |
213 | if ( val > sliderVals[1] ) {
214 |
215 | closestHandle = tempHandles[1];
216 |
217 | } else if ( val < sliderVals[0] ) {
218 |
219 | closestHandle = tempHandles[0];
220 |
221 | }
222 |
223 | }
224 |
225 | }
226 |
227 | return closestHandle;
228 |
229 | }
230 |
231 | function destroy() {
232 |
233 | slider.element
234 | .off(".selectPip")
235 | .on("mousedown.slider", slider.element.data("mousedown-original") )
236 | .removeClass("ui-slider-pips")
237 | .find(".ui-slider-pip")
238 | .remove();
239 |
240 | }
241 |
242 | // when we click on a label, we want to make sure the
243 | // slider's handle actually goes to that label!
244 | // so we check all the handles and see which one is closest
245 | // to the label we clicked. If 2 handles are equidistant then
246 | // we move both of them. We also want to trigger focus on the
247 | // handle.
248 |
249 | // without this method the label is just treated like a part
250 | // of the slider and there's no accuracy in the selected value
251 |
252 | function labelClick( label, e ) {
253 |
254 | if (slider.option("disabled")) {
255 | return;
256 | }
257 |
258 | var val = $(label).data("value"),
259 | indexToChange = getClosestHandle( val );
260 |
261 | if ( slider.values() && slider.values().length ) {
262 |
263 | slider.options.values[ indexToChange ] = slider._trimAlignValue( val );
264 |
265 | } else {
266 |
267 | slider.options.value = slider._trimAlignValue( val );
268 |
269 | }
270 |
271 | slider._refreshValue();
272 | slider._change( e, indexToChange );
273 |
274 | }
275 |
276 | // method for creating a pip. We loop this for creating all
277 | // the pips.
278 |
279 | function createPip( which ) {
280 |
281 | var label,
282 | percent,
283 | number = which,
284 | classes = "ui-slider-pip",
285 | css = "",
286 | value = slider.value(),
287 | values = slider.values(),
288 | labelValue,
289 | classLabel,
290 | labelIndex;
291 |
292 | if ( which === "first" ) {
293 |
294 | number = 0;
295 |
296 | } else if ( which === "last" ) {
297 |
298 | number = pips;
299 |
300 | }
301 |
302 | // labelValue is the actual value of the pip based on the min/step
303 | labelValue = min + ( slider.options.step * number );
304 |
305 | // classLabel replaces any decimals with hyphens
306 | classLabel = labelValue.toString().replace(".", "-");
307 |
308 | // get the index needed for selecting labels out of the array
309 | labelIndex = ( number + min ) - min;
310 |
311 | // we need to set the human-readable label to either the
312 | // corresponding element in the array, or the appropriate
313 | // item in the object... or an empty string.
314 |
315 | if ( $.type(options.labels) === "array" ) {
316 |
317 | label = options.labels[ labelIndex ] || "";
318 |
319 | } else if ( $.type( options.labels ) === "object" ) {
320 |
321 | if ( which === "first" ) {
322 |
323 | // set first label
324 | label = options.labels.first || "";
325 |
326 | } else if ( which === "last" ) {
327 |
328 | // set last label
329 | label = options.labels.last || "";
330 |
331 | } else if ( $.type( options.labels.rest ) === "array" ) {
332 |
333 | // set other labels, but our index should start at -1
334 | // because of the first pip.
335 | label = options.labels.rest[ labelIndex - 1 ] || "";
336 |
337 | } else {
338 |
339 | // urrggh, the options must be f**ked, just show nothing.
340 | label = labelValue;
341 |
342 | }
343 |
344 | } else {
345 |
346 | label = labelValue;
347 |
348 | }
349 |
350 |
351 |
352 |
353 | if ( which === "first" ) {
354 |
355 | // first Pip on the Slider
356 | percent = "0%";
357 |
358 | classes += " ui-slider-pip-first";
359 | classes += ( options.first === "label" ) ? " ui-slider-pip-label" : "";
360 | classes += ( options.first === false ) ? " ui-slider-pip-hide" : "";
361 |
362 | } else if ( which === "last" ) {
363 |
364 | // last Pip on the Slider
365 | percent = "100%";
366 |
367 | classes += " ui-slider-pip-last";
368 | classes += ( options.last === "label" ) ? " ui-slider-pip-label" : "";
369 | classes += ( options.last === false ) ? " ui-slider-pip-hide" : "";
370 |
371 | } else {
372 |
373 | // all other Pips
374 | percent = (( 100 / pips ) * which ).toFixed(4) + "%";
375 |
376 | classes += ( options.rest === "label" ) ? " ui-slider-pip-label" : "";
377 | classes += ( options.rest === false ) ? " ui-slider-pip-hide" : "";
378 |
379 | }
380 |
381 | classes += " ui-slider-pip-" + classLabel;
382 |
383 |
384 | // add classes for the initial-selected values.
385 | if ( values && values.length ) {
386 |
387 | for ( i = 0; i < values.length; i++ ) {
388 |
389 | if ( labelValue === values[i] ) {
390 |
391 | classes += " ui-slider-pip-initial-" + ( i + 1 );
392 | classes += " ui-slider-pip-selected-" + ( i + 1 );
393 |
394 | }
395 |
396 | }
397 |
398 | if ( slider.options.range ) {
399 |
400 | if ( labelValue > values[0] &&
401 | labelValue < values[1] ) {
402 |
403 | classes += " ui-slider-pip-inrange";
404 |
405 | }
406 |
407 | }
408 |
409 | } else {
410 |
411 | if ( labelValue === value ) {
412 |
413 | classes += " ui-slider-pip-initial";
414 | classes += " ui-slider-pip-selected";
415 |
416 | }
417 |
418 | if ( slider.options.range ) {
419 |
420 | if (( slider.options.range === "min" && labelValue < value ) ||
421 | ( slider.options.range === "max" && labelValue > value )) {
422 |
423 | classes += " ui-slider-pip-inrange";
424 |
425 | }
426 |
427 | }
428 |
429 | }
430 |
431 |
432 |
433 | css = ( slider.options.orientation === "horizontal" ) ?
434 | "left: " + percent :
435 | "bottom: " + percent;
436 |
437 |
438 | // add this current pip to the collection
439 | return "" +
440 | "" +
441 | "" + options.formatLabel(label) + "" +
443 | "";
444 |
445 | }
446 |
447 | // create our first pip
448 | collection += createPip("first");
449 |
450 | // for every stop in the slider where we need a pip; create one.
451 | for ( p = slider.options.pipStep; p < pips; p += slider.options.pipStep ) {
452 | collection += createPip( p );
453 | }
454 |
455 | // create our last pip
456 | collection += createPip("last");
457 |
458 | // append the collection of pips.
459 | slider.element.append( collection );
460 |
461 | // store the pips for setting classes later.
462 | $pips = slider.element.find(".ui-slider-pip");
463 |
464 |
465 |
466 | // store the mousedown handlers for later, just in case we reset
467 | // the slider, the handler would be lost!
468 |
469 | if ( $._data( slider.element.get(0), "events").mousedown &&
470 | $._data( slider.element.get(0), "events").mousedown.length ) {
471 |
472 | mousedownHandlers = $._data( slider.element.get(0), "events").mousedown;
473 |
474 | } else {
475 |
476 | mousedownHandlers = slider.element.data("mousedown-handlers");
477 |
478 | }
479 |
480 | slider.element.data("mousedown-handlers", mousedownHandlers.slice() );
481 |
482 | // loop through all the mousedown handlers on the slider,
483 | // and store the original namespaced (.slider) event handler so
484 | // we can trigger it later.
485 | for ( j = 0; j < mousedownHandlers.length; j++ ) {
486 | if ( mousedownHandlers[j].namespace === "slider" ) {
487 | slider.element.data("mousedown-original", mousedownHandlers[j].handler );
488 | }
489 | }
490 |
491 | // unbind the mousedown.slider event, because it interferes with
492 | // the labelClick() method (stops smooth animation), and decide
493 | // if we want to trigger the original event based on which element
494 | // was clicked.
495 | slider.element
496 | .off("mousedown.slider")
497 | .on("mousedown.selectPip", function(e) {
498 |
499 | var $target = $(e.target),
500 | closest = getClosestHandle( $target.data("value") ),
501 | $handle = $handles.eq( closest );
502 |
503 | $handle.addClass("ui-state-active");
504 |
505 | if ( $target.is(".ui-slider-label") ) {
506 |
507 | labelClick( $target, e );
508 |
509 | slider.element
510 | .one("mouseup.selectPip", function() {
511 |
512 | $handle
513 | .removeClass("ui-state-active")
514 | .focus();
515 |
516 | });
517 |
518 | } else {
519 |
520 | var originalMousedown = slider.element.data("mousedown-original");
521 | originalMousedown(e);
522 |
523 | }
524 |
525 | });
526 |
527 |
528 |
529 |
530 | slider.element.on( "slide.selectPip slidechange.selectPip", function(e, ui) {
531 |
532 | var $slider = $(this),
533 | value = $slider.slider("value"),
534 | values = $slider.slider("values");
535 |
536 | if ( ui ) {
537 |
538 | value = ui.value;
539 | values = ui.values;
540 |
541 | }
542 |
543 | if ( slider.values() && slider.values().length ) {
544 |
545 | selectPip.range( values );
546 |
547 | } else {
548 |
549 | selectPip.single( value );
550 |
551 | }
552 |
553 | });
554 |
555 |
556 |
557 |
558 | },
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 | // floats
568 |
569 | float: function( settings ) {
570 |
571 | var i,
572 | slider = this,
573 | min = slider._valueMin(),
574 | max = slider._valueMax(),
575 | value = slider._value(),
576 | values = slider._values(),
577 | tipValues = [],
578 | $handles = slider.element.find(".ui-slider-handle");
579 |
580 | var options = {
581 |
582 | handle: true,
583 | /* false */
584 |
585 | pips: false,
586 | /* true */
587 |
588 | labels: false,
589 | /* [array], { first: "string", rest: [array], last: "string" }, false */
590 |
591 | prefix: "",
592 | /* "", string */
593 |
594 | suffix: "",
595 | /* "", string */
596 |
597 | event: "slidechange slide",
598 | /* "slidechange", "slide", "slidechange slide" */
599 |
600 | formatLabel: function(value) {
601 | return this.prefix + value + this.suffix;
602 | }
603 | /* function
604 | must return a value to display in the floats */
605 |
606 | };
607 |
608 | if ( $.type( settings ) === "object" || $.type( settings ) === "undefined" ) {
609 |
610 | $.extend( options, settings );
611 | slider.element.data("float-options", options );
612 |
613 | } else {
614 |
615 | if ( settings === "destroy" ) {
616 |
617 | destroy();
618 |
619 | } else if ( settings === "refresh" ) {
620 |
621 | slider.element.slider( "float", slider.element.data("float-options") );
622 |
623 | }
624 |
625 | return;
626 |
627 | }
628 |
629 |
630 |
631 |
632 | if ( value < min ) {
633 | value = min;
634 | }
635 |
636 | if ( value > max ) {
637 | value = max;
638 | }
639 |
640 | if ( values && values.length ) {
641 |
642 | for ( i = 0; i < values.length; i++ ) {
643 |
644 | if ( values[i] < min ) {
645 | values[i] = min;
646 | }
647 |
648 | if ( values[i] > max ) {
649 | values[i] = max;
650 | }
651 |
652 | }
653 |
654 | }
655 |
656 | // add a class for the CSS
657 | slider.element
658 | .addClass("ui-slider-float")
659 | .find(".ui-slider-tip, .ui-slider-tip-label")
660 | .remove();
661 |
662 |
663 |
664 | function destroy() {
665 |
666 | slider.element
667 | .off(".sliderFloat")
668 | .removeClass("ui-slider-float")
669 | .find(".ui-slider-tip, .ui-slider-tip-label")
670 | .remove();
671 |
672 | }
673 |
674 |
675 | function getPipLabels( values ) {
676 |
677 | // when checking the array we need to divide
678 | // by the step option, so we store those values here.
679 |
680 | var vals = [],
681 | steppedVals = $.map( values, function(v) {
682 | return Math.ceil(( v - min ) / slider.options.step);
683 | });
684 |
685 | // now we just get the values we need to return
686 | // by looping through the values array and assigning the
687 | // label if it exists.
688 |
689 | if ( $.type( options.labels ) === "array" ) {
690 |
691 | for ( i = 0; i < values.length; i++ ) {
692 |
693 | vals[i] = options.labels[ steppedVals[i] ] || values[i];
694 |
695 | }
696 |
697 | } else if ( $.type( options.labels ) === "object" ) {
698 |
699 | for ( i = 0; i < values.length; i++ ) {
700 |
701 | if ( values[i] === min ) {
702 |
703 | vals[i] = options.labels.first || min;
704 |
705 | } else if ( values[i] === max ) {
706 |
707 | vals[i] = options.labels.last || max;
708 |
709 | } else if ( $.type( options.labels.rest ) === "array" ) {
710 |
711 | vals[i] = options.labels.rest[ steppedVals[i] - 1 ] || values[i];
712 |
713 | } else {
714 |
715 | vals[i] = values[i];
716 |
717 | }
718 |
719 | }
720 |
721 | } else {
722 |
723 | for ( i = 0; i < values.length; i++ ) {
724 |
725 | vals[i] = values[i];
726 |
727 | }
728 |
729 | }
730 |
731 | return vals;
732 |
733 | }
734 |
735 | // apply handle tip if settings allows.
736 | if ( options.handle ) {
737 |
738 | // we need to set the human-readable label to either the
739 | // corresponding element in the array, or the appropriate
740 | // item in the object... or an empty string.
741 |
742 | tipValues = ( slider.values() && slider.values().length ) ?
743 | getPipLabels( values ) :
744 | getPipLabels( [ value ] );
745 |
746 | for ( i = 0; i < tipValues.length; i++ ) {
747 |
748 | $handles
749 | .eq( i )
750 | .append( $(""+ options.formatLabel(tipValues[i]) +"") );
751 |
752 | }
753 |
754 | }
755 |
756 | if ( options.pips ) {
757 |
758 | // if this slider also has pip-labels, we make those into tips, too.
759 | slider.element.find(".ui-slider-label").each(function(k, v) {
760 |
761 | var $this = $(v),
762 | val = [ $this.data("value") ],
763 | label,
764 | $tip;
765 |
766 |
767 | label = options.formatLabel( getPipLabels( val )[0] );
768 |
769 | // create a tip element
770 | $tip =
771 | $("" + label + "")
772 | .insertAfter( $this );
773 |
774 | });
775 |
776 | }
777 |
778 | // check that the event option is actually valid against our
779 | // own list of the slider's events.
780 | if ( options.event !== "slide" &&
781 | options.event !== "slidechange" &&
782 | options.event !== "slide slidechange" &&
783 | options.event !== "slidechange slide" ) {
784 |
785 | options.event = "slidechange slide";
786 |
787 | }
788 |
789 | // when slider changes, update handle tip label.
790 | slider.element
791 | .off(".sliderFloat")
792 | .on( options.event + ".sliderFloat", function( e, ui ) {
793 |
794 | var uiValue = ( $.type( ui.value ) === "array" ) ? ui.value : [ ui.value ],
795 | val = options.formatLabel( getPipLabels( uiValue )[0] );
796 |
797 | $(ui.handle)
798 | .find(".ui-slider-tip")
799 | .html( val );
800 |
801 | });
802 |
803 | }
804 |
805 | };
806 |
807 | $.extend(true, $.ui.slider.prototype, extensionMethods);
808 |
809 | })(jQuery);
810 |
--------------------------------------------------------------------------------