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.

We are using ASP.NET MVC and AngularJS (Newbie on Angular) and I'm really stuck with bloated html.

I have a bunch of radio button choices that are true/false but are bound to a nullable (bool?)

This works below just fine, but it's a lot of repeating code. Can it be shrunk using the wonders of Angular? (We're going to have a lot of these kinds of yes/no/no choice controls)

        <div class="rdio rdio-primary col-xs-4 col-sm-4 col-md-2 col-lg-3">
            <input type="radio"
                   name="@(Html.NameFor(x => x.IsUSAResident))"
                   id="resTrue"
                   ng-value="true"
                   required
                   ng-model="model.IsUSAResident">
            <label for="resTrue" class="pull-left">Yes</label>
        </div>
        <div class="rdio rdio-primary col-xs-4 col-sm-4 col-md-2 col-lg-3">
            <input type="radio"
                   name="@(Html.NameFor(x => x.IsUSAResident))"
                   id="resFalse"
                   ng-value="false"
                   required
                   ng-model="model.IsUSAResident">

            <label for="resFalse" class="pull-left">No</label>
        </div>
share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

Yes, you can shrink it using ng-repeat:

<div ng-init="options = [{id:'resTrue',value:true,label:'Yes'},{id:'resFalse',value:false,label:'No'}]">
    <div ng-repeat="option in options"
        class="rdio rdio-primary col-xs-4 col-sm-4 col-md-2 col-lg-3">
            <input type="radio"
                   name="@(Html.NameFor(x => x.IsUSAResident))"
                   id="{{option.id}}"
                   ng-value="option.value"
                   required
                   ng-model="model.IsUSAResident">
               <label for="{{option.id}}" class="pull-left">{{option.label}}</label>
    </div>
</div>

There are ways to improve this code further. One would be to create a controller to hold the options (to get rid of ng-init):

angular.module('myApp')
.controller('yesNoRadioCtrl',function($scope){
    $scope.options = [
        {id:'resTrue', value:true, label: 'Yes'},
        {id:'resFalse', value:false, label: 'No'}
    ];
});

The corresponding markup:

<div ng-controller="yesNoRadioCtrl">
    <div ng-repeat="option in options"
        class="rdio rdio-primary col-xs-4 col-sm-4 col-md-2 col-lg-3">
            <input type="radio"
                   name="@(Html.NameFor(x => x.IsUSAResident))"
                   id="{{option.id}}"
                   ng-value="option.value"
                   required
                   ng-model="model.IsUSAResident">
               <label for="{{option.id}}" class="pull-left">{{option.label}}</label>
    </div>
</div>

This can be made more compact and reusable with directives. Let me know if you'd like to see that.

share|improve this answer
add comment

Jonathan is right. You can save some space, with just ng-repeat'ing your radio-inputs.

Here's how you could create your own directive and implement some more radio inputs, with much smaller code:

» Demo on plunker

JS

angular.module('foobar', [])
  .controller('Controller', ['$scope', function($scope) {
    $scope.zuzu = "a value";

    $scope.bars = [
      {id:"one"},
      {id:"two"}, 
      {id:"three"}
    ];

    for(i=0;i<$scope.bars.length;i++) {
      $scope.bars[i]["name"] = 'just-a-radio-group';
    }
  }])
  .directive('myRadio', function() {
    return {
      restrict: 'E',
      scope: {
        data: '=',
        ngModel: '=ngModel'
      },
      templateUrl: 'template.html'
    };
  }); 

HTML (index.html)

<body ng-app="foobar">  
  <div ng-controller="Controller">
    <h3>{{zuzu}}</h3>
    <!-- they won't update the scope -->
    <my-radio ng-repeat="bar in bars" ng-model="zuzu" data="bar"></my-radio>

    <!-- they will update the scope -->
    <my-radio ng-model="zuzu" data="bars[0]"></my-radio>
    <my-radio ng-model="zuzu" data="bars[1]"></my-radio>
    <my-radio ng-model="zuzu" data="bars[2]"></my-radio>
  </div>
</body> 

HTML (template.html)

<div class="rdio rdio-primary col-xs-4 col-sm-4 col-md-2 col-lg-3">
    <input type="radio"
           name="data.name"
           id="data.id"
           ng-value="data.id"
           required
           ng-model="ngModel">

    <label for="data.name"
           class="pull-left"
           >
               {{data.id}}
           </label>
</div> 

Additional note, why ng-repeating the custom-directive won't update ng-model: https://github.com/angular/angular.js/issues/1913

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.