Conditionally applying css to mat form field - css

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..

Related

How to Disable CSS for a particular field

I am using a styling for all the input fields but there is one field for which i do not want that style. Is there any way i can disable the css for that particular field and let it be for others.
You can add a css class to that element and use :not pseudo-class selector:
input:not(.notred) {
background: red;
}
<input name="text1">
<input name="text2">
<input name="text3">
<input class="notred" name="text4">
<input name="text5">
<input name="text6">
In CSS3, you can use ‘:not()’ to exclude an element using id or class.
add a class to that input which you want to disable, then in css
input:not(.that_class)
Let me know if you have any issue.

method gets called multiple times in angular material autocomplete

We have created a component using Angular material's autocomplete. To display the options, we are traversing through an array of 51 objects. I am applying a CSS class to the already selected option. The isAccountingTypeSelected method determines whether the option was selected or not.
The method gets called 51*28 = 1428 times. I don't seem to understand the reason? It should only be called 51 times, shouldn't it?
<mat-form-field class="full-width">
<input type="text" matInput #autoCompleteInput [formControl]="autocompleteForm" [matAutocomplete]="auto" placeholder="Choose Accounting Type" aria-label="Number">
<span matSuffix class="close-icon hover" *ngIf="autoCompleteInput.value" (click)="clearAll($event)"></span>
<span matSuffix class="arrow-drop-down-icon hover" (click)="openPanel()"></span>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="accountingTypeSelected($event)">
<mat-option *ngFor="let accountingType of filteredAccountingTypes | async" [value]="accountingType.code">
<span class="accounting-type-options" [class.selected]="isAccountingTypeSelected(accountingType.code)">
{{ accountingType.name + ' (' + accountingType.code + ')' }}
</span>
</mat-option>
</mat-autocomplete>
</mat-form-field>
isAccountingTypeSelected(code: string): boolean {
console.log('I was called');
if (this.selectedAccountingTypes.find((accountingType: AccountingType) => accountingType.code === code)) {
return true;
}
return false;
}
Angular uses changedetection lifecycle multiple times to check if the function has changed for [class.selected] or ngClass. If you use function, it will call multiple times. For this reason the use of function is not advised when you bind, instead you should calculate the values in your component.ts file and just bind the values to ngClass or [class].
Example: Stackblitz
N.B: We know when we change selected value it triggers a event change, we can calculate it and attach the calculation result to the [class.my-class] or ngClass.
Angular is gonna evaluate that expression every time it checks for changes, which in your case might be the css being added to your span elements.
Calling methods from the template in a for loop is not the best approach because they are called very often. You should instead store the result in a property and bind to this property instead.
It is a bind problem. Angular checks more times the result value. You can try with ChangeDetectionStrategy.CheckOnce
Your ngFor loop needs track a specific id so it won't re-render for nothing. Try this:
<mat-option *ngFor="let accountingType of filteredAccountingTypes | async; trackBy: trackByCode"[value]="accountingType.code">
</mat-option>
Then you add this function:
trackByCode(index: number, accountingType: yourType): string {
return accountingType.code;
}

Angular 6 - change checkbox style whether is checked

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

Pure CSS way to show/hide content based on option select?

My question is similar to this one: CSS to select another Element based on a HTML Select Option Value
Here's my HTML:
<select id="select-card">
<option value=""></option>
<option value="card">**** **** **** 1982</>
</select>
<p>Or enter a new one...</p>
I want to hide the <p> when the user selects a card from the list, and show it when the user selects the empty option.
Is this possible in pure CSS, or do I need to use JavaScript?
Use the required attribute:
<select id="select-card" required>
And write rules for valid and invalid for the element, selecting the following p-element:
#select-card:invalid + p { display: block; }
#select-card:valid + p { display: none; }
Fiddle

Change style of button element if text field is empty

I would like to change style of #postBtn, if #textfield is empty, something like
#postBtn:[#textfield.value.length==0]{
border-color:gray;
background-color:gray;
}
In html:
<input id='textfield'>
<input type="button" Value="Post" onClick="post()" id="postBtn">
How do I achieve this without javascript?
Thanks!
Ok, you can add required to your input field like so:
<input id='textfield' required>
<input type="button" Value="Post" onClick="post()" id="postBtn">
And then, using :invalid and the adjacent sibling selector (+), you can style the button if the field is empty like so:
#textfield:invalid + #postBtn {
background-color: red;
}
Here is a fiddle of it in action: http://jsfiddle.net/w7377/
Note: If the text input field is not actually a required field, then this solution is not the way to go. You may have to use a Javascript solution if that's the case.

Resources