2

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>

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.