Adding 3rd condition to ngClass is not working - css

I am trying to add a 3rd condition to my ngClass. At first, I got the following two class to work in my ngClass to alternate the color of the rows
[ngClass]="{ totalrow:i%2 != 0, odd:i%2 == 0}"
I am trying to add a 3rd class and condition where the mat-list will show a border line for the top of the mat-list-item. However when I add the 3rd condition, it gives me an error
[ngClass]="{ totalrow:i%2 != 0, odd:i%2 == 0, borderTopClass : operator === 'fas fa-equals'}"
I get the following error which is confusing to me
Parser Error: Missing expected : at column 47 in [{ totalrow:i%2 != 0,
odd:i%2 == 0, borderTopClass : operator === 'fas fa-equals'}] in
Here is the code with the ngFor
<div class="ng-container" *ngFor="let operator of operatorList; let i = index">
<mat-list-item
fxLayoutAlign="start"
style="padding-left: 0px; padding-right: 0px;"
[ngClass]="{ totalrow:i%2 != 0, odd:i%2 == 0, borderTopClass : operator === 'fas fa-equals'}">
<i class="{{operator}}"></i>
</mat-list-item>
</div>
Any help is appreciated.

I guess a commenter needs a deeper explanation of how this works.
<div [ngClass]="{
'is-active': condition,
'is-inactive': !condition,
'multiple': condition && anotherCondition,
}">
multiple class will apply when two conditions are both met. Not just one but both.
You could add a third like this: 'multiple': condition && anotherCondition && thirdCondition
Here's a StackBlitz of the OP's code working as he expected and without error. If I can help more pleas let me know.

Related

Changing a specific input color from within an each loop of inputs in a event

