Pacuraru Daniel
Pacuraru Daniel

Reputation: 1205

directive for a toggle button

I am trying to make a directive to create an YES / NO toggle button. Now I have no idea if even my HTML layout is ok but so far I did this:

<div class="toggle" toggle-button"><input type="checkbox" ng-model="confirms" /></div>
<div class="toggle" toggle-button"><input type="checkbox" ng-model="listresults" /></div>

That's the HTML that should be added into the UI so I can use the model later on in controllers, I practically have a settings page with alot of YES / NO buttons like this example.

How I want to work is when the directive inits the button, it should show the button red or green depending on the value of the each ng-model has (if confirms = false, the button should be red, if the listresults is true the 2nd button should be green). Now when i press on the button, it should change the value of the ng-model from false to true or vice verse and should maybe add or remove an 'on' class near the toggle class so i can make a design inside it.

My full HTML for button should look like this:

<div class="toggle" toggle-button>
    <input type="checkbox" ng-model="listresults" />
    <div class="toggle-inner">
        <div class="toggle-inner-yes"></div>
        <div class="toggle-inner-no"></div>
    </div>
</div>

So far I did this, I'm not sure if my approach is correct, please let me know if you have any better idea.

myApp.directive('toggleButton', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attr) {

            // add elem
            var html = angular.element('<div class="toggled"><div class="on"></div><div class="off"></div></div>');
            elem.append(html);

            elem.bind('click', function() {
                alert('a');
            });
        }
    }
});

Right now I just added the rest of the HTML inside the button and added an click event but I have no idea how to get the value of each ng-model from input into the directive, much less change that ng-model from true to false and add or remove 'on' class on the button iteself.

I appreciate any help or advice on this.

Upvotes: 2

Views: 2706

Answers (1)

Vadim
Vadim

Reputation: 8779

You can try the following: http://plnkr.co/edit/yRWumtd7RwLksFowBRmc?p=preview

Pass model to directive via attribute. Make bidirectional binding to passed property using '=' value in the directive's scope definition. Inside your directive use ng-class directive to toggle classes on the toggle button. Use ng-click to toggle data that is bounded to outer controller's scope.

HTML

<div ng-controller="ctrl">
  <div toggle="item" ng-repeat="item in items"></div>
</div>

JavaScript

angular.module('app',[]).
  controller('ctrl', ['$scope', function($scope) {
    $scope.items = [{
      text: 'Setting 1',
      checked: false
    }, {
      text: 'Setting 2',
      checked: false
    }, {
      text: 'Setting 3',
      checked: false
    }]
  }]).
  directive('toggle', function() {
    return {
      scope: {
        toggle: '='
      },
      template: '<div ng-click="toggle.checked=!toggle.checked" ng-class="{\'toggle\':true, \'toggle-inner-yes\':toggle.checked, \'toggle-inner-no\':!toggle.checked}">{{toggle.text}}</div>',
      replace: true
    }
  });

CSS

.toggle {
  border: 1px solid silver;
  display: inline-block;
  margin: 0.5em;
  padding: 0.5em;
  color: white;
}

.toggle-inner-yes {
  background-color: green;
}

.toggle-inner-no {
  background-color: red;
}

Upvotes: 1

Related Questions