Angular-js - Populating Checkbox and track it based on JSON file - javascript

I have a nested Objects in JSON, and I need to populate the checkbox based on what comes in (dynamic) from JSON file, meaning, I wouldn't know in advance the name of the fields, or how many elements there could be. Here is a sample, but there could be more child and each child could have more or less item in it.
{
"Parent":{
"Child" :
{
"Child_01" : {
"description_01":false,
"description_02":false,
"description_03":false,
"description_04":false,
"description_05":false
},
"Child_02" :
{
"something_01":false,
"something_02":false,
"something_03":false,
"something_04": false
},
"Child_03" :
{
"things_01":false,
"things_02":false,
"things_03":false,
"things_04":false,
"things_05":false
}
}
}
}
Now, I need to populate a drop down from it, (child_01, child_02, child_03....) and when user choose one of them, I need to display checkboxes of all its properties. And of course be able to keep track of the chosen one.
Here is what I have.
$scope.children = response.data.parent.child;
$scope.childrenList = [];
angular.forEach($scope.children, function(value1, key1){
$scope.childrenList.push(key1);
});
and html:
<div ng-repeat="(key, data) in children">
<input ng-model="childrenListModel" type="checkbox" name="{{child}}" value="{{child}}">{{child}}</input>
</div>
Nothing works the way I intend to. Any help would be appreciated.

You probably need several nested ng-repeats. Have a look at this working plunker: http://plnkr.co/edit/K92JI7UlW9h6gh8SPeU5?p=preview
<div ng-repeat="child in children.Parent.Child">
<div ng-repeat="options in child">
<div ng-repeat="option in options">
<div ng-repeat="(key, val) in option">
<label for="{{key}}">
{{key}}
<input name="{{key}}" type="checkbox" ng-model="option[key]" />
</label>
</div>
</div>
<hr />
</div>
</div>

Related

Angular FormControl CheckBox selection marks every sibling

StackBlitz: http://stackblitz.com/edit/angular-jul7bv
I am having trouble with Angular FromControl, that are being created dynamicly based od passed data.
My list displays Groups and Subgroups of specific Data, everything works almost perfectly fine, but whenever I check subgroup, every of its sibling is being marked and i am unable to come up whats wrong.
Thats my html:
<div *ngFor="let chapter of checkboxControlLabels; let i = index;">
<div class="input-checkbox-subgroup-list__checkbox">
<div class="input-checkbox">
<input type="checkbox" [attr.id]="chapter.id + '_checkboxControl_' + i"
[formControl]="getChapterControl(i)" />
<label [attr.for]="chapter.id + '_checkboxControl_'+ i">{{ chapter.title }} </label>
</div>
</div>
<div class="input-checkbox-subgroup-list__checkbox" *ngFor="let chart of chapter.charts; let x = index;">
<div class="input-checkbox chart">
<input type="checkbox" [attr.id]="chart.title + '_checkboxControl_' + x" [formControl]="getChartControl(i, x)" />
<label [attr.for]="chart.title + '_checkboxControl_' + x">{{ chart.heading }} </label>
</div>
</div>
</div>
And this is how I am mapping specific FormControl :
getChartControl(chapterIndex: string, chartIndex: number) {
return this.data.controls[chapterIndex].get('charts').controls[chartIndex];
}
As you can see on below image when I check subgroup, there is 11 selected and I have no idea how thats possible.
More intresting thing is that this doesnt apply to groups... So if I would check First group there would be only one selected...
This is FormGroupModel that I am using later on:
this.chapterChartsData.forEach(chapters => {
dataForm.push(new FormGroup({
chapter: new FormControl(false),
charts: new FormArray(Array(chapters.charts.length).fill(new FormControl(false)))
}))
});
Apparently problem was with populating list of form controls like that :
charts: new FormArray(Array(chapters.charts.length).fill(new FormControl(false)))

Angular ng-repeat based off of another ng-repeat

