Angular 6 - change checkbox style whether is checked - css

I have a list of checkbox and I want to underline the one that is checked. My code looks like the following:
TS file:
currentQuarter: string;
quarters: Observable<MeseRiferimento[]>;
q1: MeseRiferimento = new MeseRiferimento();
q2: MeseRiferimento = new MeseRiferimento();
ngOnInit() {
q1.desc = "One";
q1.id = "1";
q2.desc = "Two";
q2.id = "2"
currentQuarter = q1.id;
quarters.of([q1, q2]);
}
isQuarterSelected(q: MeseRiferimento): boolean {
return this.currentQuarter === this.getKeyFromQuarter(q);
}
HTML file:
<div *ngFor="let q of quarters | async" class="col-1 my-auto m-stati">
<label class="custom-control custom-checkbox ra-check">
<input type="checkbox" class="custom-control-input" [ngClass]="{'checked': isQuarterSelected(q) }">
<span class="custom-control-indicator"></span>
<span class="custom-control-description">{{q.descrizione}}</span>
</label>
</div>
CSS file:
.custom-control-input:checked~.custom-control-indicator {
color: #fff;
background-color: #3bb8eb;
}
These are the issue with this code:
1. when I load the page, the default checked checkbox has correctly the class 'checked' but the CSS is not applied, i.e. it's not underlined
2. when I manually select a checkbox the class 'checked' correctly applies and the CSS too applies
3. when I manually select another checkbox, the class 'checked' correctly switches from one to the other, but the CSS of the former do not update, i.e. the previous checkbox remains underlined
Thanks for any advice.

.custom-control-input:checked~.custom-control-indicator
:checked doesn't mean that it has the checked class, but it means that it's actually checked. If you want to select the checked class, use a dot in place of a colon:
.custom-control-input.checked~.custom-control-indicator

Related

Conditionally applying css to mat form field

I am working on an angular application and I am using mat form fields in it. For changing color of botttom border of mat form field I am using mat-form-field-ripple css which is inbuilt for mat form field. CSS is as follows.
.mat-form-field-ripple {
background-color: #f9c940!important;
}
When I use this CSS, it automatically gets applied to all form fields. I have to apply #f9c940 color in mat-form-filed-ripple in when one condition is true and a different color when another condition is true. My mat form field code is as follows:
<mat-form-field appearance="fill">
<mat-label [ngClass]="{}">Name</mat-label>
<input formControlName="Name" readonly>
</mat-form-field>
I was trying to do it using ngClass as shown above but not getting it. How can I do that?
ngClass doesn't work with <mat-form-field>. Use this syntax-
<mat-form-field [class.mat-form-field-invalid]="booleanVariable">
and in the .ts file, you can conditionally update the booleanVariable
You can apply classes conditionally like this:
<mat-label [ngClass]="{'your-class': foo=='foo', 'your-class-another':bar=='bar' }">
Name
</mat-label>
Just create your own CSS class:
.mat-form-field-ripple {
//your standard styling,
}
.myBackgroundColor {
background-color: #f9c940!important;
// add this selector below the .mat-form-field-ripple selector so that it will override..
}
Then apply it conditionally to your label:
<mat-form-field appearance="fill">
<mat-label [ngClass]="{'myBackgroundColor': mycheck}">Name</mat-label>
<input formControlName="Name" readonly>
</mat-form-field>
In your component you have the expression it is based on:
mycheck = true; // you will modify this true to any expression that is transformable to a boolean. If true, your class is applied, if false then not..

Angular 7: patching value of radio button Form Control does not update UI

