Applying CSS class conditionally in Angular2 - css

I have below HTML code which recursively create list items based on list returned from Component and I want to apply 'first-child' CSS class to first List item only.
<ul class="link-list-horz">
<li *ngFor="let menu of menulist" [ngClass]="first-child:">
{{menu}}
</li>
</ul>
.first-child a
{
border-radius: 10;
}
export class AppComponent {
name = 'Quiz';
menulist = ['Home','AngularQuiz'] ;
useremailid = 'Gaurav-Gupta';
}
Please suggest. I am totally new to Angular2.

ngClass needs a condition to know whether to set that class on the element. You can use the built-in index that comes with ngFor for that.
Try this:
<li *ngFor="let menu of menulist; let i=index" [ngClass]="{'first-child': i === 0}">

Related

Angular2 how to change styles of css classes in typescript?

I am trying to toggle viewing categories of items within a very long list, based on what the user wants to see. I want to toggle viewing everything, just meetings, just events or nothing. (this is a small example I really have about 15 categories)
<ul>
<li class="cal-meeting">meeting title</li>
<li class="cal-event">event title</li>
<!-- … the list goes on with various events and meetings -->
So I have the following checkboxes to toggle the viewable items:
<input type="checkbox" checked (click)="toggleCal('meeting')">
<input type="checkbox" checked (click)="toggleCal('event')">
// checkboxes are initially checked however I will make this dynamic saved in DB for user preference
In my angular component in TypeScript I have the function:
toggleCal(toggle_items) {
if (toggle_items === 'meeting') {
// this.display_meeting is initially set to true in ngOnInit
this.display_meeting = !this.display_meeting;
if ( this.display_meeting ) {
// set class cal-meeting to display: block;
} else {
// set class cal-meeting to display: none;
}
}
// do the same thing if toggle_items === 'event'
}
How do I change the display value of the classes cal-meeting and cal-event in my Typescript? I assume just changing the CSS values of the classes is the best way.
I did try:
document.getElementsByClassName('cal-meeting').style.display = 'none';
But I get an error saying "Property 'style' does not exist on type 'HTMLCollectionOf'"
try to convert your selection as HTMLElement
const element = <HTMLElement> document.getElementsByClassName('cal-meeting')[0];
then use :
element.style.display = 'none';
also you can use *ngif for remove it but if you want to use javascript's function to change style you should convert it to HTMLElement
but you can use angular [ngStyle]="{'property': expression}" for changing style like :
<li class="cal-meeting" [ngStyle]="{'display': !this.display_meeting ? 'none': 'block'}">meeting title</li>
or you can add class for example if you have class like :
.d-none: {display: none}
.d-block: {display: block}
you can use it in typescript like:
export class MyComponent implements OnInit {
hidingClass: string = '';
toggleCal(toggle_items) {
if (toggle_items === 'meeting') {
this.display_meeting = !this.display_meeting;
if ( this.display_meeting ) {
this.hidingClass = 'd-block'
} else {
this.hidingClass = 'd-none'
}
}
// do the same thing if toggle_items === 'event'
}
just use it in your html element:
<li class="cal-meeting" [ngClass]="hidingClass">meeting title</li>
If it's just toggle the view, why you did not put something simple like this
<li class="cal-meeting" *ngIf="this.display_meeting">meeting title</li>

StencilJS check if named slot is empty

I have a stencilJS component with two named slots. Is there a way to determine if the slots have been assigned values? For instance, the code snippet below show named slots for "logo" and "menu." How can I check inside the component if both named slots are not empty? Ideally I want to check from inside the component and during componentWillMount() . Thank you.
<koi-menu breakpoint="768" userToggled="false">
<div class="logo__header " slot="logo"><img src="assets/images/logo.png" /></div>
<ul class="nav__wrapper list mw8-ns center-m" slot="menu">
<li class="nav__listitem"><a class="ttu nav__link" href="???">Why Live Grit</a></li>
<li class="nav__listitem"><a class="ttu nav__link" href="???">Clients</a></li>
<li class="nav__listitem"><a class="ttu nav__link" href="???">Our Programs</a></li>
<li class="nav__listitem"><a class="ttu nav__link" href="???">Our Story</a></li>
</ul>
</koi-menu>
The use of a slot can be detected from the host element in the componentWillLoad() function:
hasLogoSlot: boolean;
hasMenuSlot: boolean;
#Element() hostElement: HTMLStencilElement;
componentWillLoad() {
this.hasLogoSlot = !!this.hostElement.querySelector('[slot="logo"]');
this.hasMenuSlot = !!this.hostElement.querySelector('[slot="menu"]');
}
This might not apply to your problem, but if you only want to style the slotted elements—say only add margins on non-empty slots—you can use the ::slotted pseudo-element:
::slotted([slot="logo"]) {
/* Apply styles to non-empty logo */
}
::slotted([slot="menu"]) {
/* Apply styles to non-empty menu */
}

Apply css class to specific element depending on state

I have React component, with state managed by redux, ul list and a css-class. I want to apply class to one of li elements, depending on state. For instance, if myStateProp = a, apply css class to first li, if myStateProp = b, apply class to second li and so on. But I'm not sure how to do it properly.
For now I solved this problem like this:
<ul>
<li className={this.props.myStateProp ==="a" ? "myCssClass" : ""}>A</li>
<li className={this.props.myStateProp ==="b" ? "myCssClass" : ""}>B</li>
<li className={this.props.myStateProp ==="c" ? "myCssClass" : ""}>C</li>
</ul>
But I don’t really like this approach, seems too many copied code. Maybe there is a way to do it more neatly?
While there's nothing inherently wrong with your code, you could simplify it with a class method ternary statement and return "myCssClass" or null.
class Example extends PureComponent {
isActive = item => this.props.someProp === item ? "myCssClass" : null
render = () => (
<ul>
<li className={isActive("a")}>A</li>
<li className={isActive("b")}>B</li>
<li className={isActive("c")}>C</li>
</ul>
)
}
Or, take it one step further and simplify your li elements (while less repetitive, it does abstract what's happening):
const listItems = ["a","b","c"];
class Example extends PureComponent {
isActive = item => this.props.someProp === item ? "myCssClass" : null
render = () => (
<ul>
{listItems.map(item => (
<li key={item} className={isActive(item)}>
{ item.toUpperCase() }
</li>
))}
</ul>
)
}
You can create function which will return classname
const classNames = (data)=>{
swtich/case/if... what you want
return 'SomeClassName'
}
<li className={this.classNames(dataFromStore)}>C</li>

How to access style element in react component?

Need a bit of help with react code.
Suppose a component has style declared in it like
<style>{
.list-done {
color:red;
}
`}</style>
then how do I use this style to style my link tag
<li>item1</li>
I want to use classnames for this. but how to use it in this case?
I was told to use something like this, but can't find anything in the documentation --> import cx from 'classnames';
Well, I have now declared a variable here
const styleItem={color:'red'}
How do I conditionally use it?
I am doing it like this
style={item.done?styleItem:''}
and it doesn't work.
What am I doing wrong here?
You need to add a className to your list Item, With react you can add it using className attribute
<li className={'list-done'}>item1</li>
You might need to load styles in your component. You need to configure style-loader with webpack for it.
Check this answer on how to configure styles with webpack
or else write inline styles
render() {
const listStyles = {
color:red;
}
return (
<li styles={item.done? listStyles: {}}>item1</li>
)
}
You can't declare styles like this in react. You need to put it as a variable and assign it in style attribute.
let styles = { color:red; }
<li style={styles}> item 1 </li>
OR
Declare the class outside (may be in some css) and use className attribute to assigne that class
<li className='list-done'> item1 </li>

Adding and Removing Styles to li group using Angular 2

<ul>
<li (click)="AddColor($event)">ONE</li>
<li (click)="AddColor($event)">TWO</li>
<li (click)="AddColor($event)">THREE</li>
</ul>
AddColor(e){
e.srcElement.style.color="blue"
}
I have the above list when i click any one of the li item out of 3, the clicked label color should be changed. when i click another all item colors should be revert back to original and change color of current clicked item.
#Mehdi said, you should not access DOM directly untill there is a need.
Always keep in mind, drive your view with data rather than accessing
DOM directly
I have forked and working snippet https://plnkr.co/edit/fgINMc?p=preview
When using Angular, you don't want to directly manipulate the DOM element. Rather let angular deal with it.
In your example, you can generate your list from an array you declare in the code like so
export class YourClass{
links:any;
activeLink = -1;
//...
constructor(){
this.links = ['ONE','TWO','THREE']
}
//...
}
and then in your template you could have :
<ul>
<li *ngFor="let link of links; let i = index"
(click)="activeLink = i"
[ngClass]="activeLink == i? 'blue' : '' " >
</li>
</ul>
and declare a css class blue :
.blue{
color:blue;
}

Resources