I'm currently experimenting with Angular and I have an issue, I have a set of questions from my API, some of them rely on other ones to be checked as yes when its a radio button question and will have a value in the property called ReliesOnID.
Once I check yes, the question which relies on the current one being checked needs to show.
I come from a jQuery background so I would do a function passing in the reliesonid as that will be the question number and do something like $('#question' + reliesonid').show().
How can I make the radio buttons show the other question when I click yes as they are in a repeat? Been stuck on this for ages so help is greatly appreciated. Here is my code below:
<div id="question{{question.Number}}" ng-repeat="question in questions" ng-class="question.ReliesOnID == null ? 'here' : 'hidden'">
<div ng-if="question.QuestionTypeID == 3" >
<div class="row">
<div class="col-xs-12">
<h5>{{question.Question}}</h5>
</div>
</div>
<div class="row">
<div class="col-xs-2">
<div class="col-xs-4"></div>
<div class="col-xs-8">
<input type="radio" value="yes" name="{{question.Number}}" /><label>Yes</label>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2">
<div class="col-xs-4"></div>
<div class="col-xs-8">
<input type="radio" value="no" name="{{question.Number}}" /><label>No</label>
</div>
</div>
</div>
</div>
<div ng-if="question.QuestionTypeID == 1">
<div class="row">
<div class="col-xs-12">
<h5>{{question.Question}}</h5>
</div>
</div>
<div class="row">
<div class="col-xs-4">
<input type="text" class="form-control" />
</div>
</div>
</div>
</div>
EDIT: Data structure is:
{
"Active": true,
"Comments": false,
"DecimalPlaces": 0,
"F": false,
"FP": false,
"Grouped": null,
"ID": 20500,
"Length": false,
"MP": true,
"Multiline": false,
"Number": 45,
"NumericOnly": false,
"Optional": false,
"Question": "How long ago was the treatment?",
"QuestionID": 45,
"QuestionSectionID": 2,
"QuestionTypeID": 2,
"QuestionnaireID": 298,
"ReliesOnAnswer": true,
"ReliesOnID": 44,
"Weight": false
}
You need to use ng-model for your answers like:
<input type="radio" value="yes" ng-model="question.Answer" name="{{question.Number}}"/><label>Yes</label>
And then inside that question you could have sub questions and would just use ng-repeat.
ng-if="question.subQuestions && question.Answer !== undefined" ng-repeat="subquestion in question.subQuestions"
This will all depends on your question structure of course
EDIT
Based on your structure I would say you need an ng-if in your ng-repeat that could go something like this:
ng-if="!question.ReliesOnID || wasAnswered(question.ReliesOnID)"
In wasAnswered function you would need access to the questions array and filter for that ID and check if it was answered and return true or false
Try this snippet.
Is it something, you're looking for?
I tried to understand your question, and created an example based on your JSON data structure.
Based on the selection of particular question, it will show it's answer only.
Edit-1 : Applied Angular Element
If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or jqLite.
More information angular.element
You can do eliminate jQuery from code, if you want.
You can do the set / get class in Angular by using angular.element as shown over here.
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.questions = [
{
"Active": true,
"Comments": false,
"DecimalPlaces": 0,
"F": false,
"FP": false,
"Grouped": null,
"ID": 20500,
"Length": false,
"MP": true,
"Multiline": false,
"Number": 45,
"NumericOnly": false,
"Optional": false,
"Question": "How long ago was the treatment?",
"QuestionID": 45,
"QuestionSectionID": 2,
"QuestionTypeID": 2,
"QuestionnaireID": 298,
"ReliesOnAnswer": true,
"ReliesOnID": 10,
"Weight": false,
"Answer": '2 years ago'
},
{
"Active": true,
"Comments": false,
"DecimalPlaces": 0,
"F": false,
"FP": false,
"Grouped": null,
"ID": 20500,
"Length": false,
"MP": true,
"Multiline": false,
"Number": 45,
"NumericOnly": false,
"Optional": false,
"Question": "Who is God of cricket?",
"QuestionID": 45,
"QuestionSectionID": 2,
"QuestionTypeID": 2,
"QuestionnaireID": 298,
"ReliesOnAnswer": true,
"ReliesOnID": 20,
"Weight": false,
"Answer": 'Sachin Tendulkar'
}
]
//Function when radio button clicked
$scope.flagChange = function(){
var reliesId = angular.element(event.target).attr('data-reli-id');
var value = angular.element(event.target).attr('data-value');
//Based on the condition it will show / hide the respective element
if(value == "yes")
{
$('#'+reliesId).removeClass('hide').addClass('show');
}
else
{
$('#'+reliesId).removeClass('show').addClass('hide');
}
}
}]);
.show
{
display: block;
}
.hide
{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="GreetingController">
<div ng-repeat="question in questions track by $index">
{{question.Question}}
<input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="yes" data-reli-id='{{question.ReliesOnID}}' />Yes
<input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="no" data-reli-id='{{question.ReliesOnID}}' />No
<span ng-show="custom_$index">{{question.Answer}}</span>
<br/>
<div id="{{question.ReliesOnID}}" class="hide">
Question based on ReliesOnID : {{question.ReliesOnID}}
</div>
<br/>
</div>
</div>
I dont like to use ng-if as that adds and removes the elements to the DOM. Below is a link to the ng-show/hide and a tutorial on how to use it on scotch.io.
https://docs.angularjs.org/api/ng/directive/ngShow
https://scotch.io/tutorials/how-to-use-ngshow-and-nghide
So a quick example would be below where the div element will only show when the variable is_active is true(this check can work with booleans or a text check). And this variable can be set in the controller or in the view. You dont need to toggle this. The div will automaticall hide when the evaluation is not true; so no need for a ng-hide and ng-show on the same element unless you are checking against multiple conditions.
<input type="radio" ng-model="question.subQuestion" value="true"> <br/>
<input type="radio" ng-model="question.subQuestion" value="false"> <br/>
<div ng-show="question.subQuestion">
// Your subQuestion code comes here
</div>
Edit: based on comments below and provided data structure:
If assumed that you want to iterate just that questions which are parent and doesn't related on anything at start. Related should be display only when ratio is set on true:
So replace yourng-repeat with ng-repeat-start which will make you able iterate multiple divs not just on where ng-repeat is on.
In your <div> element add :
<input type="radio" ng-model="question.subQuestion" value="true"> <br/>
<input type="radio" ng-model="question.subQuestion" value="false"> <br/>
After that make another <div> below which will display your related questions. It can looks like:
// ng-if here to display only when radio was set to true
<div class="relatedQuestion" ng-repeat-end ng-if="question.subQuestion">
<div ng-repeat="relatedQ in getRelatedQuestion(question.Number)">
// Here you display your related questions
</div>
</div>
So in your controller you need to add a function:
function getRelatedQuestion(number) {
// logic comes here which filter question
// which have property relatedOnId === number;
// it should be an array of objects to iteratee over it.
}
What you present as an option from JQUERY is possible in angular as well.
However there is prolly even easier solution.
In your ng-repeat solution you replace your radio input with something like:
<input type="radio" ng-model="question.subQuestion" value="true"> <br/>
<input type="radio" ng-model="question.subQuestion" value="false"> <br/>
And then below you add this:
<div ng-if="question.subQuestion">
// Your subQuestion code comes here
</div>
Everything will be inside of your ng-repeat and should work correctly without additional logic in controller.
Related
I'm developing an application using Angular 6. I have a big problem.
Using a template-driven form I would like that the item selected in a radio button can be sent when I press the submit button.
It's all right when I work with <input type="text" [(ngModel)] = "value" /> (value is a data field of my component), but if I try with this:
<div class="form-group">
<div *ngFor = "let option of options">
<div class="radio">
<input type = "radio"
name = "radio"
[(ngModel)] = "value"
/>
<label for="{{option.id}}">{{option.id}}</div>
</label>
</div>
</div>
</div>
The result is a bug! I can't even click the multiple buttons by moving the selector! Everything is stuck! Obviously it does not work with the form.
If I remove [(ngModel)] = "value" graphically it works, but without ngModel directive if I enter this code inside a template-driven form that uses (ngSubmit) it does not work.
Thanks a lot.
You are missing a value for each of the radio buttons so the binding does not work correctly. It is unable to determine which input should be checked so none of them get checked. Update the template to be something like:
<div *ngFor="let option of options">
<div class="radio">
<input type="radio"
name="radio"
id="radio-{{option.id}}"
[(ngModel)]="value"
[value]="option.value"
/>
<label for="radio-{{option.id}}">{{option.id}}
</label>
</div>
Stackblitz Demo
Radio buttons work different. To need to add a value to make it work. If you want to assign a value from angular use [value].
I have make it running in an example of stackblitz:
<div class="form-group">
<div *ngFor="let option of options; let i=index">
<div class="radio">
<input type="radio" id="{{option.id}}" name="radio{{i}}" [(ngModel)]="option.value" [value]="option.id" />
<label for="{{option.id}}">{{option.id}}</label>
</div>
</div>
</div>
<hr>
<h2>Values for options</h2>
<ul>
<ng-container *ngFor="let option of options; let i=index">
<li *ngIf="option.value !== ''">Value for {{option.id}}: {{option.value}}</li>
</ng-container>
</ul>
Component
value: any;
options = [
{
id: "test1",
value: ''
},
{
id: "test2",
value: ''
},
{
id: "test3",
value: ''
}];
Extension/Hints:
You can even use [(ngModel)] = "value" to assign the last selected value to value.
Give these radio buttons the same name name="radio" to ensure that only one of this group can be selected.
Inside the ts file :
radio_button_value = null;
box_options = [
{
"name": "Word",
"value": "word",
},
{
"name": "Line",
"value": "line"
},
]
Inside the html file:
Do notice of the tag 'name', it would we a great concern inside another for loop.
<div *ngFor="let box_opt of box_options; let i=index">
<input name="option-{{i}}" type="radio" [value]="box_opt.value" [(ngModel)]="radio_button_value">
{{box_opt.name}}
<br>
</div>
I have an App using Angularjs v1.69
I Get a Json Response of Time Slot
The below is the Current Code:
$scope.TimeSlotList = JSON.parse(localStorage.getItem("TimeSlots"));
Console.log($scope.TimeSlotList);
Output:
[
{
"id": 1,
"time": "7am - 10am"
},
{
"id": 2,
"time": "10am - 1pm"
},
{
"id": 3,
"time": "1pm - 4pm"
},
{
"id": 4,
"time": "4pm - 7pm"
},
{
"id": 5,
"time": "7pm - 10pm"
}
]
and this is done in the partial
<div class="col-md-6">
<div class="form_pad20">
<label>Prefered Time</label>
<div class="clearfix">
<div class="form-field field-destination">
<div class="radio-checkbox display_inline" ng-repeat="x in TimeSlotList">
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="TimeSlotList[$index]">
<label for="check-{{x.id+9}}">{{x.time}}</label>
</div>
</div>
</div>
</div>
</div>
The Required output is Whichever Checkbox is selected i want that value
For Ex: if the user select time slot 2 and 3
i want to send 23 to the backend
i.e Timeslot-2 and Timeslot-3 should return true
or something else i want output as
var FinalTime="23";
Trying to figure out from last 2 days
But After Few Atempts basically th best solution was
ng-model="TimeSlot-{{x.id}}"
but this throughs error
Error: [ngModel:nonassign] Expression 'ScdItem.TSlot(x.id)' is non-assignable.
please can anybody help me ?
Change the TimeSlotList so that it contains a selected field. The initial value can be set to false.
$scope.TimeSlotList = JSON.parse(localStorage.getItem("TimeSlots"));
$scope.TimeSlotList.forEach(item => item.selected = false);
Then bind the selected field to the corresponding checkboxes using ng-model:
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="x.selected">
This will change the selected's value based on checkbox is checked/not checked. When you send the data to the server, you can extract the IDs of the slots based on the value of selected field, like this:
var selectedSlots = $scope.TimeSlotList
.filter(slot => slot.selected) // Get all the selected slots
.map(slot => slot.id) // Extract IDs of the slots
.join(''); // Join the IDs to form a string
This way selectedSlots will contain the IDs of the slots selected.
<div class="col-md-6">
<div class="form_pad20">
<label>Prefered Time</label>
<div class="clearfix">
<div class="form-field field-destination">
<div class="radio-checkbox display_inline" ng-repeat="x in TimeSlotList">
<input id="check-{{x.id+9}}" type="checkbox" class="checkbox" ng-model="x.id" ng-change="checkTimeslot(x.id)">
<label for="check-{{x.id+9}}">{{x.time}}</label>
</div>
</div>
</div>
</div>
I am implementing a control/widget that has three options, only one of which may be selected, which led me to using radiobuttons. This widget has to appear several times on various forms so I embarked on creating (incrementally) a dedicated directive.
The template of the directive is as follows:
<div class="row">
<span class="fieldlabel col-xs-3">{{title}}</span>
<div>
<label>
<input type="radio" data-ng-model="modelName" value="{{value1}}">
{{label1}}
</label>
<label>
<input type="radio" data-ng-model="modelName" value="{{value2}}">
{{label2}}
</label>
<label>
<input type="radio" data-ng-model="modelName" value="{{value3}}">
{{label3}}
</label>
</div>
The title, labels and values are correctly defined/computed either through using the custom directives or in the controller.
The last question I am facing now is how to specify different model bindings for each such widget? All instances of this widget currently share their model binding, which is of course not what I need. For instance, both of the divs in the fictitious example below would bind to "modelName" but I need them to bind to say "annotationsPos" and "menuPos" in the view's controller.
<div my-3option-radiobutton title="Show annotations"></div>
<div my-3option-radiobutton title="Menu position"></div>
How can I specify bindings in a custom directive?
EDIT 1
I think either I haven't really made myself clear or I lack some elements that would have helped me understand the answers that were offered.
If I had written the HTML by hand, I would have had something like this:
<div class="row">
<span class="fieldlabel col-xs-3">Position of your annotations</span>
<div>
<label>
<input type="radio" data-ng-model="annotationsPos" value="left">
Left of the element
</label>
<label>
<input type="radio" data-ng-model="annotationsPos" value="middle">
Through the element
</label>
<label>
<input type="radio" data-ng-model="annotationsPos" value="right">
Right of the element
</label>
</div>
<!-- -->
<div class="row">
<span class="fieldlabel col-xs-3">Position of the top menu</span>
<div>
<label>
<input type="radio" data-ng-model="menuPos" value="left">
Top left
</label>
<label>
<input type="radio" data-ng-model="menuPos" value="middle">
Top middle
</label>
<label>
<input type="radio" data-ng-model="menuPos" value="right">
Top right
</label>
</div>
<!-- -->
<div class="row">
<span class="fieldlabel col-xs-3">Position of notifications</span>
<div>
<label>
<input type="radio" data-ng-model="notificationPos" value="left">
Bottom left
</label>
<label>
<input type="radio" data-ng-model="notificationPos" value="middle">
Bottom middle
</label>
<label>
<input type="radio" data-ng-model="notificationPos" value="right">
Bottom right
</label>
</div>
Instead of copying and pasting this boilerplate code multiple times, I'm looking to do this thanks to an attribute directive:
<div my-3option-radiobutton title="Position of your annotations"></div>
<div my-3option-radiobutton title="Position of system notifications"></div>
<div my-3option-radiobutton title="Position of the top menu"></div>
What changes between these block is made of titles, values and, most importantly, model attribute values. I've covered the titles and values in the directive's controller in a non elegant way (see plunk further below). My problem is that I can't seem to:
determine where to specify an ng-model AND
have the "generated" HTML code refer correctly to that model attribute value (i.e. 'annotationPos', 'notificationsPos' and 'menuPos') AND
have two-way binding with the parent controller
EDIT 2
This plunk shows that #Suresh's answer is working, with a minor modification concerning the field name. However, the directive that I have written does not work (all widgets on the page bind to the same value), maybe due to it being an attribute directive and not an element directive. I don't want to have the latter type as it doesn't make sense to me and to top it all, this is to be integrated in an existing larger project, with other developers on it, that uses no element directive. This however does not mean that element directives are never to be used on the project.
Anyway, I'll keep looking for a solution. Thanks.
EDIT 3
I have resorted to using an ng-repeat directive in the template, just like #Suresh did. Using a developed template (i.e. repeating the input tag manually) does not work but I don't know whether that has to do with using/not using ng-repeat or rather with the way I "build" the values and labels in the controller.
Lessons learned from my plunk: even with a two-way binding over ngModel (below) in the controller of the widget:
all controls on the page will bind to the same value/variable unless ng-repeat is used
the parent controller's bound model is not updated if the template has data-ng-model="ngModel" instead of data-ng-model="$parent.ngModel"
scope: {
ngModel: "="
}
'use strict';
var app = angular.module('MyApp',[]);
app.directive("myRadiobutton", function () {
var templateHtml = function () {
return '<div class="form-group" >' +
'<label style="margin-right: 10px"; ng-repeat="(key, option) in options.valueList">' +
'<input type="radio" name="myfield" ng-value="option.value" ng-model="$parent.ngModel" ng-required="options.required" />{{option.title}}' +
'</label>' +
'</div>';
};
return {
scope: { options: '=', ngModel: '=' },
required: ['ngModel'],
restrict: 'E',
template: templateHtml,
};
});
app.controller('myController', function ($scope) {
$scope.radioGender = {
"label": "Gender",
"required": true,
"className": "",
"valueList": [
{
"title": "Male",
"value": "1"
},
{
"title": "Female",
"value": "2"
},
{
"title": "Others",
"value": "3"
}
]
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="myController" >
<my-radiobutton options="radioGender" ng-model="genderValue"></my-radiobutton>
<span>{{genderValue}}</span>
</div>
You should use the "=" in the directive scope to bind an object:
directives.directive("dirname", function () {
return {
restrict: 'A',
replace: false,
scope: {
model: '=', // pass a referecne object
title: '#' // path as string
},
controller: function ($scope, $rootScope) {
...
},
}
});
<div dirname title="Menu Position" model="modelName" ></div>
Let's say I have a form, which iterates over some fields.
I want to wrap some fields in a container, so that I can split the form into sections.
I have tried to put field_open = true under the item I want to start opening the div, and then field_close = true under the last field in that container and then I repeat this process.
<form name="{{form.form_name}}" id="{{form.form_id}}">
<div ng-if="field.field_open == true" class="halfCol">
<div ng-repeat="field in form.form_fields">
<div class="{{field.field_class}}">
<field-directive field="field"></field-directive>
</div>
</div>
</div ng-if="field.field_close == true">
</form>
Obviously this doesn't work, but I'm wondering how I can achieve this?
The below HTML is how it should be rendered:
<form name="test" id="test">
<div class="halfCol">
<label for="apple">Apple</label>
<input type="text" name="apple" id="apple" />
<label for="fruit">Fruit</label>
<input type="text" name="fruit" id="fruit" />
</div>
<div class="halfCol">
<label for="dog">Dog</label>
<input type="text" name="dog" id="dog" />
</div>
</form>
The above html should be drawn from the following data.
var data = {
"form_name": "test",
"form_fields": [
{
"field_title": "Apple",
"field_open" : false
"field_open" : true
}{
"field_title": "Fruit",
},{
"field_title": "Dog",
"field_close" : true
"field_open" : true
}
]}
I'm more or less looking for a way to wrap certain elements in the same field scope.
What will the decision to separete the fields in sections depend on?
If the decision depends on some aspect of presentation, I think you don't need to use model data as you do. I mean you could write simple html without ng-repeat directives.
If you insist to use model data, your model structure will be like below.
var data = {
"form_name": "test",
"form_sectinons": [
{
"section_title": "section 1",
"fields": [
{"field_title": "Apple"},
{"field_title": "Fruit"},
]
},
{
"section_title": "section 2",
"fields": [
{"field_title": "Dog"},
]
}
]
}
And Html will be like below.
<form>
<div ng-repeat="section in data.form_sections">
<div ng-repeat="field in section.fields" class="halfCol">
<field-directive field="field"></field-directive>
</div>
</div>
</form>
I'm not sure quite what you are trying to do but you should do like this:
<form name="{{form.form_name}}" id="{{form.form_id}}">
<div ng-if="field.field_open == true && field.field_close == true" class="halfCol">
<div ng-repeat="field in form.form_fields">
<div class="{{field.field_class}}">
<field-directive field="field"></field-directive>
</div>
</div>
</div>
</form>
I'm trying to build a calculator for daycare prices in Angular.
Every location in the company franchise has separate prices for every day. So my thinking was to build a form, with first a select that allows you to select the location, then a series of checkboxes for the days.
I'm having trouble with ng-true-value in the checkboxes selecting the correct prices from my json file.
UPDATE: Added Plunkr: http://plnkr.co/edit/MDmrqaH1VzLBzjd5eHgT?p=preview
Consider this code:
<p class="kind_section">Choose location</p>
<select ng-model="formData.location" ng-options="location.title for location in data.bso"></select>
<p class="kind_section">Select days</p>
<input type="checkbox" ng-model="location.day.mon" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.monday}}" ng-false-value="0">Ma
<input type="checkbox" ng-model="location.day.tue" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.tuesday}}" ng-false-value="0">Di<br />
<input type="checkbox" ng-model="location.day.wed" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.wednesday}}" ng-false-value="0">Wo
<input type="checkbox" ng-model="location.day.thu" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.thursday}}" ng-false-value="0">Do<br />
<input type="checkbox" ng-model="location.day.fri" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.friday}}" ng-false-value="0">Vr
First the select sets formData with a location ID, then I want to use this ID to select the day prices for the matching location and set those to ng-true-value.
I'm using ng-true-value="{{data.bso[formData.location.ID].prices.monday}}" for this. This doesn't work.
When I set the ID manually like ng-true-value="{{data.bso[0].prices.monday}}" it does work. Why is the result of the select not being picked up by ng-true-value?
This is my json file:
$scope.data = {
"bso": [
{
"ID": 0,
"title": "Locatie 1",
"prices": {
"monday": 130,
"tuesday": 130,
"wednesday": 200,
"thursday":130,
"friday": 130
}
},
{
"ID": 1,
"title": "Locatie 2",
"prices": {
"monday": 430,
"tuesday": 530,
"wednesday": 600,
"thursday":990,
"friday": 730
}
}
]
};
It seems ng-true-value does not accept non-constant expressions. From the docs(v1.3.0):
Some attributes used in conjunction with ngModel (such as ngTrueValue or ngFalseValue) will only accept constant expressions.
Examples using constant expressions include:
<input type="checkbox" ng-model="..." ng-true-value="'truthyValue'">
<input type="checkbox" ng-model="..." ng-false-value="0">
Examples of non-constant expressions include:
<input type="checkbox" ng-model="..." ng-true-value="someValue">
<input type="checkbox" ng-model="..." ng-false-value="{foo: someScopeValue}">
An ideal workaround probably would be calling a Controller method on ng-click or ng-change inside which you can analyse all the checkboxes for truthy or non-truthy values.
Another approach is to delay the creation of the checkbox until the value is ready (on scope or whatever).
In my case I was loading a value via http that wasn't on the scope when the checkbox was created. So I just wrapped it in an ng-if.
<div class="checkbox" ng-if="viewData.conditionId != undefined">
<label>
<input type="checkbox" ng-true-value="{{'\''+ viewData.conditionId + '\''}}" ng-false-value="undefined" ng-model="model.conditionId" required />
I agree
</label>
</div>
Which worked perfectly for my scenario. Yours is a bit different but the same principal should apply - delay creation of the checkbox until you know the value being bound is there.
And yes the stupid quotation marks seem to be necessary.
Expression in the ng-true-value will be evaluated only once, so it won't be dynamic.
One alternative approach is to calculate the values in ng-change callback instead.
Please see my fork http://plnkr.co/edit/9zYS3OZ0sSkXX9rHwcgv?p=preview for the full example.
In html:
<input type="checkbox" ng-model="selectedDays.monday" ng-change="calculatePrice()" /> Mon
<input type="checkbox" ng-model="selectedDays.tuesday" ng-change="calculatePrice()" /> Tue <br />
<input type="checkbox" ng-model="selectedDays.wednesday" ng-change="calculatePrice()" /> Wed
<input type="checkbox" ng-model="selectedDays.thursday" ng-change="calculatePrice()" /> Thu <br />
<input type="checkbox" ng-model="selectedDays.friday" ng-change="calculatePrice()" /> Fri
and in controller:
$scope.calculatePrice = function(){
$scope.formData.location.day = {};
angular.forEach($scope.selectedDays, function (selected, day) {
if (selected) {
$scope.formData.location.day[day.slice(0, 3)] = $scope.data.bso[$scope.formData.location.ID].prices[day];
}
});
}
$scope.selectedDays = {};