Skip to content

Commit

Permalink
Merge pull request #314 from MelleB/tick-positions
Browse files Browse the repository at this point in the history
(feat) Add option to define position of ticks
  • Loading branch information
rovolution committed Apr 11, 2015
2 parents 4e1d73e + a57c70f commit 19deef5
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 94 deletions.
4 changes: 2 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ module.exports = function(grunt) {
tasks: ['jshint:spec', 'jasmine:src']
},
css : {
files: '<%= pkg.gruntConfig.less.slider %>',
files: ['<%= pkg.gruntConfig.less.slider %>', '<%= pkg.gruntConfig.less.rules %>', '<%= pkg.gruntConfig.less.variables %>'],
tasks: ['less:development']
},
index : {
Expand Down Expand Up @@ -232,4 +232,4 @@ module.exports = function(grunt) {
grunt.registerTask('dist', 'production');
grunt.registerTask('dist-no-tests', ['less:production', 'less:production-min', 'uglify', 'append-header']);
grunt.registerTask('default', 'build');
};
};
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Options can be passed either as a data (data-slider-foo) attribute, or as part o
| formatter | function | returns the plain value | formatter callback. Return the value wanted to be displayed in the tooltip |
| natural_arrow_keys | bool | false | The natural order is used for the arrow keys. Arrow up select the upper slider value for vertical sliders, arrow right the righter slider value for a horizontal slider - no matter if the slider was reversed or not. By default the arrow keys are oriented by arrow up/right to the higher slider value, arrow down/left to the lower slider value. |
| ticks | array | [ ] | Used to define the values of ticks. Tick marks are indicators to denote special values in the range. This option overwrites min and max options. |
| ticks_positions | array | [ ] | Defines the positions of the tick values in percentages. The first value should alwasy be 0, the last value should always be 100 percent. |
| ticks_labels | array | [ ] | Defines the labels below the tick marks. Accepts HTML input. |
| ticks_snap_bounds | float | 0 | Used to define the snap bounds of a tick. Snaps to the tick if value is within these bounds. |
| scale | string | 'linear' | Set to 'logarithmic' to use a logarithmic scale. |
Expand Down
3 changes: 2 additions & 1 deletion css/bootstrap-slider.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@
}
.slider.slider-horizontal .slider-tick-label-container {
white-space: nowrap;
margin-top: 20px;
}
.slider.slider-horizontal .slider-tick-label-container .slider-tick-label {
margin-top: 24px;
padding-top: 4px;
display: inline-block;
text-align: center;
}
Expand Down
121 changes: 83 additions & 38 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -711,53 +711,87 @@ <h3>Example 13:</h3>
</code></pre>
</div>

<div class='slider-example'>
<h3>Example 14:</h3>
<p>Using tick marks at specific positions..</p>
<div class="well">
<input id="ex14" type="text"/>
</div>
<pre><code>
###################
HTML
###################

&ltinput id="ex14" type="text" data-slider-ticks="[0, 100, 200, 300, 400]" data-slider-ticks-snap-bounds="30" data-slider-ticks-labels="['$0', '$100', '$200', '$300', '$400']" ticks_positions="[0, 30, 60, 70, 90, 100]" /&gt

###################
JavaScript
###################

// With JQuery
$("#ex14").slider({
ticks: [0, 100, 200, 300, 400],
ticks_positions: [0, 30, 60, 70, 90, 100],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_snap_bounds: 30
});

// Without JQuery
var slider = new Slider("#ex14", {
ticks: [0, 100, 200, 300, 400],
ticks_positions: [0, 30, 60, 70, 90, 100],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_snap_bounds: 30
});

</code></pre>
</div>

<div class='slider-example'>
<h3>Example 14:</h3>
<h3>Example 15:</h3>
<p>With a logarithmic scale.</p>
<div class="well">
<input id="ex14" type="text" data-slider-min="1000" data-slider-max="10000000" data-slider-step="5" />
<input id="ex15" type="text" data-slider-min="1000" data-slider-max="10000000" data-slider-step="5" />
</div>
<pre><code>
###################
HTML
###################

&lt;input id="ex14" type="text" data-slider-min="1000" data-slider-max="10000000" data-slider-step="5" /&gt;
&lt;input id="ex15" type="text" data-slider-min="1000" data-slider-max="10000000" data-slider-step="5" /&gt;

###################
JavaScript
###################

