My form is structured like the following:
<form class="content">
<div class="inner-content" ng-repeat="item in items">
<span class="inner-content-name">{{item.name}}</span>
<input
class="inner-content-toggle"
ng-class="{{item.className}}"
type="radio"
ng-click="toggle(item.id, item.name)"
ng-checked={{item.checked}}
/>
</div>
</form>
My question is more of why this does not work... When I click on one of the radio buttons in the rendered UI it adds the inner dot, however the inner dot when clicked again does not go away and stays permanently. As well if I select another radio button while one is already clicked both are now clicked and both will not unclick. This behavior is very much like a checkbox, but I want only one to be clicked ever. Any suggestions?
You must set the name attribute with the same value for the radio elements if they are mutually exclusive.
For example try this:
javascript:
this.items = [
{
name: 'foo',
nameAttr: 'radio-option1',
className: 'foo-bar',
checked: 1
},
{
name: 'bar',
nameAttr: 'radio-option1',
className: 'foo-bar',
checked: 0
}
];
html:
<form class="content">
<div class="inner-content" ng-repeat="item in $ctrl.items">
<span class="inner-content-name">{{item.name}}</span>
<input
class="inner-content-toggle"
name="{{item.nameAttr}}"
ng-class="{{item.className}}"
type="radio"
ng-click="$ctrl.toggle(item)"
ng-checked="item.checked"
/>
</div>
</form>
Playground: https://stackblitz.com/edit/angularjs-qhcken?file=home/home.controller.js
Related
I have a list of Users to select for a team. Imagine that i select a User, he can either be active or inactive in his team. Now, if i don't select him at all, i should not be able to either activate or deactivate him.
This is made by a checkbox and a slider, like this:
When I click the checkbox, i need to disable the toggle. I have tried doing this by:
$("#2048").prop('disabled', true);
or
document.querySelector('[name="' + '#2048' + '"]').disabled = true;
Does not work either (And yes, i know that IDs should not be numbers, but it's because every toggle is inside a *ngFor. Still, i can use them as numbers, as jQuery can select them anyway)
Either way, i strongly believe that the only way to do something like this is to data-bind the 'disabled' attribute as some back-end variable that returns either a 'true' or 'false' value.
Something like:
<mat-slide-toggle
[id]='data.id'
class="status"
[disabled]='disableVariable'
>Active
</mat-slide-toggle>
and then:
disableVariable = someFunction(); //that returns true or false
This works, but the variable is 'too generic', i mean, every single slider will become disabled. Another problem is that this is not 'real-time', so i cant disable and enable multiple times.
Basically, it does not do the job.
What should i be doing here? If i had a way to select those tags using their unique ID's, that would fix the problem, but neither jQuery or Javascript's Query selector can disable or enable this tag.
EDIT:
A litle more of my code:
<div id="table" *ngFor="let data of User; let i = index">
<div [id]='data.id' *ngIf='data.user== 0' class="item">
<label class="container" style="width: 90%">
<input
type="checkbox"
*ngIf='data.status== 0'
id={{i}}
class="checkbox"
color=primary
checked>
<span class="checkmark"></span>
<div *ngIf='data.status== 0'>{{data.name}}
<mat-slide-toggle
[id]='data.id'
(change)=toggle(data.id)
*ngIf='data.status== 0'
color=primary
class="status"
>Active
</mat-slide-toggle>
</div>
</label>
</div>
</div>
When i add the ([ngModel)], my checkboxes stop working, and yes, i'm importing the FormsModule
You can use two-way binding to update the status of the checkbox as follows:
Add [(ngModel)] and disabled property to the input field
// Declare variable in component
CheckboxVar:boolean;
// In Html write below code
<input type="checkbox" [(ngModel)]="CheckboxVar" [disabled]="!CheckboxVar">
// Disabled checkbox when checkboxvar = false;
<input type="checkbox" [disabled]="!CheckboxVar">
Update CheckboxVar variable as per your need in your component.
Example with mat-slide-toggle
TS Code:
checked = false;
disabled = false;
HTML Code:
<input type="checkbox" [(ngModel)]="checked">
<mat-slide-toggle [disabled]="checked">
Slide me!
</mat-slide-toggle>
Now in the above example, if you checked the checkbox checked variable will be updated and if checked equals true then your toggle will be disabled.
If I understand the requirement correctly:
HTML Code:
<div *ngFor="let obj of list">
<mat-checkbox [(ngModel)]="obj.inTeam">In Team</mat-checkbox>
<br><br>
<mat-slide-toggle [(ngModel)]="obj.inTeam">Active</mat-slide-toggle>
</div>
TS Code:
list = [
{ id : 1,inTeam: false, isActive: false },
{ id : 3,inTeam: false, isActive: false },
{ id : 3,inTeam: false, isActive: false },
{ id : 4,inTeam: false, isActive: false }
]
StackBlitz
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 need to know if a radio button has been selected to hide / show other options.
<input #r4 type="radio" name="x">
<span>Group</span>
<div class="subOption" *ngIf="r4.checked"></div>
div.subOption must be displayed when it has been selected.
it's correct?¿
I would just create a new boolean variable in the component, that you set as true when radio button has been checked. With that boolean you then display the div. So for example:
isChecked: boolean = false; // our new variable
<input type="radio" name="x" (click)="isChecked = true">
<div *ngIf="isChecked">
<!-- Your code here -->
</div>
EDIT: As to multiple radiobuttons... as mentioned in a comment, radio buttons seems at this point be kind of buggy with Angular. I have found the easiest way to deal with radio buttons seems to be using a form. So wrap your radio buttons in a form, like so:
<form #radioForm="ngForm">
<div *ngFor="let val of values">
<input (change)="changeValue(radioForm.value)" type="radio" [value]="val.id" name="name" ngModel />{{val.name}}
</div>
</form>
whereas on radio button would look like the following in this example:
{
id: 1,
name: 'value1'
}
In the form there is a change event, from which we pick up the chosen radio button value.
(change)="changeValue(radioForm.value)"
Then I would just play with boolean and the value chosen:
changeValue(val) {
this.valueChosen = true; // shows div
this.chosenVal = val.name; // here we have the value chosen
}
A plunker to play with: here
Iam running foreach loop above the radio button but unfortunately i could not check any of radio button.Here is my view
<div class="tab-pane" id="tab3">
<div class="form-body">
<div class="row">
<div class="col-md-12">
<h3 class="form-section">Qualification Factor</h3>
<div class="row" data-bind="foreach: leadqualificlist">
//Here is my foreach loop
<div class="col-md-6">
<div class="form-group">
<div class="radio-list radio-list-padding">
<label class="radio-inline">
<input type="radio" name="serious" value="0" data-bind="checked:Scoreschk, attr: { name: 'grp' + $data.Negativescore}" />
Negative
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Iam having list in leadqualificlist observable array.
Radio buttons behave differently than checkboxes, see documentation:
For radio buttons, KO will set the element to be checked if and only if the parameter value equals the radio button node’s value attribute or the value specified by the checkedValue parameter. <...> When the user changes which radio button is selected, KO will set your model property to equal the value of the selected radio button.
So, having that said, you cannot set different names for your checkboxex (using attr binding), but should set value in binding, like this:
...
<input type="radio" name="serious" data-bind="value: Scoreschk, checked:$parent.selectedScoreCheck" />
...
Now your view model should look like this:
function ViewModel() {
var self = this;
self.leadqualificlist = ko.observableArray([new Qualification(0, 5),
new Qualification(1, 2),
new Qualification(2, 1)]);
self.selectedScoreCheck = ko.observable("2"); // Note here must be string!
}
Where Qualification is:
function Qualification(scoreCheck, negativeScore) {
this.Scoreschk = scoreCheck;
this.Negativescore = negativeScore;
}
See demo.
If I have two or more checkboxes how would I move unchecked checkboxes below the ones that are checked. At the moment I have simple HTML below, so if Checkbox 2 is checked it should move to the top and Checkbox 1 should move down.
The 2 ways I have thought of doing this is:
create and array on the scope and use ng-repeat to populate the checkboxes then apply a filter based on weather or not a checkbox is checked or splice the array. Only problem with this is I don't really want to define my checkboxes on the scope.
create a directive to somehow manipulate the dom element.
If someone has had a similar problem what would you recommend to be the best solution?
<div class="col-md-6">
Please check one or more boxes <i tooltip-placement="bottom" tooltip="On the Bottom!" class="fa fa-question-circle"></i>
<span ng-show="checked || checked_2" class="glyphicon glyphicon-ok text-success"></span>
<span ng-hide="checked || checked_2" class="glyphicon glyphicon-remove text-danger"></span>
<div class="checkbox">
<label>
<input ng-model="checked" type="checkbox" value="1">
Checkbox 1
</label>
</div>
<div class="checkbox">
<label>
<input ng-model="checked_2" type="checkbox" value="2">
Checkbox 2
</label>
</div>
<div ng-hide="checked || checked_2" class="text-danger">Some error message!</div>
<br/>
</div>
Try using the orderBy filter:
JS
var app = angular.module("app", []);
app.controller('Ctrl', function ($scope) {
$scope.users = [
{ Name: 'John', Selected: false },
{ Name: 'Mary', Selected: false },
{ Name: 'Jane', Selected: false },
{ Name: 'Tom', Selected: false },
{ Name: 'Benny', Selected: false }
];
});
HTML
<body ng-app="app" ng-controller='Ctrl'>
<ul>
<li ng-repeat="user in users | orderBy: ['-Selected','Name']">
{{user.Name }} <input type="checkbox" ng-model="user.Selected" />
</li>
</ul>
</body>
Demo Plunker