bootstrap-slider
bootstrap-slider copied to clipboard
tick labels are not correctly possitioned if slider is used in a modal
The tick labels are not correctly positioned when the slider is used in a bootstrap modal.
see fiddle: http://jsfiddle.net/h3WDq/662/
This appears to be related (if not a duplicate) of: #140 #358 #381
this has something "similar" the problem with the tick labels is that when the slider is used on a modal the "calculated" labelSize is 0 and therefore all calculations done with it are also wrong.
The labelSize is wrong because "this.size" is zero.
var labelSize = this.size / (this.options.ticks.length - 1);
The calculation should be done if something is visible. which seems not the case if a modal is used or the slider is added via ajax in a modal.
This problem would be fixed (and all other positioning problems) if all positions/margins etc. are not set in "px" but instead in "%".
Another thing i have seen that on vertical orientation the tick labels are also not working at all (so also in the normal rendering)
As written above this is all because of "px" alignment of the labels.
Also the positioning with fixed ticks_positions isn't working (test with 0%,50% ,100%)
i have updated the fiddle to show these issues http://jsfiddle.net/h3WDq/752/ (updated the fiddle with new src links)
I have already fixed the tick label positioning problem see my latest commit. https://github.com/seiyria/bootstrap-slider/commit/97e11114589d53659c95db6663ecb97736dfd49a
I used the flexbox method mentioned here http://stackoverflow.com/questions/19461521/how-to-center-an-element-horizontally-and-vertically and used css translate to put the labels in the correct position.
@Bhoft, I got around the initial issue with tick label positioning (which also occurs in a Bootstrap nav-tab which is not active on page load) by calling
$("input.slider").bootstrapSlider('refresh');
once the tab has switched. I would think that the same should work for modals.
As you might have seen in a fiddle which uses my fork i fixed this issue some time ago some other way (I don't set the positions like the original version, so i don't have to do a refresh).
I don't know what has changed since that date on the original version because I didn't had time to check and my PRs nether were merged and are now again not automatically merge-able.
But my fiddle tests still seem to work https://github.com/seiyria/bootstrap-slider/issues/341#issuecomment-143150101 so i guess the issue is still valid on current version.
I've the same problem, the issue only happens if the slider is hidden by default and when it appears, the labels are displayed like in first image above, but is not happening if the slider is initially displayed, someone knows what's the issue related to?
This might have been fixed by the most recent bug fix. Have you tried the most recent version?
I'm with 6.1.6, this bug still there, label positions incorrect when slider created in a modal.
I got around just like what @mat2maa said, only difference is, wrapped in a timeout call (sorry, it's in typescript)
let slider = new Slider(id, options) this.Timeout(() => { slider.refresh() })
This is still an issue in Release v7.0.3. Please add a fix.
If something is urgent, we'd suggest you to add a well-tested PR. It closes issues a lot faster!
Confirmed this issue is still present in 7.0.2:
https://jsfiddle.net/jz7f7vas/
Request you to write the code in CSS. How ever the solution would be temporarily
.slider.slider-horizontal .slider-tick-label-container .slider-tick-label{ width: 35 !important; }
if they anyone gets the solution it would be a great help
This still seems to be an issue with 9.7.2:
https://jsfiddle.net/jz7f7vas/ (same example from @el-timm )
As pointed out, it will render fine on the page after clicked / interacted with, and if the page is not refreshed, it will continue to render properly with each subsequent click to open the modal - it's just the initial render that is hosed.
Any known ways around it?
Until someone has the time to fix this, here is a very simple workaround that seems to work:
https://jsfiddle.net/jz7f7vas/7/
var thisModal =$('#myModal');
thisModal.modal('show');
$("#slider").slider("refresh");
thisModal.modal('hide');
(it's kind of stupid, but hey, it works. :P)
just have to instantiate the slider BEFORE you call it in your code - for anyone noob like me :)
we would really appreciate a PR to fix this!
+1 Same issue with v9.8.0
I was able to work around this problem by triggering a resize event that causes a redraw:
window.dispatchEvent(new Event('resize'));
The refresh
command caused other side-effects so this was the easiest workaround.
I was able to resolve this using the 'relayout' event to force a redraw at the right moment. Since I'm using the data-provide attribute my jQuery command looks as follows: $('input[data-provide="slider"]').slider('relayout');
Currently using an interval approach in my ngx app.
const interval = setInterval(() => this.slider.refresh(), 100);
this.modal.onShown = () => clearInterval(interval);
Or, from a more jQuery approach...
var interval = setInterval(function() {$("#slider").slider("refresh")}, 100);
$('#modal').on('shown.bs.modal', function() {clearInterval});
This is the only way I could get the modal to appear smoothly and not have a timer perpetually running in the background.
This solution does not please me in any way.
I found a Fix, in my case I use this slider inside an item into bootstrap carousel (#webform-carousel), I put refresh() function into slid.bs.carousel event and this update all style parameters for those labels.
var slider_credit = new Slider("#credit_score", { ticks: [619, 659, 699, 739], ticks_labels: ['Pobre 639 o Menor', 'Justo 640-679', 'Buena 680-719', 'Excelente 720+'], value: 619, step: 40, tooltip: 'hide' });
$('#webform-carousel').on('slid.bs.carousel',function(e){ slider_credit.refresh(); });
I initially tried this Javascript fix for Bootstrap 4, but it made a subtle flash when initiated:
$('#modal').on('shown.bs.modal', function (e) {
$("#slider").slider("refresh");
})
However, looking through the fork by @Bhoft, I realized I only needed to commit the following changes:
boostrap-slider.js – line 1259 (included the old code for reference)
if (this.tickLabels[i]) {
this.tickLabels[i].style[styleSize] = labelSize + '%';
this.tickLabels[i].style.position = 'absolute';
if (this.options.ticks_positions[i] !== undefined) {
this.tickLabels[i].style[this.stylePos] = this.options.ticks_positions[i] + '%';
} else {
this.tickLabels[i].style[this.stylePos] = (100 / (this.options.ticks.length-1)) * i + '%';
}
// this.tickLabels[i].style[styleSize] = labelSize + "px";
// if (this.options.orientation !== 'vertical' && this.options.ticks_positions[i] !== undefined) {
// this.tickLabels[i].style.position = 'absolute';
// this.tickLabels[i].style[this.stylePos] = percentage + "%";
// this.tickLabels[i].style[styleMargin] = -labelSize / 2 + 'px';
// } else if (this.options.orientation === 'vertical') {
// if (this.options.rtl) {
// this.tickLabels[i].style['marginRight'] = this.sliderElem.offsetWidth + "px";
// } else {
// this.tickLabels[i].style['marginLeft'] = this.sliderElem.offsetWidth + "px";
// }
// this.tickLabelContainer.style[styleMargin] = this.sliderElem.offsetWidth / 2 * -1 + 'px';
// }
}
bootstrap-slider.css (line 154) or custom css file
.slider-tick-label {
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
justify-content: center;
}
.slider.slider-vertical .slider-tick-label-container .slider-tick-label {
padding-left: 30px;
}
Since I am only using the vertical slider and not sure how , I won't make a PR (yet).
for me this fixed the issue. I called this when using the next button action method that would render the bootstrap slider in a form.
window.dispatchEvent(new Event('resize'));
I had it in a bootstrap tab, this worked for me:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
window.dispatchEvent(new Event('resize'));
});
hmmm...so looks like the solution would be to somehow expose a way to trigger the method listening for the resize event
Until someone has the time to fix this, here is a very simple workaround that seems to work:
https://jsfiddle.net/jz7f7vas/7/
var thisModal =$('#myModal'); thisModal.modal('show'); $("#slider").slider("refresh"); thisModal.modal('hide');
(it's kind of stupid, but hey, it works. :P)
It is really nice.
Hi! I solved this problem by adding this line in the slider statement:
$('.slider').bootstrapSlider({
...
ticks_positions: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
...
})
Defines the positions of the tick values in percentages. The first value should always be 0, the last value should always be 100 percent.
So the numbers don't overlap and each one takes its place.