14

I'm trying to create a simple twitter bootstrap button group that allows the user to select one of several options (think radio buttons). I've got it to a point where it's affecting changes on the model, but the "active" state is not properly being set onclick...unless I click it a second time?? I've created a fiddle and the basic markup follows...

<div range="justified"
    model="myModel"
    options="rangeOptions"></div>
<hr/>
<div range="vertical"
    model="myModel"
    options="rangeOptions"></div>
<hr/>

<pre>myModel:{{myModel}}</pre>

<script type="text/ng-template" id="range.tpl.html">
    <div class="btn-group btn-group-{{type}}" data-toggle="buttons">
        <span class="btn btn-lg btn-primary"
            ng-repeat="option in options"
            ng-class="{active:option.id==model.range_id}" <!-- not working?? -->
            ng-click="activate(option.id)">{{option.label}}</span>
    </div>
</script>
function Main($scope) {
    $scope.rangeOptions = [
        {id:1,label:"Agree"},
        {id:2,label:"Neutral"},
        {id:3,label:"Disagree"}
    ];
    $scope.myModel = {range_id: 2};
}
angular
    .module('range', [])
    .directive('range', function () {
        return {
            replace: true,
            scope: { type:'@range', model:'=', options:'=' },
            templateUrl:'range.tpl.html',
            controller: function ($scope,$element,$attrs) {
                $scope.activate = function (option) {
                    $event.preventDefault();
                };
            }
        };
    });
1

5 Answers 5

27

You don't need 90% bootstrap js to get things like this to work all you need to do is make a button group and attach some ng-clicks to it and ng-class to it:

function myscope($scope) {
  $scope.button = 'red';
}

<div class="btn-group">
    <a href="javascript:void(0)" ng-click="button = 'red'" ng-class="{ 'active' : button == 'red' }" class="btn">red</a>
    <a href="javascript:void(0)" ng-click="button = 'blue'" ng-class="{ 'active' : button == 'blue' }" class="btn">blue</a>
    <a href="javascript:void(0)" ng-click="button = 'green'" ng-class="{ 'active' : button == 'green' }" class="btn">green</a>
</div>
Sign up to request clarification or add additional context in comments.

3 Comments

Yeah, seems I was over thinking it a bit ;) Thanks!
Pure swag -> <div class="btn-group" ng-init="button = 'red'"> insteda dis -> function myscope($scope) {$scope.button = 'red';}
@AndrewM correct you could do ^ but some would argue best practice is to keep application logic out of the DOM as much as humanly possible. My rule of thumb is: Put it in the controller if you can. That way you're not having to crawl through templates to change it someday. So a better solution would be to have ng-init call a function that changes the prop.
8

There is some additional info here on making your button group work as radio buttons.

http://getbootstrap.com/javascript/#buttons

Using that info, I forked your Fiddle and this appears to be working.

http://jsfiddle.net/puatj/

The change was just to switch your span element to a label/input.

<div class="btn-group btn-group-{{type}}" data-toggle="buttons">
    <label class="btn btn-lg btn-primary"
        ng-repeat="option in options"
        ng-class="{active:option.id==model.range_id}"
    ng-click="activate(option.id)"><input type="radio"></input>{{option.label}}</label>
</div>

Comments

4

If you don't mind giving up a little bit of the snazzy bootstrap styling, you can fix this by simply taking out the data-toggle tag

<div ng-app>
<h1>{{color}}</h1>
<form>
    <div>
        <label>Select a Color</label>
    </div>
    <div class="btn-group">
        <label class="btn btn-primary">
            <input type="radio" name="color" data-ng-model="color" value="'red'"> Red
        </label>
            <label class="btn btn-primary">
        <input type="radio" name="color" data-ng-model="color" value="'green'"> Green
            </label>
        <label class="btn btn-primary">
            <input type="radio" name="color" data-ng-model="color" value="'blue'"> Blue
        </label>
        <label class="btn btn-primary">
            <input type="radio" name="color" data-ng-model="color" value="'black'"> Black
        </label>
        <label class="btn btn-primary">
            <input type="radio" name="color" data-ng-model="color" value="'orange'"> Orange
        </label>
    </div>
</form>
</div>

You can find the JSFiddle here.

1 Comment

I'm trying to do the same thing but want the SNAZZ! Has anyone figured out how to get AngularJS to work with the toggle buttons?
3

Leave out data-toggle="buttons" from the parent div and add a class or style in the inputs that set the properties width: 0px and visibility: hidden.

To display the buttons as active, use ng-init, ng-click, and ng-class to toggle active classes.

<label>Location</label><br/>
<div class="btn-group" ng-init="selectedButton = 'all'">
            <label class="btn btn-default active" ng-class="{'active':selectedButton === 'all'}" ng-click="selectedButton = 'all'">
               <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="all" ng-model="filterData.locations" checked style="visibility:hidden; width:0px;" > All Locations
            </label>
            <label class="btn btn-default" ng-class="{'active':selectedButton === 'boroughs'}" ng-click="selectedButton = 'boroughs'">
               <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="boroughs" ng-model="filterData.locations" style="visibility:hidden; width:0px;" > Boroughs
            </label>
            <label class="btn btn-default" ng-class="{'active':selectedButton === 'depots'}" ng-click="selectedButton = 'depots'">
               <input type="radio" name="inlineRadioOptions" id="inlineRadio3" value="depots" ng-model="filterData.locations" style="visibility:hidden; width:0px;" > Depots
            </label>
</div>

Comments

0

I found the angular way of handling this, directly from an array in your controller.

<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-tertiary" ng-class="{active: availableOption === searchFieldsContent.searchOption}" ng-repeat="availableOption in searchOptions">
        <input type="radio" name="searchOption" id="searchOption{{$index}}" ng-model="searchFieldsContent.searchOption" ng-value="availableOption">{{availableOption.name}}</input>
    </label>
</div>

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.