I am using a HTML template in Angular 7 that consists of a number of radio buttons, each with an associated label - this is associated with a FormGroup object. Clicking on the label should change the state of the radio button to be selected and update the value of the associated FormControl. This works, the problem I have is setting a particular radio button to be selected when the UI loads, or using patchValue - the state of the formGroup is correct when the template is loaded, but the UI does not reflect that a particular radioButton has been selected.
Here's code that shows the problem:
export class AppComponent {
frequencyMinutesOptions: number[] = [1, 2, 5, 10, 60];
myForm: FormGroup;
constructor() {
}
ngOnInit() {
this.myForm = new FormGroup({
frequencyMinutes: new FormControl(5,[])
});
this.myForm.patchValue({'frequencyMinutes':10})
}
}
The HTML template:
<form [formGroup]="myForm">
<ul>
<li *ngFor="let frequency of frequencyMinutesOptions">
<input id="asset-frequency-{{frequency}}" type="radio" value={{frequency}} formControlName="frequencyMinutes" />
<label for="asset-frequency-{{frequency}}"> {{frequency}} </label>
</li>
</ul>
</form>
Relevant CSS:
input {
display: none;
}
input:checked+label {
background-color: blue;
color: #ffffff;
}
You may see a working demo of this here:
https://stackblitz.com/edit/angular-of2ubt
(I know that I'm supposed to embed code examples within the Stackoverflow editor but I'm not sure how to do this with Angular 7 / typescript or if its even possible)
it's a type error. In your html form, the value="10" is interpreted as the string '10'.
You have to use
this.myForm.patchValue({'frequencyMinutes':'10'}) or (see [value])
<input id="asset-frequency-{{frequency}}" type="radio" [value]="frequency" formControlName="frequencyMinutes" />
Either use formGroupName or call external function to make default radio button as true.
<div class="container">
<form [formGroup]="myForm">
<ul>
<li *ngFor="let frequency of frequencyMinutesOptions">
<input id="asset-frequency-{{frequency}}" type="radio" value="{{frequency}}" formControlName="frequencyMinutes" [checked]="isDefaultSelection(frequency)" >
<label for="asset-frequency-{{frequency}}"> {{frequency}} </label>
</li>
</ul>
</form>
<div class="debug">{{myForm.value | json}}
</div>
</div>
export class AppComponent {
frequencyMinutesOptions: number[] = [1, 2, 5, 10, 60];
myForm: FormGroup;
constructor() {
}
ngOnInit() {
this.myForm = new FormGroup({
frequencyMinutes: new FormControl(5,[])
});
this.myForm.patchValue({'frequencyMinutes':10})
}
isDefaultSelection(frequency) {
return frequency == 10 ? true : false;
}
}
or simply use property-binding
<input id="asset-frequency-{{frequency}}" type="radio" [value]="frequency" formControlName="frequencyMinutes">

Angular 6: ngx-translate not working with data-title attribute for tooltips

