Set a checkbox in a ng-repeat to checked by default - angularjs

I have the below checkbox that is in a ng-repeat where this should always be checked by default. The issue that I am running into is that I can set it to checked at the controller scope but not at the item (perf) scope. So if I set it at the controller scope, if you unchecked it, all of the items (perfs) unchecked. BTW, from all of the examples that I have come across show the checkbox being initially checked based on a value in the item array which I don't have.
<div ng-repeat="(perf) in $ctrl.filteredPerfs">
<div class="row">
<div class="pull-right cs-fg" ng-class="{'hidden': perf.showContigSeats == 'N'}">
<md-input-container class="cs_ic">
<span>
<md-checkbox md-block class="ada-reserve" ng-model="perf.resTkts"></md-checkbox>
</span>
<span class="cs-ada-label">Only reserve tickets next to each other</span>
</md-input-container>
</div>
</div>
</div>

Solution 1
Initialize perf.resTkts as true:
<md-checkbox md-block ng-model="perf.resTkts" ng-init="perf.resTkts = true"></md-checkbox>
Solution 2
Use ng-checked:
<md-checkbox md-block ng-model="perf.resTkts" ng-checked="true"></md-checkbox>

ng-checked : If this expression evaluates as truthy, the 'md-checked' css class is added to the checkbox and it will appear checked
<md-checkbox md-block class="ada-reserve" ng-checked="perf.resTkts" ng-model="perf.resTkts"></md-checkbox>
set perf.resTkts = true for default
<md-checkbox md-block class="ada-reserve" ng-checked="true" ng-model="perf.resTkts"></md-checkbox>

Related

Angular - ngClass being added to each clicked radio button (instead of ONLY clicked one)

In my angular app I'm using ng-repeat to generate several radio buttons, the ultimate goal is to add a choiceSelected class (ngClass colour styling) to the label of the clicked radio input. I can add the style to the clicked button, BUT that style is added to every other clicked radio button and I end up with 5 coloured labels. Can't understand why.
Here is the HTML code:
<div class="row" ng-repeat="obj in questionObject.choices">
<div class="radio">
<label class="choice" ng-class="{'choiceSelected': isChecked==$index}">
<input type="radio" name="optradio" ng-model="isChecked" ng-value="$index" ng-click="selectAnswer($index,questionObject)">{{obj.body}}</label>
</div>
</div>
<div class="row" ng-repeat="obj in questionObject.choices">
<div class="radio">
<label class="choice" ng-class="{'choiceSelected': isChecked==$index}">
<input type="radio"
name="optradio"
/*********************************************/
ng-model="isChecked"
ng-value="$index"
/*********************************************/
ng-click="selectAnswer($index,questionObject)">{{obj.body}}
</label>
</div>
</div>
Look at the lines inside the comments, clearly tells that your value of the checkbox($index) is binding to the isChecked variable.
By your, condition in ng-class isChecked==$index it is same for all the elements and so the class is applied for all radio buttons.
if you can update the Json of questionObject , can give you alternative option.
Assuming that questionObject contains the following json
[{
"body": "abc"
}, {
"body": "def"
}, {
"body": "aghi"
} ]
You can use the below code to make your result achieve
<div class="row" ng-repeat="obj in questionObject track by $index" >
<div class="radio" >
<label class="choice"
ng-class="{'choiceSelected': isChecked==$index}">
<input type="radio"
name="optradio"
ng-value="obj.body"
ng-click="selectAnswer($index,obj)">
{{obj.body}}
</label>
</div>
The method selectAnswer should make your work simple. Use this
$scope.selectAnswer=function(number,obj)
{
$scope.isChecked=number;
}
LIVE DEMO
NOTE: In your code the selectAnswer method call in HTML passes the
questionObject fully
Update 1
Reason for manually defining isChecked
Angular looks for the the value of isChecked in the scope because you have used ng-class in the

md-select not binding to the object referenced by ng-model

I have a form with some md-select dropdowns which im trying to bind with a scope object in my angular controller.
The html looks like that :
<div id="horizontal_form_category" class="row">
<div class="col-md-2 col-lg-2" data-ng-repeat="r in categories[general]" dir="rtl">
<md-input-container>
<label> {{ r.name }} </label>
<md-select ng-model="formObject[r.name]" class="md-no-underline">
<md-option ng-repeat="option in r.values" ng-value="option "> {{ option }} </md-option>
</md-select>
</md-input-container>
</div>
</div>
The controller has a definition of the object $scope.formObject = {}; (Although it should work without it)
But, unfortunately, the $scope.formObject object in my controller stays empty.
Any ideas what could cause such weird behavior ? I have some normal bootstrap components whom ng-model is written the same and are working just fine.
Thanks
Does this help in any way? - CodePen
The true as the last parameter for $watch checks for changes in the object formObject.
Markup
<div ng-controller="AppCtrl" ng-cloak="" ng-app="MyApp">
<md-input-container>
<label> Options </label>
<md-select ng-model="formObject['Options']" class="md-no-underline">
<md-option ng-repeat="option in options" ng-value="option "> {{ option }} </md-option>
</md-select>
</md-input-container>
</div>
JS
angular.module('MyApp',['ngMaterial'])
.controller('AppCtrl', function($scope) {
$scope.options = ["Earth", "Saturn", "Jupiter"];
$scope.$watch("formObject", function () {
console.log($scope.formObject);
}, true)
});
Apparently there wasnt any bug.
My form's md-select were empty and therefore the formObject was empty.
The minute I started puting values, the formObject got filled, one field at a time, containing only the fields that were set.
I added a default value and everything is now showing correctly, just to be sure this was the "bug".
In retrospect, this bevahiour actually saves me some lines of code so I adopted it :)
Gotta thank #camden_kid answer for the $watch tip, helped me figure it out in matter of seconds.

