I have 3 columns of radio drop down boxes. I have logic where if a user selects a radio button in column 1, the radio buttons in column 2 will refresh with a new list. I always want the top radio button all to default to check on each new refresh of a new list in column 2. However, on a second new refresh the ng-check="true" will not apply and all will not be checked.
How can I make all default to checked when the list of radio buttons refresh with a new list?
<div class="filter-column">
<div class="filter-title">Market</div>
<div class="bottom-line"></div>
<div class="overflow-container">
<div ng-show="markets.length >= 1">
<input type="radio" value="all" name="marketRadio" ng-checked="true" class="resetAll"
ng-model="filter.market" ng-change="radioMap('market')">All
</div>
<div ng-repeat="choice in markets| orderBy: 'name'">
<input type="radio" value="{{choice.name}}" name="marketRadio"
ng-change="radioMap('market', $index)" ng-model="filter.market" >
{{choice.description}}
</div>
</div>
</div>
Logic when second column of radio buttons refresh with new list:
var ppvFilter = {
regions: [],
markets: [],
dealers: []
};
function populateMarkets(regionCode) {
ppvFilter.markets.length = 0;
ppvFilter.dealers.length = 0;
var urlPath = API_BASE_URI + 'service/org/' +
regionCode + "/markets";
var params = {
url: urlPath,
method: 'GET'
};
$http(params)
.then(function(response) {
ppvFilter.markets = ppvFilter.markets.concat(response.data);
})
.catch(failure);
}
The ng-checked attribute in this case is being overridden by the value of the ng-model you have bound to that input. If you need to set it on page load, you could use ng-init="filter.market = true" to set filter.market to be truthy, which will check the box.
In general, if you have an ng-model bound to an input of any kind, the model will take priority over any hardcoded attributes that attempt to set that value. You need to programmatically set filter.market to be true for it to work.
Related
I am making angular application with angular form.
Here i have given a form with input fields first name and last name which will always showing..
After that i am having children which will be displayed upon clicking the add button and the children will get removed on click remove button.
As of now everything works fine.
Here i am making patching of data to the inputs on click option from select box.. The neccessary inputs gets patched..
HTML:
<div>
<form (ngSubmit)="onSubmit()" [formGroup]="form">
<div *ngFor="let question of questions" class="form-row">
<ng-container *ngIf="question.children">
<div [formArrayName]="question.key">
<div *ngFor="let item of form.get(question.key).controls; let i=index" [formGroupName]="i">
<div *ngFor="let item of question.children">
<app-question [question]="item" [form]="form.get(question.key).at(i)"></app-question>
</div>
</div>
<select multiple (change)="changeEvent($event)">
<option *ngFor="let opt of persons" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
</ng-container>
<ng-container *ngIf="!question.children">
<app-question [question]="question" [form]="form"></app-question>
</ng-container>
</div>
<div class="form-row">
<!-- <button type="submit" [disabled]="!form.valid">Save</button> -->
</div>
</form> <br>
<!-- Need to have add and remove button.. <br><br> -->
<button (click)="addControls('myArray')"> Add </button>
<button (click)="removeControls('myArray')"> Remove </button><br/><br/>
<pre>
{{form?.value|json}}
</pre>
</div>
TS:
changeEvent(e) {
if (e.target.value == 1) {
let personOneChild = [
{ property_name : "Property one" },
{ property_name : "Property two" },
]
for (let i = 0; i < personOneChild.length; i++) {
this.addControls('myArray')
}
this.form.patchValue({
'myArray': personOneChild
});
}
if (e.target.value == 2) {
let personTwoChild = [
{ property_name : "Property three" },
{ property_name : "Property four" },
{ property_name : "Property five" },
]
for (let i = 0; i < personTwoChild.length; i++) {
this.addControls('myArray')
}
this.form.patchValue({
'myArray': personTwoChild
});
}
}
addControls(control: string) {
let question: any = this.questions.find(q => q.key == control);
let children = question ? question.children : null;
if (children)
(this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
}
removeControls(control: string) {
let array = this.form.get(control) as FormArray;
array.removeAt(array.length - 1);
}
Clear working stackblitz: https://stackblitz.com/edit/angular-x4a5b6-fnclvf
You can work around in the above link that if you select the person one option then the value named property one and property two gets binded to the inputs and in select box the property one is highlighted as selected..
The thing i am in need is actually from here,
I am having a remove button, you can see in demo.. If i click the remove button, one at last will be got removed and again click the last gets removed..
Here i am having two property one and two, if i remove both the inputs with remove button, the the highlighted value person one in select box needs to get not highlighted.
This is actually my requirement.. If i remove either one property then it should be still in highlighted state.. Whereas completely removing the both properties it should not be highlighted..
Hope you got my point of explanation.. If any needed i am ready to provide.
Note: I use ng-select for it as i am unable implement that library, i am making it with html 5 select box.. In ng-select library it will be like adding and removing the option.. Any solution with ng-select library also appreciable..
Kindly help me to achieve the result please..
Real time i am having in application like this:
Selected three templates and each has one property with one,two,three respectively:
If choose a dropdown then the property values for the respective will get added as children.
Here you can see i have deleted the property name three for which the parent is template three and the template three still shows in select box even though i removed its children
Firstly, get a reference to the select, like so:
HTML:
<select multiple (change)="changeEvent($event)" #mySelect>
<option *ngFor="let opt of persons" [value]="opt.key">{{opt.value}}</option>
</select>
TS:
import { ViewChild } from '#angular/core';
// ...
#ViewChild('mySelect') select;
Then, in your remove function, check if all elements have been removed, and if they have, set the value of the select to null
if (array.length === 0) {
this.select.nativeElement.value = null;
}
Here is a fork of the StackBlitz
I am building an administration panel within a meteor app to be able to manage the users of the app. Currently I am displaying all the users with a dropdown for each user to change their role .
I need to update the changed roles only after I hit some confirmation button at the end.
I have a template that gets rendered with the username and a dropdown with the current role of the user, my template is similar to this:
<div class="ui selection dropdown">
<input type="hidden" name="role">
<i class="dropdown icon"></i>
<div class="default text">{{role}}</div>
<div class="menu">
<div class="item" data-value="admin">Admin</div>
.
.
.
<div class="item" data-value="user">User</div>
</div>
</div>
This renders as many as users I have in my database. I need to update all users who have their role changed after clicking a button.
My current approach is to plug the user id to the dropdown:
<div class="ui selection dropdown" id={{_id}}>
Then I have an event handler for the dropdown change and catch the value:
Template.templateName.events({
"change .ui.selection.dropdown": function(event, template) {
var id = template.find(".ui.selection.dropdown").id;
var role = template.find("input[name=role]").value;
...
},
});
Now I am wondering if I should push those id,role pairs in some session key and update the users after clicking save button or there is a better and more effective alternatives for this ?
Instead of saving them in session variable and clearing session variable on template's destroyed callback, you can add an attribute to the changed element indicating that the element has changed. When save button is clicked, you can use attribute selector to get all the elements that were changed by this user. See the code sample below for further reference.
Template.templateName.events({
"change .ui.selection.dropdown": function(event, template) {
var target = $(event.target);
target.attr("data-changed", "data-changed");
},
"click #saveButtonId": function(event, template) {
var changedElements = template.$(".ui.selection.dropdown[data-changed]");
var changedItems = [];
for (var i = 0; i < changedElements.length; i++) {
var changedElement = changedElements[i];
changedItems.push({ id: changedElement.id, value: changedElement.value });
// or
//changedItems.push([changedElement.id, changedElement.value]);
}
// here you can call a meteor method like
// Meteor.call('updateUserRoles', changedItems); //this updateUserRoles will now get only changed items that you can update in your DB.
}
});
I am trying to make one demo in which i have one checkbox list .I am able to display the list using ng-repeat .
What I need if user click on one check box(only one checkbox is checked) .it display only one columns (100%) width .Which user checked two column it display two columns of equal width (50%).if user check three column it show three column of equal width ..As as if user checked four checkbox it show four column of equal width ..Initially some of checkbox is checked ( checked:true) ..
my first step is to unchecked the checked option "training 3" ..but after unchecked it still display why ? I already use splice. method ?
here is my code
http://codepen.io/anon/pen/adBroe?editors=101
init();
function init(){
for(var i =0;i<self.data.length;i++){
var obj=self.data[i];
if(obj.checked)
{
self.selectedList.push(obj);
}
}
alert('starting '+self.selectedList.length)
}
self.checkBoxClick=function(obj,i){
if(obj.checked)
{
alert('if')
self.selectedList.push(obj);
}else
{
alert('else'+i);
self.selectedList.splice(i,1);
}
alert(self.selectedList.length);
}
})
here is i am trying to display
<div class='container-fluid'>
<div class='row'>
<div ng-repeat="i in vm.selectedList" class='col-xs-{{12/vm.selectedList.length}}'>
{{i.name}}
</div>
</div>
</div>
It can be much simpler. In HTML you don't even need ngChange handler, just bind to checked property:
<div class="checkbox" ng-repeat='v in vm.data'>
<label>
<input type="checkbox" ng-model='v.checked'> {{v.name}}
</label>
</div>
and then render columns with just ngRepeat:
<div ng-repeat="i in filteredList = (vm.data | filter:{checked:true})" class='col-xs-{{12/filteredList.length}}'>
{{i.name}}
</div>
So as the result, clean controller without any logic at all, with Angular doing all necessary column filtering using template vm.data | filter:{checked:true}.
Demo: http://codepen.io/anon/pen/bEBydL?editors=101
This is happening because you are trying to remove it from 2nd index while training 3 is present at 0th index.
else
{
alert('unchecked '+i);
var index = self.selectedList.indexOf(obj);
self.selectedList.splice(index,1);
}
change your else part to this. and it will work fine.
http://codepen.io/anon/pen/yeVWeQ?editors=101
In my Angular app, I have the following list of checkboxes, generated within a nested ng-repeat:
<div ng-repeat="partner in type.partners">
<label class="checkbox-inline">
<input type="checkbox"
ng-model="partners[$parent.$index][$index]"
ng-true-value="{{partner}}"
ng-change="handleCheckboxChanged({{type.id}})"
ng-checked="getChecked({{partner.id}})"
>
<p><span ></span>{{partner.name}}<p>
</label>
</div>
This will end up looking like the picture below:
When a user selects a partner with a chekcbox, this partner gets added to the nested list of selected partners, making use of ng-true-value and ng-model.
However, when a user deselects a checkbox, my object will still keep that key:value pair, except the value will now simply be false, as seen here in the console:
My intention would be that this key:value pair would disappear when a user unticks a checkbox, instead of it just becoming false.
Is it possible to do so by triggering a function as the ng-false-value?
What you described - this is a default behaviour. You can adjust your ngChange function.
Just a simple example, how you can make desired.
<div ng-repeat="partner in partners">
<label>
<input type="checkbox"
value="partner.id"
ng-model="partner.selected"
ng-change="changeValue(partner)"
/>
{{partner.name}}
</label>
</div>
var partnersList = [], idsArray = [];
$scope.changeValue = function(partner){
if(partner.selected)
addPartner(partner);
else
removePartner(partner);
};
var addPartner= function(partner){
if(!existInList(partner))
partnersList.push(partner);
};
var removePartner= function(partner){
idsArray = getIdsArray();
var indexToRemove = idsArray.indexOf(partner.id);
if(indexToRemove == -1)
return;
partnersList.splice(indexToRemove, 1);
};
var existInList = function(partner){
idsArray = getIdsArray();
return idsArray.indexOf(partner.id) != -1;
};
var getIdsArray = function(){
return partnersList.map(function(partner){ return partner.id });
};
Link to JSFiddle example.
I have a list of checkboxes and values I"m loading from a list which comes back from the database.
Controller
listA = ['item1','item2'...'itemn']; //Master list of items
$scope.selectedItems = ["item1",... "item5"]; //selected items
$scope.attributesModel = [ //new model based on selected items
{"index":5,"attribute":"item1"},
{"index":10, "attribute":"item2"},
{"index":13, "attribute":"item3"},
{"index":21, "attribute":"item4"},
{"index":24, "attribute":"item5"}
];
View part 1
<td>
<div class="checkbox checkbox-notext">
<input checklist-model="selectedItems" checklist-value="key" type="checkbox" id="{{key}}" ng-disabled="exceededLimit && !checked" />
</div>
</td>
<td>
<label for="{{key}}">{{key}}{{$index}}</label>
</td>
view part 2
<div ng-repeat="(index, row) in attributesModel" >
<div class="margin10">
<div>Index<input ng-model="row.index" value="row.index" type="number" class="indexInputs"></input>{{row.attribute}}</div>
</div>
</div>
Now I would like to sync $scope.selectedItems and $scope.attributesModel. When a checkbox is deselected, both selectedItems and attributesModel models remove that item, and vice versa. So every time someone checks a new checkbox they are presented a attributesModel with an empty text field to type the index value.
catch The index key is null initially for every newly selected item that is added to attributesModel. The user must enter a new index # once the new item is created.
I've tried using watch but the problem I run into is when a new item is selected, I don't have access to the item itself. I only have access to the list without any idea whether the new item is X or if the item removed is Y in order to push/delete the right item.
So this might be a watch solution that I'm missing.
Let me know if I can clarify anything.
I am not sure what the problem is, but you could use ngChange on the checkboxes:
<input type="checkbox" ... ng-change="..." />
I asdume you have a checklist directive or something, so should do something there, but (since you don't share it with us) I can't tell what exactly :)
UPDATE:
Since the checklist directive is an external dependency, you could handle the ng-chage in your code:
<input type="checkbox" ... ng-change="changed(key)" />
/* In the controller: */
...
$scope.changed = function (key) {
if ($scope.selectedItems.indexOf(key) === -1) {
// The checkbox for `key` was unchecked...
} else {
// The checkbox for `key` was checked...
}
};