I have a <select> in my application, which is supplied data from an ng-repeat but each option in the select has data of it's own. Simply enough, here is the JSON payload I am working with:
{
"0":{
"name":"Mover",
"scalar":[
{
"name":"Size",
"unit":"m"
},
{
"name":"Speed",
"unit":"m/s"
}
]
},
"1":{
"name":"Stationary",
"scalar":[
{
"name":"Size",
"unit":"m"
}
]
},
"2":{
"name":"Vibrator",
"scalar": [
{
"name":"Frequency",
"unit":"hz"
}
]
}
}
I need the outer 3 names in the select, but I'd like the 'scalar' values to show up as checkboxes next to the select. It's obviously got to be dynamic, so i was curious if there was a way to do this based off of the ng-repeat of the select. Another reason why I am asking is because due to formatting, I'd like to place the checkboxes outside of the ng-repeat (clearly since that's in a select) so not too sure how the checkboxes would access the repeat value. Below is the html snippet:
<div id="type-selection"
class="row ng-hide"
ng-show="rcw.page ==='Type Selection'">
<div class="col-md-6">
<div class="form-group">
<label for="rule-type">Type</label>
<select id="rule-type"
class="form-control"
ng-model="rcw.selectedRuleType">
<option ng-repeat="type in rcw.QueryTypes">{{type.name}}</option>
</select>
</div>
</div>
<div class="col-md-2" ng-repeat="ideally scalar in type from above^">
<label>
<input type="checkbox"
class="faChkSqr"
ng-model="ideally this would be dynamically tied to scalar.name </input>
<span></span>
<b>{{ideally this would be scalar.name}}</b>
</label>
</div>
</div>
Just not too sure if this is possible, or if I need to handle what's selected then from there in the javascript decide what needs to be displayed? Thanks in advance!
You are storing the selection in a variable: rcw.selectedRuleType
<select id="rule-type" class="form-control" ng-model="rcw.selectedRuleType">
<option ng-repeat="type in rcw.QueryTypes">{{type.name}}</option>
</select>
I guess you just have to loop over this object with your ng-repeat:
<div class="col-md-2" ng-repeat="scalar in rcw.selectedRuleType">
{{scalar.name}}
</div>
As a side note, I suggest you to use ng-options in your select:
<select ng-model="rcw.selectedRuleType"
ng-options="type as type.name in rcw.QueryTypes">
</select>
Try like this.
<li ng-repeat="n in items">{{n.name}}{{n.scalar}}
<select ng-model="selectme" ng-options="options.name for options in n.scalar">
<option value="">-- choose color --</option>
</select>{{selectme}}
</li>
We can create checkboxes based on the selection,But not sure how we can dynamically bind model based on scaler.name.
We need to set the value of option as scaler of selected option.Then we should listen to change event on select field & extract the scalar value from the selected value.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.QueryTypes = [{
"name":"Mover",
"scalar":[
{
"name":"Size",
"unit":"m"
},
{
"name":"Speed",
"unit":"m/s"
}
]
},
{
"name":"Stationary",
"scalar":[
{
"name":"Size",
"unit":"m"
}
]
},
{
"name":"Vibrator",
"scalar": [
{
"name":"Frequency",
"unit":"hz"
}
]
}
];
$scope.getScalarTypes=function(){
$scope.scalarTypes=JSON.parse($scope.selectedRuleType);
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div id="type-selection">
<div class="col-md-6">
<div class="form-group">
<label for="rule-type">Type</label>
<select id="rule-type"
class="form-control"
ng-model="selectedRuleType" ng-change="getScalarTypes()">
<option ng-repeat="type in QueryTypes" value="{{type.scalar}}">{{type.name}}</option>
</select>
</div>
</div>
<div class="col-md-2" ng-repeat="scalar in scalarTypes">
<label>
<input type="checkbox"
class="faChkSqr"</input>
<span></span>
<b>{{scalar.name}}</b>
</label>
</div>
</div>
</div>
</body>
</html>

using ng-options within ng-repeat

I am new to angular and I'm confused over this thing. I'm trying to populate a select box based on object inside an array. I want selectbox by using ng-repeat for that array... but initially i need to show only one selectbox after clicking add() next selectbox has to come. for ref:[initially one selectbox has to come]
HTML
<div class="col-lg-12" id="variant1" style="margin-top:10px" ng-repeat="variant in variants">
<div class="col-lg-4" style="text-align:right;padding-top:2px;padding-right: 20px" >
<label for="variant1name">Variant Name</label>
</div>
<div class="col-lg-6" >
<div >
<select class="form-control" ng-model="filterFormInputs.apps" ng-options="app.Application for app in variants" >
<option value="" disabled selected>Select an Application</option>
</select>
<label ng-repeat="checkbox in filterFormInputs.apps.details">
<input class="ecomtexttype1" type="checkbox" ng-model="checkbox.checked"> {{checkbox.name}}
</label>
</div>
</div>
</div>
Controller:
$scope.variants =
[
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]}
]
I think that you can just have your add() function update the array... if things are configured correctly the new row should render due to the binding on the array.
As mentioned in comments you did not provide enough source code, so here is the assumed pseudo-code:
in html you might have
<button ng-click="$scope.add()">Add</button>
so in the controller
$scope.variants = [
// array of whatever you are displaying
{"foo":"bar1"},
{"foo":"bar2"}
];
$scope.add = function() {
variants.push({"foo":"bar_new"});
}
Have you considered using a Directive for this? That may work better, depending on your situation. Look into this: https://docs.angularjs.org/guide/directive

AngularJS: Is there a way to create two-way binding on a label element so that I can dynamically attach it to an object?