angular ng-options does not render the right value in IE 11

I have two dropdowns with ng-options. One for displaying primary brokers and other for secondary brokers.
The Mark-up is as follows:-
<div class="col-md-4">
<div class="form-group">
<label>Primary Broker: </label>
<button type="button" class="btn-help" tabindex="-1" data-popover="" data-content="Lead JLL broker for the opportunity">
<span class="circle-help">?</span>
</button>
<select class="form-control"
ng-options="jllContact.JllUserId as jllContact.Name for jllContact in controller.primaryJllBrokers"
ng-model="controller.primaryJllContactId"
id="primaryJllContact" data-field='{"name": "Primary Broker", "attribute": "PrimaryJllContact"}'
ng-change="controller.setPrimaryJllContact()"
ng-class="{'req': controller.data.isFieldRequired('PrimaryJllContact'), 'has-error': controller.data.isFieldValid('PrimaryJllContact') == false}"
ng-disabled="!controller.isEnabled('JllContacts')||!controller.canEditBrokerAllocation()">
<option value="">Select Primary Broker</option>
</select>
</div>
</div>
#* Secondary Broker*#
<div class="col-md-4">
<div class="form-group">
<label>Secondary Broker: </label>
<button type="button" class="btn-help" tabindex="-1" data-popover="" data-content="Secondary JLL broker for the opportunity">
<span class="circle-help">?</span>
</button>
<select class="form-control"
ng-options="jllContact.JllUserId as jllContact.Name for jllContact in controller.secondaryJllBrokers"
ng-model="controller.data.SecondaryJllContactId"
id="secondaryJllContact" data-field='{"name": "Secondary Broker", "attribute": "SecondaryJllContact"}'
ng-change="controller.handleSecondaryJllContactChange()"
ng-class="{'req': controller.data.isFieldRequired('SecondaryJllContact'), 'has-error': controller.data.isFieldValid('SecondaryJllContact') == false}"
ng-disabled="!controller.isEnabled('JllContacts')||!controller.canEditBrokerAllocation()">
<option value="">Select Secondary Broker</option>
</select>
</div>
When I change the secondary broker, as seen in the markup I call a method called
handleSecondaryJllContactChange. The method is as follows.
handleSecondaryJllContactChange:()=>
primaryJllContactId = this.primaryJllContactId
this.refreshPrimaryBrokers((primaryBrokers)=> this.primaryJllContactId = primaryJllContactId)
refreshPrimaryBrokers:(callback)->
this.primaryJllBrokers = _.where(this.data.JllContacts, (jllc)=> jllc.Role.ID == 21 && jllc.JllUserId != this.data.SecondaryJllContactId)
if callback? && callback!= undefined && this.primaryJllBrokers!=null && this.primaryJllBrokers != undefined
callback(this.primaryJllBrokers)
As seen from the code, we are setting the ng-model "controller.primaryJllContactId" for the first drop down after the collection controller.primaryJllBrokers has been refreshed.
However, the drop down still shows instead of the correct option in IE 11.
NOTE:
On examining the console, we did notice that ng-model for the first
dropdown controller.primaryJllContactId has the right value. It just
doesn't display correctly in the drop down.
This is happenning only in IE 11. It works perfectly in chrome.
Couple of things we have tried:-
Instead of ng-change="controller.handleSecondaryJllContactChange()" in the second dropdown we tried to have a watch on controller.secondaryJllBrokers
and call the method controller.handleSecondaryJllContactChange().
The second route which we took was based on the assumption that we are setting the ng-model before options are rendered. Hence we took the $timeout
approach. In the handleSecondaryJllContactChange() method shown above we did this in the second line:-
this.refreshPrimaryBrokers((primaryBrokers)=> this.$timeout(=> this.primaryJllContactId = primaryJllContactId))
None of these two approaches worked. Any ideas why this is happening and what is the way to know when options have finished rendering.
Thanks in Advance !!!!

Radio button checked by default when using ng-repeat

