0
votes

I have set up a basic boolean binding on a radio element. When a user selects the "true" radio element, it should display a div beneath it with some further options. When the view loads, I'd like to ensure that all elements that are "true" have the div's beneath displayed.

Prior to Angular, I would just two two things with jQuery:

// pseudo-ish code
$(element).on("click", function() { /* show/hide div */ });
$(element:checked).each(function() { /* show child div if val() == 'true' */}

With Angular, I needed a directive to do that. The directive does exactly what I want it to do, but it broke the data binding with the element, so the element is no longer checked if the model is set to true/false.

  1. How do I get the data binding to work again so that the "true" radio is checked, and the div shows?
  2. Any suggestions on improving this directive/code? Angular newbie here, but LOVING the framework so far!

Here's a fiddle that shows it:

http://jsfiddle.net/nloding/SLpBG/

Here's the code:

HTML:

<div ng-app="myApp" ng-controller="testController">
    <input type="radio" name="TransferControl" data-test-control required data-ng-value="true" data-ng-model="transfer" /> TRUE<br/>
    <input type="radio" name="TransferControl" data-test-control data-ng-value="false" data-ng-model="transfer" /> FALSE

    <div class="testcontrols">SHOW SOME STUFF HERE IF TRUE</div>
</div>

JS:

var myApp = angular.module('myApp', [])
    .directive('testControl', function() {
         return {
            require: 'ngModel',
            restrict: 'A',
            replace: false,
            transclude: true,
            scope: {
               enabled: "=ngModel"
            },
            link: function (scope, element) {
               if (scope.enabled && element.val().toLowerCase() === 'true') {
                  element.nextAll('div.testcontrols').first().show();
               }
                element.bind('click', function() {
                    if ( element.val().toLowerCase() === 'true') {
                        element.nextAll('div.testcontrols').first().show();
                    } else {
                        element.nextAll('div.testcontrols').first().hide();
                    }
                });
               return;
            }
         };
      });

function testController($scope) {
        $scope.transfer = true;
    }
2

2 Answers

0
votes

What you are trying to do is pretty simple and you can do that without needing to write a directive.

Replace data-ng-values with values.

Use ng-show to hide/show the contents based on the value of transfer.

<div ng-app="myApp" ng-controller="testController">
    <input type="radio" name="TransferControl" ng-model="transfer" 
    value="true"/> TRUE<br/>
    <input type="radio" name="TransferControl" ng-model="transfer" 
    value="false"/> FALSE
    <!-- compare against 'true' instead of true -->
    <div ng-show="transfer=='true'">SHOW SOME STUFF HERE IF TRUE</div>
</div>

Controller:

function testController($scope) {
    /* since attribute values in HTML are strings */
    /* $scope.transfer = true; wont work */     
    /* use a string instead */
    $scope.transfer = "true";
}
0
votes

Noob here as well but I think you might be running into the problem with using truthy or falsy values in an angular directive. The key here is that since you are using true and false as directive values, they are immediately eval'd by Angular as javascript, not as strings. Check out the ng-true and ng-false directives as shown in the second fiddle here: https://github.com/angular/angular.js/issues/2220

Good luck!