This problem has been frustrating me for the last couple days now so, here I am. I'll try to be as clear as possible.
I have an object to retrieve from the database. This object is used to create dropdown menus. It has two properties on it: A section property, which contains one string. The other property is called value, which contains all the possible options that the user can select in the dropdown. I use two nested ng-repeats in my HTML to create the dropdowns.
I am trying to send out to the database a formData object that has 2 properties in it: the name of the dropdown menu, and the value that the user selected. Appending the value selected from the dropdown menu is easy thanks to two way data binding that I set on the select element. However, I CANNOT figure out how to grab the value from the label element inside my controller so that I can attach it to my formData object. As far as I know, ng-model does not work on a label element. Here is the HTML, which hopefully will make it a bit more clear:
<form class="form-horizontal" ng-controller="PreferenceCtrl">
<div ng-repeat="(name, section) in configs">
<label ng-bind="name"></label>
<select class="form-control" ng-model="formData.settings[$index].value">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
</option>
</select>
</div>
<div class="col-md-12" ng-include="gametemp"></div>
<div class="row">
<div class="hr-line-dashed"></div>
<div class="text-center col-md-12 padding-15">
<button class="btn btn-primary btn-lg" ng-click="saveSetting()" formnovalidate translate>
<i class='fa fa-circle-o-notch fa-spin' ng-if="showBusy"></i> Save
</button>
</div>
</div>
</form>
Because the <select> class can have an ng-model attached to it, I can easily capture that value in my controller. I cannot do the same with the label. If anyone can help me out I will forever be your best friend. Thank you!
In answer to your question title "Is there a way to create a two-way binding on a label element", no, that isn't possible.
But if I understand correctly what you're trying to do, it sounds like you want to save data to the database based on information contained in both the <label> and it's associated <select>. If that's true, then I'd recommend using an ng-change function in your <select> like this:
<select class="form-control" ng-model="formData.settings[$index].value" ng-click="dropdownItemClicked(name, formData.settings[$index].value)">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
</option>
</select>
In your controller, create a function to handle this ng-click event:
$scope.dropdownItemClicked = function(name, value) {
console.log(name, value);
// save name/value to database
}
The key is to pass in the exact data you want to save to the database into your dropdownItemClicked() function.
Could you just put the value inside the label?
<label ng-bind="name">{{formData.settings[$index].value}}</label>
There is no way to read from the label. It is the one way binding after all, right. I would do something like this.
var app = angular.module('MyApp', []);
app.controller("MyCtrl", function($scope){
$scope.formData = {
settings:[]
};
$scope.configs = {
'Label1': [{ value: 11 }, { value: 12 }],
'Label2': [{ value: 21 }, { value: 22 }]
};
$scope.change = function(name, idx) {
$scope.formData.settings[idx].name = name;
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-cloak="" ng-app="MyApp">
<form class="form-horizontal" ng-controller="MyCtrl">
<div ng-repeat="(name, section) in configs">
<label ng-bind="name"></label>
<select class="form-control" ng-model="formData.settings[$index].value" ng-change="change(name, $index)">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
{{item.name}}
</option>
</select>
</div>
<div class="col-md-12" ng-include="gametemp"></div>
<div class="row">
<div class="hr-line-dashed"></div>
<div class="text-center col-md-12 padding-15">
<button class="btn btn-primary btn-lg" ng-click="saveSetting()" formnovalidate translate>
<i class='fa fa-circle-o-notch fa-spin' ng-if="showBusy"></i> Save
</button>
</div>
</div>
<div>
{{formData.settings}}
</div>
</form>
</div>

Angularjs input radio and ng-repeat issue

Okay so here is my setup i have the following array:
answers = [answer1, answer2]
with these i do the following:
<form>
<div class="col-xs-12" ng-repeat="answer in component.question.answers">
<div class="col-xs-1" style="width: 1%">
<div class="radio">
<label class="i-checks">
<input type="radio" name="a" ng-model="answer.is_correct">
<i></i>
</label>
</div>
</div>
<div class="col-xs-11">
<input type="text" ng-model="answer.answer" class="form-control" placeholder="Svar">
</div>
</div>
</form>
Now the input[radio] are inside the same form as they should. My goal is that when i set one as selected both of the answer objects should be updated so that only one of the object has the value is_correct = true
However what happens right now is that if i click the first and then second both values have is_correct = true
So what can i do?
Radio buttons are used to choose between different values for a single field or, in Angular's case, a single model. The logical solution would be to select the correct answer:
<input type="radio" ng-model="component.question.correctAnswer" ng-value="answer">
If you really need to set a flag you can easily achieve that with a watcher:
$scope.$watch('component.question.correctAnswer', function(correctAnswer) {
component.question.answers.forEach(function(answer) {
answer.is_correct = answer === correctAnswer ? true : false;
});
});

Categories