Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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;
    }
share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

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";
}
share|improve this answer
    
I'd prefer to keep $scope.transfer as a boolean, not a string, due to what happens later when the form is submitted. With that setup, this scenario doesn't work (unless I'm still missing something). –  Nathan Loding Aug 25 '13 at 0:17
    
At this point, Angular won't play nice with my booleans, so this is the answer. Here's an updated fiddle for reference: jsfiddle.net/nloding/SLpBG/5 –  Nathan Loding Aug 26 '13 at 14:01
add comment

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!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.