I have been wanting to have a radio button checked out of a list of radio buttons that I present in the screen using ng-repeat, but my code does not work. This is what I am doing:
<div class="clubRole" data-ng-if="club.checked">
<div data-ng-repeat="role in securityGroups.slice(0,1)">
<input type="radio" class="clubRole" data-ng-model="club.role" data-ng-value="role.securityGroupCode" checked="checked"> {{role.description}}
</div>
<div data-ng-repeat="role in securityGroups.slice(1,securityGroups.length+1)">
<input type="radio" class="clubRole" data-ng-model="club.role" data-ng-value="role.securityGroupCode"> {{role.description}}
</div>
</div>
The intention of the code is to get the first radio button checked, and the others unchecked. That code has a problem: it does not work. But at least it gives the idea of what I am trying to do: I want one of the radio buttons checked by default, no matter which one it is.
Radio button will be check if the value of the input attribute is equal to the value of modal applied on the radio button.
<div ng-repeat="val in ['a','b','c']">
<input
type="radio"
name="val"
data-ng-model="role"
data-ng-value="val"
ng-init="$index==0?(role=val):''"
/>
{{val}}
</div>
Checked="checked" will not work in angular context. You can either set the value of radio button explicitly in controller or you can manage it in the view itself as i did in the above example.But the modal should be equate according to the value attribute on the inmput element.
For example if modal is x on three radio button's and each radio button have different value like a,b and c. then x must be equal to any of the value to be checked.
Plunker
You don't need to worry about checked.
HTML:
<div ng-app="app">
<div ng-controller="mainController">
<label ng-repeat="option in options">
<input type="radio" ng-model="$parent.selected" ng-value="option"/>{{option}}
</label>
</div>
</div>
JavaScript:
var appModule = angular.module('app', []);
appModule.controller('mainController', function($scope) {
$scope.selected = 'red';
$scope.options = ['red', 'blue', 'yellow', 'green'];
});
Working fiddle here: https://jsfiddle.net/qnw8ogrk/1/
You don't need checked="checked", I think angular will take care of it itself if you set the model to one of the values. Something like:
club.role = securityGroups.slice(0,1)[0].securityGroupCode;
Also, the scope may trip you up here, the model may have to be $parent.club.role
if you use a primitive type in list, the answer of bm1729 is correct, but if you use objects in the list, then look this example: https://jsfiddle.net/9chd58mk/2/
the first part is bad, because the selected object is look like same with a list item, but it doesn't same by reference. the == operator is false in this case
$scope.selected = {c:'red'};
$scope.options = [{c:'red'}, {c:'blue'}, {c:'yellow'}, {c:'green'}];
but the second and third examples are use the list item reference, and the radio button checked. the == operator is true in this case
$scope.options3 = [{c:'red'}, {c:'blue'}, {c:'yellow'}, {c:'green'}];
$scope.selected3 = $scope.options3[0];
<md-radio-group ng-model="data.group3">
<md-radio-button value="{{o._id}}" class="md-primary" ng-repeat="o in lstDataRecord" ng-click="updTemplateId(o._id)">
<div flex-gt-sm="50" style="height: 150px; width: 250px;">
<img src="{{PageInfo_PATH}}{{o.imgUrl}}" />
{{o.displayName}}
</div>
</md-radio-button>
<md-radio-button value="active" class="md-primary" [checked]='true'> </md-radio-button>
</md-radio-group>

AngularJS bind class attribute to model

I have the following markup:
<div ng-app="app" ng-controller="Ctrl">
<label ng-repeat="role in roles">
<div ng-class="{ big: selectedRoles }">
<input type="checkbox" checklist-model="selectedRoles" checklist-value="role.id" />{{role.text}}</div>
</label>
</div>
I need the class "big" to be set to checked items. The ng-class attribute is not working as expected. Replicated problem in http://jsfiddle.net/qky1ownh/1/.
If you don't want to keep stuffing logic in your view, you could use an object literal to track the changes to the list instead.
$scope.selectedRoles = {
1: true,
2: true,
4: true
};
It allows you to just use ng-model on your checkboxes as well instead of some funky checkbox-list/value type stuff:
<div ng-class="{ big: selectedRoles[role.id] }">
<input type="checkbox" ng-model="selectedRoles[role.id]" />{{role.text}}
</div>
Updated fiddle:
http://jsfiddle.net/qky1ownh/8/
Since selectedRoles is an array of role ids you could just use array.indexOf to find if it in the selected list:-
<div ng-class="{ big: selectedRoles.indexOf(role.id)+1 }">
Since indexOf returns the item's index in the array(zero-based) and -1 when not found just add-up 1 to make it falsy.
Or just add a method in your controller to keep out any logic from the view and the fact that controllers are better testable than template, do :
controller:-
$scope.hasRole = function(id){
return $scope.selectedRoles.indexOf(id) > -1;
}
and use it in the view as:
<div ng-class="{ big: hasRole(role.id) }">
Another option is to apply a selected property to the object.
Fiddle: http://jsfiddle.net/7kfum1uu/
<div ng-class="{ 'big': role.selected }">
<input type="checkbox" ng-model="role.selected">{{role.text}}
</div>

Resources