I am new to Svelte. I have 2 arrays of letters. One of which is the question and one is the answer. The question has empty values so they can be guessed. The question is displayed through an loop of inputs.
I loop through the inputs, disabling ones that already contain a correct value or ones with spaces. When I enter a correct value in one of the inputs I would like only that input to change the background colour to green. The same goes for an incorrect value changing to red. If it's cleared it changes back to white. A handleInput() function handles this.
Currently, if I enter one correct value all the inputs change green or red. Is there a way to manipulate this so that only the individual id that is targeted changes to the correct colour?
<script>
let scrambledMessage =["h","","","",""," ","t","o","d","","y"]
let answer = ["h","e","l","l","o"," ","t","o","d","a","y"];
const colorCode = { white: 'bg-white', red: 'bg-red-500', green: 'bg-green-500' };
$: color = colorCode.white;
const handleInput = (event) => {
let val = event.data;
let id = event.target.id;
//check to see if val is in answer
if (val === answer[id]) {
console.log('You are correct');
color = colorCode.green;
//event.target.classList.add(colorCode.green);
} else if (val === '') {
color = colorCode.white;
//event.target.classList.add(colorCode.white);
} else {
console.log('You are not correct');
color = colorCode.red;
//event.target.classList.add(colorCode.red);
}
};
</script>
<svelte:head><link src="https://cdn.tailwindcss.com"></svelte:head>
<div class="bg-black p-20 text-black">
{#each scrambledMessage as mes, i}
{#if mes === ' '}
<input
class="bg-gray-500 w-12 px-4 py-2 border mx-2 rounded text-center border-purple-500"
disabled />
{:else if mes === ''}
<input
class="{color} w-12 px-4 py-2 border mx-2 rounded text-center border-purple-500"
placeholder={mes}
id={i}
on:input={(event) => handleInput(event)}
maxlength="1"
value={mes} />
{:else}
<input
class="bg-white w-12 px-4 py-2 border mx-2 rounded text-center border-purple-500"
value={mes}
disabled />
{/if}
{/each}
</div>
Check it out on repl
I would not recommend manipulating DOM like that. This is not how Svelte is intended to be used and subsequent updates can mess with this.
Instead it would be better to have a function that simply returns the intended for the given input. That way the result can be different for each input in the loop.
E.g.
<script>
const answer = 'hello today'.split('');
const givenCharacters = 'h____ tod_y';
const inputs = answer.map(() => '');
function getColorClass(correctValue, value) {
if (value === '')
return 'white';
return correctValue === value ? 'green' : 'red';
};
</script>
<div>
{#each answer as answerCharacter, i}
{#if givenCharacters[i] == answerCharacter}
<input
disabled class:grey={answerCharacter == ' '}
value={answerCharacter} />
{:else}
<input
class="{getColorClass(answerCharacter, inputs[i])}"
maxlength="1"
bind:value={inputs[i]} />
{/if}
{/each}
</div>
REPL
Here all entered values are stored in an inputs array. It is important that getColorClass is called with inputs[i] since changes to that cause the function to re-evaluate.
There is no need to have two separate inputs just to grey out spaces, that can also be done conditionally via a class:... directive or adding to the class attribute.

Get Text is not working for Data selection from calendar

I used get text/get value with the xpath element, but it's not getting the text/value.
Below are the Code and tried to get text/value and getting element not visible error.
Note : Same element is working For click element.
<div class="cal-month-day cal-day-inmonth cal-day-future cal-day-has-events" ng-class="{
'cal-day-outmonth': !day.inMonth,
'cal-day-inmonth': day.inMonth,
'cal-day-weekend': day.isWeekend,
'cal-day-past': day.isPast,
'cal-day-future': day.isFuture,
'cal-day-has-events': day.events.length > 0,
'cal-day-selected': vm.calendarCtrl.isSelectedDate(day),
'cal-day-open': dayIndex === vm.openDayIndex
}" ng-click="vm.calendarCtrl.onDateSelection(day.date)">
<small class="cal-events-num badge badge-important pull-left ng-binding" ng-show="day.badgeTotal > 0 && (vm.calendarConfig.displayAllMonthEvents || day.inMonth)" ng-bind="day.badgeTotal">2</small>
<span class="pull-right ng-binding" ng-bind="day.label">2</span>

How to use [ngClass] with simple condition and ternary condition?

I have a series of a tags that represent steps. As shown here, if step one is the current step, apply the step-active class.
<a (click)="goStep2" [ngClass]="{'step-active': currentStep === 1 }">
Step 1
</a>
Now, I'd like also to add another condition which related to the contain of the page. Let's user has responded to all the required questions. I'd like to highlight the step by green if the step is valid, otherwise by red.
<a (click)="goStep2" [ngClass]="{'step-active': currentStep === 1,
isValid ? 'valid-state' : 'invalid-state' }">
Step 1
</a>
I'm getting an error about missing :. How to apply this 2 conditions given that the first one is just a simple condition while the second is a ternary one.
Thanks for helping
<a (click)="goStep2" [ngClass]="{'step-active': currentStep === 1,
'valid-state' : isValid, 'invalid-state': !isValid }">
Step 1
</a>

bootstrap css not getting rendered properly in ngClass

I've following line of code for displaying a message in modal based on the modal type -
<div class="modal-body">
<span class="fa sb-alert-icon" [ngClass]="{ 'fa-exclamation-circle text-danger': (type == error),'fa-exclamation-triangle text-warning': (type == alert)
,'fa-question-circle text-warning': (type == confirm), 'fa-info-circle text-info': (type == info)}">{{message}}</span>
</div>
Issue is that, i don't see proper text color for alert message with above conditions and its rendered as white.
In browser console I don't see 'text-warning' being rendered. But I do see the place where text color is set to white which is shown below.
However, if i change above condition to following -
<span class="fa sb-alert-icon" [ngClass]="{ 'fa-exclamation-circle text-danger': (type == error),'fa-exclamation-triangle text-warning': (type == alert)
, 'fa-info-circle text-info': (type == info)}">{{message}}</span>
I see 'text-warning' css getting applied properly as shown below.
Here CSS overriding doesn't happen.
EDIT-1 :
.sb-alert-icon has following code -
.sb-alert-icon{
font-size: medium;
padding-right: 10px;
}
Not sure, if this is happening because -
using 'text-warning' css consecutively for both 'Alert' & 'Confirm' scenarios.
using both Font Awesome and bootstrap together.
<span class="fa sb-alert-icon"
[ngClass]="{
'fa-exclamation-circle text-danger': type == error,
'fa-exclamation-triangle': type == alert,
'fa-info-circle text-info': type == info,
'fa-question-circle': type == confirm,
'text-warning': type == alert || type == confirm
}">
{{ type }} - {{ message }}
</span>

ng-class Conditional is not working

<style>
.btn.active {
color: #fff;
background-color: #FE9A2E;
border-color: #d58512;
}
.btn.normal {
color: #fff;
background-color:cornflowerblue;
border-color: #398439;
}
</style>
<div class="btn-group" ng-repeat="list in inputarray" >
<label ng-model="ngModel" class='btn' ng-class="{'btn normal':'{{ngModel}}'== '{{list.score}}' && '{{ngModel}}'== '2','btn active':'{{ngModel}}'== '{{list.score}}' && '{{ngModel}}'!= '2' }" value ="{{list.score}}" btn-radio="{{list.score}}">{{list.name}}</label>
</div>
so here if a user Selects Any Radio button based on this the Css is Set
normal is set if it satisfies 2 conditions
'{{ngModel}}'== '{{list.score}}' && '{{ngModel}}'== '2'
and active is Set if it Satisfies 2 conditions
'{{ngModel}}'== '{{list.score}}' && '{{ngModel}}'!= '2'
and if non of this conditions are met then default class is applied
so the problem i am facing is when i see the first condition is satisfied it is not showing in outout as Expected it still showing active style even though the condition for normal is satisfied
Please any one Help me correcting my code
Try to remove '{{}}'.
E.g.
<label class="btn"
ng-class="{'btn normal': ngModel == list.score && ngModel == '2',
'btn active': ngModel == list.score && ngModel != '2'}"
btn-radio="{{list.score}}">
{{list.name}}
</label>
Note that ng-model and value are not applicable with label element so I removed it.
Hope it helps.

Resources