Closed rcbgit closed 9 years ago
I can confirm this issue (using Angular 1.4.x).
Update: if i resize my window, slider is updated and renders as it should. My problem might be rleated to the fact that i'm using angular-ui tabs and probably i have to use somehow:
$scope.$broadcast('reCalcViewDimensions');
I also see the slider render correctly when I resize.
Still no fix. Let me know if you come up with anything.
Thanks!
Hi @rcbgit,
as i mentioned before i am using it inside tabs (ui-bootstrap) so the tab content is loaded when we select tab and because of this the sliders aren't updated as they should i think. What i do is to use tab 'select' attribute to call my custom function:
<tabset>
<tab select="ctrl.broadcast()">
<tab-heading>Heading</tab-heading>
@include('_partials.form_tabs_general')
</tab>
...
</tabset>
and in my controller:
function broadcast() {
setTimeout(function(){
$scope.$broadcast('reCalcViewDimensions');
}, 10);
}
In some cases it is better to use Angular's $timeout service instead of native setTimeout.
I can also confirm this issue. It doesn't work in combination with the following Jquery:
$(document).ready(function () {
$('.filterButton').click(function (e) {
e.preventDefault();
$('.filterButton').removeClass('on');
$('.filterContent').slideUp('normal');
if ($(this).next().is(':hidden') == true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
}
});
$('.filterContent').hide();
});
I also experienced exactly what OP described. This repo however seems to be dead anyway.
Yes same issue here. But repo seems to be abandoned
I also got the same issue, i used setTimeout(function(){ $scope.$broadcast('reCalcViewDimensions'); },500)
Indeed, using $scope.$broadcast('reCalcViewDimensions');
is the solution. This problem is due that when the slider is instantiated, the view is not visible and so it cannot be rendered properly.
This particular problem with tabs is mentionned here: https://github.com/rzajac/angularjs-slider#slider-events . I have also experienced the issue when using a slider inside a angular-ui dropdown.
Hey guys, I am having the same issue and I tried adding $scope.$broadcast('reCalcViewDimensions'); but it didn't work. Here is live working example:
http://ec2-52-16-54-212.eu-west-1.compute.amazonaws.com/test.html
The slider is on page "2".
Am I doing anything wrong?
Please provide a Fiddle that present the strict minimum of your problem. I don't want to go visiting a random page which can contain anything (virus?)...
Sure, here is an example on Codepen: http://codepen.io/anon/pen/QbJmja
There you go: http://codepen.io/ValentinH/pen/yNQKXR?editors=001
You had several Angular-related problem:
Finally, in your example, it also works without wrapping the $scope.$broadcast('reCalcViewDimensions')
with $timeout but it depends on the step plugin sequencing. To be sure that it is always called after the view is shown, use $timeout so the broadcast is called in the next JS loop.
Awesome, thanks a lot for your help, it's much appreciated!
Per the OP's use context, and attempting the fix proposed from Jul 29, this still doesn't work.
Failing an example with tabs, I warn others about this integration!
Since I'm in a good mood today, there is your example: Slider inside Angular UI tabs: http://jsfiddle.net/7w755fLv/
I'm adding it to the doc...
Yes, that does better address it, though the rendering is triggered by tab select and I think I notice the slider's correcting action, visually.
Based on review of Angular-UI Bootstrap tab issues, I might expect challenges for the embedding of any directive in tab content panes. Therefore, my proposal to anyone (perhaps it is already familiar to most) is to confirm their chosen tab directive works with any directives planned for use in tab panes.
You will get issues with any widgets that show/hide content dynamically such as tabs, popover or even ng-show. The problem is that the directive you place inside the content, such as this slider, does not have an efficient way to detect when it becomes visible. So if this directive needs to compute the width/height/position of its parent, you will need to trigger a refresh event manually.
Hi All,
I have faced the same issue inside accordion my slider not initializing. Finally ValentinH solution guide me in right path. Below is the code.
Calling refreshSlider() in ng-click of the accordion div .
HTML:
<form name="myform">
<div class="panel-group flatPannels filterGroup" id="accordion">
<div class="panel panel-default filterStyle" ng-click="refreshSlider()">
<div class="panel-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" data-target="#collapseFour">
<h4 class="panel-title"> myslider<i class="indicator glyphicon glyphicon-chevron-down pull-right"></i></h4>
</a>
</div>
<div id="collapseFour" class="panel-collapse collapse">
<div class="panel-body">
<label class="title" ></label>
<div class="sliderInputWrapepr">
<input type="number"
placeholder="{{ 'enter' }}"
ng-change="chklim($event)"
ng-minlength="1"
ng-maxlength="3"
ng-min="aslider.floor"
ng-max="aslider.ceil"
name="inputvalMax" class="sliderinput" ng-class="{'err-txtbox':!searchFilterForm.inputvalMax.$valid}" ng-model="aslider.value1" required /><br />
</div>
<rzslider rz-slider-floor="aslider.floor"
rz-slider-ceil="aslider.ceil"
rz-slider-model="aslider.value"
rz-slider-step="1"
rz-slider-always-show-bar="true"
rz-slider-tpl-url="rzSliderTpl.html"
rz-slider-on-change="searchval();"></rzslider>
</div>
</div>
</div>
</div>
</form>
Angular:
$scope.refreshSlider = function () {
$timeout(function () {
$scope.$broadcast('rzSliderForceRender');
});
};
With ng-if works, not with ng-show
@Luddinus ng-if works but it doesn't maintain slider values after you hide and show it again.
If the slider is inside a div toggled with ng-if, it is destroyed on each hide: this is normal since ng-if destroys its content.
You need to save the slider value in the parent's scope then or in a service.
Hi Valentin, I have the same issue if you wouldn't mind taking a look, please?
https://jsfiddle.net/mjknight50/hmap4qj7/
I have tried all of the suggestions I have seen you post so far, but the initial slider position isn't setting correctly until I resize the screen or until I click on the slider.
@mjknight50 You need to send the following event when the slider becomes visible:
$scope.$broadcast('rzSliderForceRender');
I can't really help more because your example is complex and generating a lot of errors that are not linked to the slider.
Thanks Valentin... I added this, which fixed it:
angular.element(document).ready(function () {
$scope.$broadcast('rzSliderForceRender');
});
Same problem here, I have to try this solution!
2016-04-25 23:13 GMT+02:00 Matthew Knight notifications@github.com:
Thanks Valentin... I added this, which fixed it:
angular.element(document).ready(function () { $scope.$broadcast('rzSliderForceRender'); });
— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/angular-slider/angularjs-slider/issues/79#issuecomment-214523887
For the ng-show and tab problems, I have looked into this further and have a solution that gets rid of any flickering. In angularjs v1.2, the slider did not require a timeout and could be force rendered immediately. This is the breaking commit that defers ng-show until the end of the digest cycle.
So, running force render in post digest instead of JavaScript's next execution cycle (setTimeout) will get rid of any flickering (jsfiddle):
$scope.$$postDigest(function () {
$scope.$broadcast('rzSliderForceRender');
});
Also, if you want to continue using $setTimeout you should at least stop it from running digest again, since rzSliderForceRender does not require another digest:
$timeout(function () {
$scope.$broadcast('rzSliderForceRender');
}, 0, false);
Thanks, this is really interesting! I'll add it to the README 👍
I am using uib-accordion and faced this issue. The solution that works for me, is to watch the is-open variable and render rzSlider on open.
In the slider controller:
$scope.accordion1.status = false;
$scope.$watch('accordion1.status', function(isOpen){
if (isOpen) {
$scope.$broadcast('rzSliderForceRender');
console.log('accordion1 is open');
}
});
And the accordion:
<uib-accordion close-others="true">
<uib-accordion-group is-open="accordion1.status">
<uib-accordion-heading>
<span>Hello world</span>
</uib-accordion-heading>
<p>
<rzslider rz-slider-model="formData.weight" rz-slider-options="wslider"></rzslider>
</p>
</uib-accordion-group>
</uib-accordion>
EDITED: Changed $rootScope to $scope according to ValentinH's comment.
You probably don't need to broadcast on the whole $rootscope, $scope.$broadcast might be enough ;)
I got over this issue by increasing timeout delay to above 170ms.
$timeout(function () { $scope.$broadcast('rzSliderForceRender'); },170);
I think this is the rendering time taken in my case.
The issue is that the rendering time is browser dependant so it might be more on other browser/devices..
I tried any solutions but in uib-tab and uib-tabset, i have always the problem
Demo please. Btw there is an example of slider in uib-tab on the website...
Sorry but i in the demo find tab and tabset doesn't see ui-tab and ui-tabset did saw in wrong place?
This is just because the demo use on old version of ui-bootstrap where the uib- prefix wasn't mandatory. But the demo shows how to use uib-bootstrap tabs
Thank you for your help. Used this as described in the fiddle: http://jsfiddle.net/8zg6rrn2/1/
In the controller js: var vm = this; vm.refreshSlider = function () { $scope.$$postDigest(function () { $scope.$broadcast('rzSliderForceRender'); }); };
Called it from the ng-show function also in the controller js:
vm.refreshSlider();
$postDigest nor $broadcast() workarounds does not work for me. I'll try to provide fiddle someday.
No chances to make corrent rendering without such tricks?
Unfortunately no, the library can't know when it become visible (or at least not without doing some dirty-checking) so you have to tell it (I usually use $broadcast
inside a $ timeout
).
Thanks. I've double checked callback and found a typo. Sorry for disturbing.
Unfortunatelly there are too many use cases, where refreshing is required. I have a controller which gets an event probably before rendering. It is hard to know when element becomes visible (rendered by browser engine). Maybe you can control it within a directive, but a view controller can't do that without checking DOM elements directly. This makes using the slider very hard and time-consuming. You should find other solution. Just my 5cents.
A solution like this: http://stackoverflow.com/a/31085644/1713469 could be doable but it's very heavy since that means angular will check the dom at each $digest iteration! Also this answer: http://stackoverflow.com/a/1462510/1713469 summarizes what I have in mind... Your logic should be predictable so you should always know if the slider container is visible.
I'm setting scope var to make container visible and directly after that I'm calling refresh event. It does not work probably due some race condition. Unfortunatelly I have no time to dig this issue today.
HI! I am using rzslider with controllerAs syntax.
$timeout(function () {
$scope.$broadcast('rzSliderForceRender');
}, 10);
This doesnt work. how can i make it work with controllerAs syntax.
Please provide a demo showing the issue. There is no reason that using controllerAs
syntax could be a cause of this issue.
@rsrikanth080 I am using controllerAs with no problem. As @ValentinH said, if you have a more complete example, it would help.
Here is how I am doing that same block you listed:
//in theory, only one of these should be needed, to force the render, but both are needed in my testing
$timeout(function () { $scope.$broadcast('rzSliderForceRender'); }, 170);
angular.element(document).ready(function () {
$scope.$broadcast('rzSliderForceRender');
});
When do you call $timeout
? BTW, we need code to understand what you do. The best so we can help you would be to create a JSFiddle only showing the issue and the code for it.
@rsrikanth080 - Please be considerate of our time. Searching through your source code to help you isn't ideal. A JSFiddle would be better and would probably also help you by isolating the issue.
Please, I won't help you if you don't provide materials! I'm not supposed to go and read all your code, people are are contributing on their free time. If you want enterprise support, then pay somebody for that.
However, your issue is probably due to the fact the you must call rzSliderForceRender
after your popup is shown (as done on the uib-modal demo on our demo page).
I agree with @ValentinH; the issue is that when your shopService comes back with prices, you must then call rzSliderForceRender to reinitialize the slider. You can use my sample code from above to do this rendering.
Using angular-fullstack I am setting a slider with the scope value like so:
and the markup:
I am displaying the value of the slider on the page and it is correctly set to 100, but the slider position is stuck at 0 until i click on it, then it jumps up to where it's supposed to be.