I'm developing an Angular 6 app which uses ngx-translate for localization and I'm also using Bootstrap 4 tooltips and the problem I'm facing is I'm not being able use localization keeping Bootstrap tooltip style.
Without localization I would use an input this way:
<input type="text" class="form-control text-truncate" id="position"
placeholder="position" data-title="position" />
And this will show a very nice Bootstrap tooltip as it can be seen below:
With ngx-translate localization I would use an input this way:
<input type="text" data-toggle="tooltip" class="form-control tooltipped text-truncate" id="position"
[attr.placeholder]="'wfrh_vacancyform_position' | translate"
[attr.data-title]="'wfrh_vacancyform_position' | translate" />
and the problem here is data-title attribute. "data-title" attribute is used to display the tooltip but I guess ngx-translate doesn't recognize it (maybe?).
Placeholder is working fine this way (the text is translated and shown correctly) but tooltip won't show.
I've also tried this way:
<input type="text" data-toggle="tooltip" class="form-control tooltipped text-truncate" id="position"
placeholder="{{'wfrh_vacancyform_position' | translate}}"
data-title="{{'wfrh_vacancyform_position' | translate}}" />
which is also not working (it only works for placeholder) so I'm stuck.
If I do:
<input type="text" data-toggle="tooltip" class="form-control tooltipped text-truncate" id="position"
[attr.placeholder]="'wfrh_vacancyform_position' | translate"
[attr.title]="'wfrh_vacancyform_position' | translate" />
then the tooltip shows but with no style as it can be seen in the next image:
And this is the way I create the tooltips in code (in ngOnInit):
ngOnInit() {
setTooltip()
}
setTooltip() {
$('.tooltipped').tooltip({
placement: 'auto',
trigger: 'focus',
template: '<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner bg-dark text-light"></div></div>'
});
$('.tooltipped').bind("mouseover", function () {
var _this = $(this);
_this.tooltip("show");
});
$('.tooltipped').bind("mouseout", function () {
var _this = $(this);
_this.tooltip("hide");
});
$('.tooltipped').bind("keyup", function () {
var _this = $(this);
_this.tooltip("hide");
});
}
Well I'm stuck. I need to be able to display this nice styled tooltip with translation. Any help / ideas?
Thanks.
Ok, after long time investigating I was able to find a solution and I'll post it here in case it helps anyone else.
The problem is I was setting tooltip in onInit (which is fired only once when the component is created) and wasn't setting any tooltip text, just leaving it to pickup the one set with:
[attr.data-title]="'text_to_translate_key' | translate"
(the initial text translation) and after changing language tooltip was not refreshing (the text was static with the initial value) but you can use a function with the tooltip "title" property this way:
$('.tooltipped').tooltip({
placement: 'auto',
trigger: 'focus',
template: '<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner bg-dark text-light"></div></div>',
title: this.setTitle
});
setTitle() {
return $(this).attr("placeholder");
}
and this function (which has current object reference -this- as an implicit input parameter) acts as a binding which updates the title property continuosly so when placeholder text changes (placeholder does not need to be refreshed after language changes and that's why it works) the tooltip "title" property will be updated and as a consequence tooltip text will change and user will see updated text.
"The end" :)

Mark required field's label based on assigned validator in Angular 2 form

I have an Angular 2 form with lots of required fields. Those have Validators.required assigned. I want to add an asterisk to these fields' labels.
<form [formGroup]="form">
<div class="form-group row">
<label class="col-sm-3 col-form-label">First Name -> Add asterisk here</label>
<div class="col-sm-9">
<input formControlName="firstName" type="text" class="form-control">
</div>
</div>
...
I have googled and read the docs, but can't find an implementation for this use case.
I know I can add the required attribute manually and work from there, but I would prefer to avoid as this seems redundant with the validator assignment.
Not sure, if its the best ng2-style solution, but what about this:
Let your FormComponent hold an array of required fields. In your template you can simply use something like:
<label for="firstName">
FirstName <span *ngIf="isFieldRequired('firstName')"> *</span>
</label>
You can create separate component for Label with asterisk, if you don't want to repeat the code through your template, for example:
#Component({
selector: 'my-label',
template: `<label for="{{id}}">{{label}} <span *ngIf="isFieldRequired(id)"> *</span></label>`
})
export class MyLabelComponent {
#Input() label: string;
#Input() id: string;
#Input() requires: [];
constructor() { }
isFieldRequired(id) {
return this.requires.indexOf(id) !== -1; // check if the array contains the value
}
}
In your Form Component, you just pass values to the my-label component, like:
<my-label [requires]="requiredFields" [label]="'Name'" [id]="'name'"></my-label>
Here is working plunker of this example: http://plnkr.co/edit/M66IFQGhhe82mNt3ekxw?p=preview
with the idea how to use the required definition together with more custom validators. See app.component.ts

bind data to an element on an ng-if condition angular js

I am new to angular js. and I have a situation.
I want to bind data to an input element from another input element based on a condition (checking a checkbox). I am trying to achieve this using the
ng-if angular directive. But it's not working,
So when I type something into input1 and check the checkbox, I want the value of input1 to be reflected in input2.
<input ng-model="value.one" type="text" />
<input ng-model="checked" ng-change="isChecked(value.one)" type="checkbox" />
<input ng-model="value.selected" />
in your controller:
$scope.isChecked(val) {
if($scope.checked) {
$scope.value.selected = val;
} else {
$scope.value.selected = null;
}
}

Resources