// With JQuery
$("#ex14").slider({
$("#ex15").slider({
min: 1000,
max: 10000000,
scale: 'logarithmic',
step: 10
});

// Without JQuery
var slider = new Slider('#ex14', {
var slider = new Slider('#ex15', {
min: 1000,
max: 10000000,
scale: 'logarithmic',
step: 10
});


</code></pre>
</div>
</div>

<div class="slider-example">
<h3>Example 15:</h3>
<h3>Example 16:</h3>
<p>Focus the slider handle after a value change.</p>
<div class="well">
Single-value slider:<br/>
<input id="ex15a" type="text"/><br/>
<input id="ex16a" type="text"/><br/>
<br/><br/>
Range slider:<br/>
<input id="ex15b" type="text"/>
<input id="ex16b" type="text"/>
</div>
<pre>
<code>
Expand All @@ -766,28 +800,29 @@ <h3>Example 15:</h3>
HTML
###################
&lt;!-- Single-value slider: --&gt;
&ltinput id="ex15a" type="text"/&gt&ltbr/&gt
&ltinput id="ex16a" type="text"/&gt&ltbr/&gt

&lt;!-- Range slider: --&gt;
&ltinput id="ex15b" type="text"/&gt&ltbr/&gt
&ltinput id="ex16b" type="text"/&gt&ltbr/&gt
Note that the slider handle that caused the value change is focused.

###################
JavaScript
###################

// With JQuery
$("#ex15a").slider({ min: 0, max: 10, value: 0, focus: true });
$("#ex15b").slider({ min: 0, max: 10, value: [0, 10], focus: true });
$("#ex16a").slider({ min: 0, max: 10, value: 0, focus: true });
$("#ex16b").slider({ min: 0, max: 10, value: [0, 10], focus: true });

// Without JQuery
new Slider("#ex15a", { min: 0, max: 10, value: 0, focus: true });
new Slider("#ex15b", { min: 0, max: 10, value: [0, 10], focus: true });
new Slider("#ex16a", { min: 0, max: 10, value: 0, focus: true });
new Slider("#ex16b", { min: 0, max: 10, value: [0, 10], focus: true });

</code>
</pre>
</div>


</div> <!-- /examples -->
</div> <!-- /container -->

Expand Down Expand Up @@ -894,35 +929,45 @@ <h3>Example 15:</h3>
value: [ 3, 7 ]
});

/* Example 13 */
$("#ex13").slider({
ticks: [0, 100, 200, 300, 400],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_snap_bounds: 30,
value: 200
});
/* Example 13 */
$("#ex13").slider({
ticks: [0, 100, 200, 300, 400],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_snap_bounds: 30,
value: 200
});

/* Example 14 */
$("#ex14").slider({
ticks: [0, 100, 200, 300, 400],
ticks_labels: ['$0', '$100', '$200', '$300', '$400'],
ticks_positions: [0, 30, 70, 90, 100],
ticks_snap_bounds: 20,
value: 200
});

/* Example 15 */
$("#ex15").slider({
min: 10,
max: 1000,
scale: 'logarithmic',
step: 10
});
});

/* Example 15 */
$("#ex15a").slider({
min : 0,
max : 10,
value: 0,
focus: true
});
$("#ex15b").slider({
min : 0,
max : 10,
value: [ 0, 10 ],
focus: true
});

