Integration of Angular and JQuery.iCheck by using a directive is not working
13,857
Solution 1
Already solved on this link: https://github.com/fronteed/iCheck/issues/62 by wajatimur
webApp.directive('icheck', function($timeout, $parse) {
return {
require: 'ngModel',
link: function($scope, element, $attrs, ngModel) {
return $timeout(function() {
var value;
value = $attrs['value'];
$scope.$watch($attrs['ngModel'], function(newValue){
$(element).iCheck('update');
})
return $(element).iCheck({
checkboxClass: 'icheckbox_flat-aero',
radioClass: 'iradio_flat-aero'
}).on('ifChanged', function(event) {
if ($(element).attr('type') === 'checkbox' && $attrs['ngModel']) {
$scope.$apply(function() {
return ngModel.$setViewValue(event.target.checked);
});
}
if ($(element).attr('type') === 'radio' && $attrs['ngModel']) {
return $scope.$apply(function() {
return ngModel.$setViewValue(value);
});
}
});
});
}
};
});
Solution 2
With the code from XaReSx answer I had one issue : When updating the model from the scope the radio doesn't changed. I had to add a timeout in the model watch :
$scope.$watch($attrs['ngModel'], function (newValue) {
$timeout(function () {
$(element).iCheck('update');
})
})
Related videos on Youtube
![Canttouchit](https://i.stack.imgur.com/wFt9n.jpg?s=256&g=1)
Author by
Canttouchit
Updated on June 28, 2022Comments
-
Canttouchit about 2 years
I'm trying to integrate JQuery.iCheck (plugin for
checkbox&Radio buttons
styling). I followed few suggestions here that said that the way to integrate a jQuery plugins to be fully compatible with AngularngRepeat
is by usingdirectives
.So I implemented a
directive
:webApp.directive('icheck', function($timeout, $parse) { return { link: function($scope, element, $attrs) { return $timeout(function() { var ngModelGetter, value; ngModelGetter = $parse($attrs['ngModel']); value = $parse($attrs['ngValue'])($scope); return $(element).iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal-grey', checkboxClass: 'icheckbox_minimal-grey', increaseArea: '20%' }).on('ifChanged', function(event) { if ($(element).attr('type') === 'checkbox' && $attrs['ngModel']) { $scope.$apply(function() { return ngModelGetter.assign($scope, event.target.checked); }); } if ($(element).attr('type') === 'radio' && $attrs['ngModel']) { return $scope.$apply(function() { return ngModelGetter.assign($scope, value); }); } }); }); } }; });
This
directive
does not fully work with myngRepeat elements
and does not change the properties of theobject
vote
.My code:
var webApp = angular.module('webApp', []); //controllers webApp.controller ('VotesCtrl', function ($scope, Votes) { $scope.votes = Votes; $scope.statuses = ["Approved","Pending","Trash","Spam"]; $scope.selectedID = 1; $scope.expand = function(vote) { console.log("show"); $scope.vote = vote; $scope.selectedID = vote.id; }; $scope.change = function() { for(var i = 0; i < $scope.votes.length; i++) { if($scope.votes[i].cb) { $scope.votes[i].status = $scope.votes.status; $scope.votes[i].cb = false; } $scope.show = false; } }; }); //services webApp.factory('Votes', [function() { //temporary repository till integration with DB this will be translated into restful get query var votes = [ { id: '1', created: 1381583344653, updated: '222212', ratingID: '3', rate: 5, ip: '198.168.0.0', status: 'Pending', userIdentification:'IP-ADDRESS' }, { id: '111', created: 1381583344653, updated: '222212', ratingID: '4', rate: 5, ip: '198.168.0.1', status: 'Spam', userIdentification:'FLASH-COOKIES' }, { id: '2', created: 1382387322693, updated: '222212', ratingID: '3', rate: 1, ip: '198.168.0.2', status: 'Approved', userIdentification:'HTTP-COOKIES' }, { id: '4', created: 1382387322693, updated: '222212', ratingID: '3', rate: 1, ip: '198.168.0.3', status: 'Spam', userIdentification:'IP-ADDRESS' } ]; return votes; }]); webApp.directive('icheck', function($timeout, $parse) { return { link: function($scope, element, $attrs) { return $timeout(function() { var ngModelGetter, value; ngModelGetter = $parse($attrs['ngModel']); value = $parse($attrs['ngValue'])($scope); return $(element).iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal-grey', checkboxClass: 'icheckbox_minimal-grey', increaseArea: '20%' }).on('ifChanged', function(event) { if ($(element).attr('type') === 'checkbox' && $attrs['ngModel']) { $scope.$apply(function() { return ngModelGetter.assign($scope, event.target.checked); }); } if ($(element).attr('type') === 'radio' && $attrs['ngModel']) { return $scope.$apply(function() { return ngModelGetter.assign($scope, value); }); } }); }); } }; });
My HTML:
<body ng-controller="VotesCtrl"> <div> <ul> <li class="check" ng-click=""> <input type="checkbox" ng-model="master" /> </li> <li class="created"> <a>CREATED</a> </li> <li class="ip"> <b>IP ADDRESS</b> </li> <li class="status"> <b>STATUS</b> </li> </ul> <ul ng-repeat="vote in votes"> <li class="check"> <input type="checkbox" ng-model="vote.cb" ng-checked="master" /> </li> <li class="created" ng-class="{selected: vote.id == selectedID}"> <a href="#" ng-click="expand(vote)">{{vote.created|date}}</a> </li> <li class="ip"> {{vote.ip}} </li> <li class="status"> {{vote.status}} </li> </ul> </div> <br /> <br /> <div class="details" ng-init="expand(votes[0])"> <h3>Details:</h3> <div>DATE: {{vote.created | date}}</div> <div>IP: {{vote.ip}}</div> <div > Cookies: <div> <input icheck type="radio" ng-model="vote.userIdentification" name="iCheck" value="FLASH-COOKIES" /> <span>FLASH COOKIES</span> </div> <div> <input icheck type="radio" ng-model="vote.userIdentification" name="iCheck" value="HTTP-COOKIES" /> <span>HTTP COOKIES</span> </div> <div> <input icheck type="radio" ng-model="vote.userIdentification" name="iCheck" value="IP-ADDRESS" /> <span>IP ADDRESS</span> </div> </div> </div> </body>
-
jcuenod about 9 yearsJust for reference, the issue you cite has continued discussion so it's worth checking back there rather than just copy/pasting this answer.
-
CESCO over 6 yearsthis solved a problem I had using iCheck when upgrading an existing code base from es5 to es6