Add a class to the Immediate Parent Element in Angular - javascript

I have an element where it has a class creates dynamically. I want to add a new class to it's parent element if the child element has a specific class.
<a [ngclass]="addClassHere"> //need to add class here if child has a specific class
<div [ngclass]="getScheduleDateColour(date.day)">{{date.day}}</div> //child class
</a>
the a element is created by the package and cannot access directly.

Assuming your getScheduleDateColour() returns different names of classes, say 'childClass1','childClass2' and so on, and the required is 'childClass1'.
Now you can set a new class to your parent according to your child's class by :
<a [ngclass]="childDiv.className == 'childClass1'? 'ReqParentClass' : '' ">
<div #childDiv [ngclass]="getScheduleDateColour(date.day)">{{date.day}}</div>
</a>
PS: If you want to add different parentClasses if child is not the required one, you can add it also in the ternary operator, like: 'childClass1'? 'ReqParentClass' : 'ElseThisWillBeTheParentClass'

One of the options you have is to use Template reference variables
for both your parent and child elements and change them pragmatically from your TS file
like so in html
<div #parentElem class="aquaDay">
<div #childElem class="aqua">day</div>
</div>
and use #ViewChild to bind them and change them as you want
#ViewChild("parentElem") parent: ElementRef;
#ViewChild("childElem") child: ElementRef;
changeColour() {
const childClass = this.child.nativeElement.className;
this.parent.nativeElement.className =
childClass === "aqua" ? "greenDay" : "aquaDay";
}
I created a simple demo here: https://stackblitz.com/edit/angular-ivy-422p1t?file=src/app/app.component.ts

Related

Toggle class on buttons in Svelte

