Open softdays opened 9 years ago
anyone has the same problem?
@softdays Yes, I have the same issue, and have no idea how to fix it.
@softdays & @Deliaz :
I've found a simple (but slightly non-angular) workaround for this.
First I added ng-model, but no event function specifier like ng-change or ng-click. That's just done using the "bootstrap method" (Bind JQuery change event). In my case I also removed the "checked" attr, because the switch needs to be off by default.
<input class="form-control mytoggle" data-toggle="toggle" type="checkbox" ng-model="mytogglestatus">
Next, in the controller, I just put something like the following code. In my case, the toggle switches a few options for a $http call. You need to change the "$scope.mytogglestatus" to either true or false depending on whether you included the "checked" attribute. After this, data binding works as expected*.
// At the top, where I initialize most scope vars
$scope.mytogglestatus = false;
// actual function which runs when the slider is toggled
$scope.actualtogglefunction = function(){
$scope.mytogglestatus =! $scope.mytogglestatus;
$scope.$apply();
// use toggle status in async call, or to modify elements/variables with angular, etc.
};
$('.mytoggle').change(function() {
$scope.actualtogglefunction();
};
*Edit: Just noticed it only works one way. Switching the toggle updates the scope variable, but not the other way around. Could probably use an Angular watch function, although that's getting pretty messy. Still learning about Angular myself :)
I threw this together and it seems to do the job in the most bare-bones way; https://gist.github.com/dave-newson/f6c5e9c2f3bc315e292c
Thanks @dave-newson, that seems to be a very good approach.
Still have trouble getting something like an ng-change function to trigger. I've been reading the AngularUI-bootstrap source to see if I can solve it. Something along the lines of this directive: https://github.com/angular-ui/bootstrap/blob/master/src/buttons/buttons.js Although they have a slightly different approach to toggles/checkboxes/radiobuttons, and I don't understand custom directives well enough yet to get it working. Quite educational though.
If I figure out something useful I'll let you know.
Using require: ['ngModel']
in the definition of the directive means the link function is passed the controllers specified as the 4th argument, in our case it's just ngModel.
ng-change
should be monitoring ngModel on the input element. That ngModel controller should be shared between the input, ngChange
and our toggleCheckbox
directive.
When the toggle is modified, the $element.on('change'
event is fired, which runs updateModelFromElement()
, which calls ctrl.$setViewValue(x)
.
ctrl.$setViewValue(x)
should be applying the new value of the toggle element (true/false) to the ngModel controller (ctrl
).
Finally, $scope.$apply()
prompts everything on $scope (including ngModel) to check for changes. This should trigger ngChange to fire as a result.
Can you provide a jsFiddle of this not working? We might be able to sort something out that way.
You're right, ng-change works, but I still have some trouble.
In my case, I start the toggle in the off position by setting the model variable to false at the top of the controller. Then I do a $http call to check whether a configuration is in place on the server, update the model (and hopefully the element), and use the ng-change function from that point on to enable/disable the configuration setting on the server. The toggle should server as a "live" switch, directly representing something on the server. First I thought it failed to update the element because of async/scope/digest problems.
But it actually works with a generic (non-bootstrap) checkbox when I couple it to a ng-model & ng-change callback.
This example shows the problem fairly well: http://plnkr.co/edit/NI0nMn3wGbO7NqJTndvY?p=preview
The element is updating the model, but the model doesn't seem to update the element. Well, it does when I set the scope variable initially, but not if I manipulate the model from some other place (try clicking the second checkbox -- that updates the model, but not the toggle element). The toggle updates the checkbox, but not the other way around!
Is it some one-way vs two-way data binding problem?
Thanks a lot so far! :)
Ah, thanks for the plunk, that makes it a lot easier :)
The problems turned out to be:
This is what I came up with: http://plnkr.co/edit/YyO1dQpFDnzSTLqaOllc https://gist.github.com/dave-newson/f6c5e9c2f3bc315e292c
Awesome. Just implemented it in my project, and it's working 100% as expected. Now I can easily allow people to toggle various scheduled cron jobs on the server, while keeping the visually appealing UI intact.
@minhur: If you could document this solution on www.bootstraptoggle.com, it would make it much easier for future AngularJS/Bootstrap users to find a way to implement your element.
Thanks!
Thank you for the inputs everyone. Sorry I haven't been much help, I don't have enough experience with angular to offer insight in the matter. I'll update the doc with a reference to this discussion for future users.
@dave-newson Is it possible to get the value of the toggle (checked/unchecked status) in the event '$scope.toggleschedule'? If yes, can you please let me know. I'm using this control in a very different way and would require the new value of the control in the event.
I don't know why but when I use the control in a grid, the toggle event is fired multiple times. Any thoughts you guys can share?
@sagar-ag05 Can you provide a fiddle which replicates this?
Hi Dave,
Unfortunately I'd spent considerable time on this and failure to get it working, I made a custom directive on my own which exposes an event (using $emit) and was able to achieve the same feat as the toggle control.
I'm sorry as I couldn't provide the jsFiddle. I was trying to use this control in Kendo-Angular's grid control. With the custom directive, my code is working perfectly. If I get a chance in future to create a fiddle, I will share with you.
@sagar-ag05 as a directive to bootstrap-toggle? If it was useful to you it might be useful to others, perhaps throw it up as a gist and then we can at least see the differences in our approach?
@dave-newson : No, not as a directive to bootstrap-toggle but a totally new directive created from scratch. This new directive has div's and span's to give it a look of Toggle button (using CSS) and a click event within the directive. Inside the click event, I do $emit which my parent scope is listening. Also, I toggle the value between true and false and switch between CSS classes to give it a toggle like effect.
@sagar-ag05 .. Oh. If you look at the second plunker (http://plnkr.co/edit/YyO1dQpFDnzSTLqaOllc), there's an ng-change callback on the input using the directive. Currently it just fires a console.log(). From the sound of things, you could use the ng-change callback to run code in the controller, or you could fire an $emit from there if you want to push an event up the controller scope. I'm not sure I'm seeing the problem?
or https://github.com/frapontillo/angular-bootstrap-switch seems promising
how it should render: http://www.bootstrap-switch.org/examples.html
Really strange, I forked the plunker to upgrade the libraries given my code used newer angular and such. http://plnkr.co/edit/W1FalJqVBX7uf1txENfF?p=preview
It works in the plunker, but for some reason in my real app the $scope.schedule
model is not being updated and I can't figure out why. I cropped the directive right from the example.
Any insight? When I debug the directive, the call to ngModel.$setViewValue(checked);
triggers the watch, not sure if that's the issue. But again, it works in the Plunker, so I'm stumped.
Wondering if @dave-newson or anyone else has ideas on how to debug? Could there be another $watch
somewhere screwing things up?
Solved it. I had some nested scope and wasn't using controllerAs
syntax. All good.
I extended the Plunk that @dave-newson made. Data attributes are now passed thru.
How would I be able to apply this directive on checkbox within a ui-grid?
I'm trying to use bootstrap-toggle with AngularJs:
But when the toggle state changes the Angular model is not updated.