/* Example 16 */
$("#ex16a").slider({
min : 0,
max : 10,
value: 0,
focus: true
});
$("#ex16b").slider({
min : 0,
max : 10,
value: [ 0, 10 ],
focus: true
});
});
</script>
<!-- Placed at the end of the document so the pages load faster -->
</body>
Expand Down
74 changes: 64 additions & 10 deletions js/bootstrap-slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,25 @@
linear: {
toValue: function(percentage) {
var rawValue = percentage/100 * (this.options.max - this.options.min);
var value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step;
if (this.options.ticks_positions.length > 0) {
var minv, maxv, minp, maxp = 0;
for (var i = 0; i < this.options.ticks_positions.length; i++) {
if (percentage <= this.options.ticks_positions[i]) {
minv = (i > 0) ? this.options.ticks[i-1] : 0;
minp = (i > 0) ? this.options.ticks_positions[i-1] : 0;
maxv = this.options.ticks[i];
maxp = this.options.ticks_positions[i];

break;
}
}
if (i > 0) {
var partialPercentage = (percentage - minp) / (maxp - minp);
rawValue = minv + partialPercentage * (maxv - minv);
}
}

var value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step;
if (value < this.options.min) {
return this.options.min;
} else if (value > this.options.max) {
Expand All @@ -220,9 +237,27 @@
toPercentage: function(value) {
if (this.options.max === this.options.min) {
return 0;
} else {
return 100 * (value - this.options.min) / (this.options.max - this.options.min);
}

if (this.options.ticks_positions.length > 0) {
var minv, maxv, minp, maxp = 0;
for (var i = 0; i < this.options.ticks.length; i++) {
if (value <= this.options.ticks[i]) {
minv = (i > 0) ? this.options.ticks[i-1] : 0;
minp = (i > 0) ? this.options.ticks_positions[i-1] : 0;
maxv = this.options.ticks[i];
maxp = this.options.ticks_positions[i];

break;
}
}
if (i > 0) {
var partialPercentage = (value - minv) / (maxv - minv);
return minp + partialPercentage * (maxp - minp);
}
}

return 100 * (value - this.options.min) / (this.options.max - this.options.min);
}
},

Expand Down Expand Up @@ -523,7 +558,6 @@
this.options.min = Math.min.apply(Math, this.options.ticks);
}


if (Array.isArray(this.options.value)) {
this.options.range = true;
} else if (this.options.range) {
Expand Down Expand Up @@ -658,6 +692,7 @@
},
natural_arrow_keys: false,
ticks: [],
ticks_positions: [],
ticks_labels: [],
ticks_snap_bounds: 0,
scale: 'linear',
Expand Down Expand Up @@ -894,14 +929,27 @@
var labelSize = this.size / (this.options.ticks.length - 1);

if (this.tickLabelContainer) {
this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';
var extraMargin = 0;
if (this.options.ticks_positions.length === 0) {
this.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';
extraMargin = this.tickLabelContainer.offsetHeight;
} else {
/* Chidren are position absolute, calculate height by finding the max offsetHeight of a child */
for (i = 0 ; i < this.tickLabelContainer.childNodes.length; i++) {
if (this.tickLabelContainer.childNodes[i].offsetHeight > extraMargin) {
extraMargin = this.tickLabelContainer.childNodes[i].offsetHeight;
}
}
}
if (this.options.orientation === 'horizontal') {
var extraHeight = this.tickLabelContainer.offsetHeight - this.sliderElem.offsetHeight;
this.sliderElem.style.marginBottom = extraHeight + 'px';
this.sliderElem.style.marginBottom = extraMargin + 'px';
}
}
for (var i = 0; i < this.options.ticks.length; i++) {
var percentage = 100 * (this.options.ticks[i] - minTickValue) / (maxTickValue - minTickValue);

var percentage = this.options.ticks_positions[i] ||
100 * (this.options.ticks[i] - minTickValue) / (maxTickValue - minTickValue);

this.ticks[i].style[this.stylePos] = percentage + '%';

/* Set class labels to denote whether ticks are in the selection */
Expand All @@ -918,6 +966,12 @@

if (this.tickLabels[i]) {
this.tickLabels[i].style[styleSize] = labelSize + 'px';

if (this.options.ticks_positions[i] !== undefined) {
this.tickLabels[i].style.position = 'absolute';
this.tickLabels[i].style[this.stylePos] = this.options.ticks_positions[i] + '%';
this.tickLabels[i].style[styleMargin] = -labelSize/2 + 'px';
}
}
}
}
Expand Down Expand Up @@ -953,9 +1007,9 @@
this._addClass(this.tooltip_max, 'top');
this.tooltip_max.style.top = this.tooltip_min.style.top;
}
}
}

var formattedTooltipVal;
var formattedTooltipVal;

if (this.options.range) {
formattedTooltipVal = this.options.formatter(this.options.value);
Expand Down
7 changes: 4 additions & 3 deletions less/rules.less
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@
}
.slider-tick-label-container {
white-space: nowrap;

margin-top: @slider-line-height;

.slider-tick-label {
margin-top: @slider-line-height * 1.2;
padding-top: @slider-line-height * .2;
display: inline-block;
text-align: center;
}
Expand Down Expand Up @@ -174,4 +175,4 @@
#gradient > .vertical(#89cdef, #81bfde);
opacity: 1;
}
}
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
"bindPolyfill": "test/phantom_bind_polyfill.js"
},
"less": {
"slider": "less/bootstrap-slider.less"
"slider": "less/bootstrap-slider.less",
"rules": "less/rules.less",
"variables": "less/variables.less"
},
"css": {
"bootstrap": "bower_components/bootstrap/dist/css/bootstrap.min.css",
Expand Down
Loading

0 comments on commit 19deef5

Please sign in to comment.