Consider this Svelte code
{#each filters as filters, i}
<div class='filter-container'>
<div class='button filter' on:click={ () => setFilter(filters.name, filterContext)}>{filters.name}</div>
</div>
{/each}
The above filter buttons are made depending on how many filters there are in some js object. How can I create a class that is toggled for all filter buttons when the one button is clicked.
eg. when one is active all the others are not?
Class are just strings - in svelte you can bind them to an expression as any other attribute.
For example:
<div class={'button filter ' + (activefilter === filters.name ? 'isactive' : '')}/>
when activefilter === filters.name is true, then the button class will became 'button filter isactive'
A special short syntax to toggle classes is provided too. Find more here
We can easily bind class names to expressions, so that the class will be added if the expression becomes truthy:
<script>
let isActive = false
</script>
<style>
.active {
color: red;
}
</style>
<h1 class:active={isActive}>Hello!</h1>
<button on:click={() => isActive = !isActive}>Click me</button>
Here, clicking the button toggles the isActive boolean. The class active is bound to that variable on the h1 element and you can see that the color now changes on every button click.
That is the standard way on how to set single classes dynamically.
REPL: https://svelte.dev/repl/988df145876a42c49bb8de51d2cae0f2?version=3.23.0

Angular Updating Parent div Class when Click

I have the following code and i wish to update the parent class when click on the image. The image will call "SelectVariation" method when clicked. Is there any way to do this?
component.html :
<div class="clr-row">
<ng-container *ngFor="let variOption of product.variOptions">
<div class="card clickable clr-col-2 variationCard"
*ngFor="let variOptionTwo of variOption.variOptionTwos"> //Update this class
<div class="card-img" (click)="selectVariation(variOptionTwo.id, $event)">
<clr-tooltip>
<img src="{{variOptionTwo.url}}" class="variationImgScale" clrTooltipTrigger>
<clr-tooltip-content clrPosition="top-right" clrSize="m" *clrIfOpen>
<span>{{variOption.optName}} - {{variOptionTwo.optName}}</span>
</clr-tooltip-content>
</clr-tooltip>
</div>
</div>
component.ts :
selectVariation(id: number, event: any) {
//Update parent class
}
In the child component use
#Output() variableHere = new EventEmitter<>();
this.variableHere.emit(this.variableToSend);
Then in the parent associate the variable to a method in html child template definition:
<app-child (variableHere)="manageVariable($event)"></app-achild>
In the parent component define the method and do a variable equels the result of the method for example:
manageVariable(event) {
this.variableToUpdate = event;
}
If you have to check if the variable has changed his state call what you need to check in an ngDoCheck().
Take the advantage of the EventEmitter in angular with output
parent.component.html
<my-child-comp (onSelectVariation)="myVariation($event)" ></my-child-comp>
parent.component.ts
myVariation(myVars) {
console.log(myVars)
}
child.component.html
<button (click)="onSelectVariation.emit(myData)">trigger variation</button>
child.component.ts
#Output() onSelectVariation = new EventEmitter();
Name which you have defined in the output should be used as a event in it host element in parent

Web Components: how to access a slotted element using shadowRoot.querySelector

Hi I am new to Web Components concept. I wanted to know if we can access a slotted element using shadowRoot.querySelector
I have implemented an input field as slot for setting some values dynamically. And have a class added to it 'column-title'. I am trying to access this element in connectedCallback() like this
var titleInput = this.shadowRoot.querySelector('.column-title')
But it returns null.
Please help.
Going off of #royyko 's response. The better answer here is instead of giving a class or id with the purpose to grab the slot... use the already provided identifier, its name. To do this you would do the following this.shadowRoot.querySelector('slot[name=interior]')
I'm not sure what the issue is, but you should be able to get a slot using querySelector and its class. I've mocked up an example below.
The console will print out references to the slot. If you're attaching a class just for the purpose of finding the slot then it's probably better to set an id (assuming that it's within a shadow root) and find it with this.shadowRoot.getElementById('my-slot-id')
customElements.define('blue-box',
class extends HTMLElement {
constructor() {
super();
var template = document
.getElementById('blue-box')
.content;
const shadowRoot = this.attachShadow({
mode: 'open'
})
.appendChild(template.cloneNode(true));
}
connectedCallback() {
console.log(this.shadowRoot.querySelector('slot.target-slot'));
}
});
<template id="blue-box">
<style>
.blue-border {
border: 2px solid blue;
padding: 5px;
margin: 5px;
}
</style>
<div class='blue-border'>
<slot name='interior' class='target-slot'>NEED INTERIOR</slot>
</div>
</template>
<blue-box>
<span slot='interior'>My interior text</span>
</blue-box>
<blue-box>
<span slot='interior'>
Check Here: <input type='checkbox'>
</span>
</blue-box>

Remove all occurances of class in angular 2 +

I have just started coding in angular5 and I came across need of removing all class occurances on click event.
Something like below we have in Jquery
$('.m-active').removeClass('m-active');
I am looking for alternative of this in angular2 + (Typescript)
You could use document.querySelector all to remove the class - in the following - I have two divs - iniitally set to be red / green text, but using querySelectorAll - I am removing the red class from the divs.
function toggleRedClass() {
var redDivs = document.querySelectorAll('.red');
if (redDivs.length) {
for(i=0;i<redDivs.length;i++) {
redDivs[i].classList.remove('red');
redDivs[i].classList.add('black')
}
} else {
var blackDivs = document.querySelectorAll('.black');
for(i=0;i<blackDivs.length;i++) {
blackDivs[i].classList.remove('black')
blackDivs[i].classList.add('red')
}
}
}
.red {color:red}
.green {color:green}
<div class="red">test</div>
<div class="green">test1</div>
<button type="button" onclick="toggleRedClass()">Click to toggle the red class</button>
In Angular 2+ better use bindings instead of jQuery
<div [class.my-class]="isMyClass">div 1</div>
<div [class.my-class]="isMyClass">div 2</div>
<button (click)="isMyClass = !isMyClass">toggle</button>
export class MyComponent {
isMyClass:boolean = true;
}
You can create a directive like this :
https://plnkr.co/edit/eKokX0IrsIWIuY9ACUZ4?p=preview
#Directive({
selector: '[class]'
})
export class ClassDirective {
#Input('class') claz;
private _claz;
public set claz(claz){
this._claz = claz;
}
public get claz(){
return this._claz;
}
#HostBinding('class') get hostClass(){
return this.claz;
}
constructor(){
console.log('***');
}
ngOnInit(){
console.log('this.classz',this.claz);
setTimeout(()=>{
this.claz= this.claz.replace('milad','');
},2000)
}
}
I know it doesn't do exactly what you want, but the idea is to create a Directive which has a selector called class and then you have access to all the classes in your application (obviously this component should be declared in your modules).
Then you can do whatever you'd like inside that directive, you can use host binding to override the classes and whatnot.
You can create an event listener to some button, pass the event listener's call back to this directive and let it do whatever you want.

React render to element by class

How i can render my component in few elements by class? I have one component, and i need show him in my page in differents tags, but with general logic
var FilterBox = React.createFactory(FilterBox),
ToRender = document.getElementsByClassName('filter-box')
React.render(FilterBox(), ToRender);
html:
<div class="filter-box"></div>
...
...
<div class="filter-box"></div>
you should be able to iterate over your classes and call React.render in each
for(var i;i < ToRender.length;i++{
React.render(FilterBox(), ToRender[i])
}

Categories

Resources