Appyling conditional css values in angular 8 - html

I have a parent component and child component where I am using child component's selector to render it in parent component.
my child component html:
<div class="main-container" [ngStyle]="{'transform': 'scaleX(widthScale) scaleY(heightScale)'}">
<img src="../../assets/svg/kiln-main.jpg" class="kiln-image">
<svg id="area2"></svg>
<svg id="area"></svg>
</div>
child component ts:
#Input() widthScale:string;
#Input() heightScale:string;
I want to apply "transform:scalex() scaley()" to child based on the values from the parent.
my parent:
<app-child [widthScale]="0.5" [heightScale]="0.5"></app-child>
The above code somehow isnt working.How to apply values to css property "transform" here?

You can create a method in the child as follows:
getTransformStyle() {
let styles = {
transform: `scaleX(${this.widthScale}) scaleY(${this.heightScale})`,
};
return styles;
}
Use it in child html as follows:
<div class="main-container" [ngStyle]="getTransformStyle()">
<img src="../../assets/svg/kiln-main.jpg" class="kiln-image" />
<svg id="area2"></svg>
<svg id="area"></svg>
</div>
You can refer to the child as follows:
<app-child [widthScale]="'0.5'" [heightScale]="'0.5'"></app-child>
Working example: https://stackblitz.com/edit/angular-ivy-gaohfo

Related

Change style of a child component using parent class from parent component's style file

I have TrackCard component defined as:
<React.Fragment>
{this.props.items.map((item, index) => (
<div className={classes['genre-col']} key={index}> //<--------
<div className={classes['track-single']}>
<div className={classes['track-img-container']}>
<img src={item.url} alt="" className={classes['track-image']} />
</div>
<div className={classes.genre}>
<h6>{item.name}</h6>
<p>{item.artist}</p>
</div>
</div>
</div>
))}
</React.Fragment>
The genre-col class is defined in Music.scss
.genre-col {
width: 20%;
}
Now I am accessing the TrackCard Component in another Component named Feeds as follows and the styles are defined in Feeds.scss :
<div className={`${classes['feed-cover']}`}>
<TrackCard items={this.state.tracks}/>
</div>
But here I need to change the width of the .genre-col without affecting other components. So I need to access .genre-col using the parent class in Feeds Component and define it in Feeds.scss.
I tried to import the style files in both the components and define the class globally. But there was no result.
I use SCSS modules for styling.
Correct Me if I'm wrong. As I understood, What you want is to control TrackCard from Feeds Component. There are few ways to do that.
1. Create a class in Feeds.css and pass it to TrackCard like below
<TrackCard items={this.state.tracks} customClass={classes['track-card']}/>
and Inside TrackCard
{this.props.items.map((item, index) => (
<div className={classnames(classes['genre-col'], this.props.customClass)} key={index}> />
classnames is a library for the doing class concatenation and stuff easily. Have a look at the library.
2.Define different classes which represents various sizes, you want, inside Music.scss itself. Pass a prop from Feeds like in below code.
.small { width: 300px; }
.medium { width: 500px; }
.large { width: 800px; }
For TrackCard pass needed size as props.
<TrackCard items={this.state.tracks} size={'medium'}/>
and Inside TrackCard
{this.props.items.map((item, index) => (
<div className={classnames(classes['genre-col'], classes[this.props.size])} key={index}> />

Select an element in DOM which is not a sibling, but goes after

Let us suppose I have the following DOM
<div class="parent">
<div class="childNotSibling">
</div>
</div>
<div class="elementToSelect">
</div>
Now I would like to select the div with elementToSelect class but only if div with parent class has inside it an element with childNotSibling class. Is it possible to acomplish this using css?
This JSFiddle should do the trick: https://jsfiddle.net/tremor/f4cghd5x/
Using JQuery here is the Javascript portion of the code.
// find all the occurrences of .childNotSibling
$("body").find(".childNotSibling").each(function(index, element) {
// if .childNotSibling's parent has class "parent"
if ($(this).parent().hasClass("parent")) {
// and if the parent's next sibling has "elementToSelect"
if ($(this).parent().next().hasClass("elementToSelect")) {
// do something with that element
$(this).parent().next().css("background-color", "red");
}
}
});

Insert HTML element after a specific div class name with Typescript & Angular

What I want to do is to insert a component inside a div, after a specific div with a specific class name. How do I do this in typescript?
<div class ="{{order.orderId}}">
<div class="enter-here"></div>
<other html elements here>
</div>
And TypeScript:
insertDiv(){
insert.component.after.className.enter-here;
}
Inserting new element is not the angular way of doing it, when using angular DOM manipulation should be avoided as much as possible. In your question you haven't mentioned what will be the contents of .enter-here, so I am assuming it is just plain text:
In your html:
<div class ="{{order.orderId}}">
<div *ngIf="showEnterHereDiv" class="enter-here">
some text or list which should be visible after showDiv is called
</div>
<other html elements here>
</div>
In your typescript:
// hidden by default
showEnterHereDiv: boolean = false;
...
showDiv() {
// call this method to show the div
this.showEnterHereDiv = true;
}
hideDiv() {
this.showEnterHereDiv = false;
}

How to replace one child react/html component with another based up on event using react?

I am new to react and I have a react component structure like:
<MainComponent>
<Button />
<Content />
</MainComponent>
Now when I click on the Button, I need to replace the existing div (say div1) of the Content component with another div (div2). Can you please tell me how to do it. Thank you.
Note: Till now, on click event I have been changing the data of the single div using state and prop. Now I got to replace the whole div with another one.
Like this.
render() {
var returnIt;
if (useDivOne) returnIt = (<div id='one'></div>);
else returnIt = (<div id='two'></div>);
return (returnItj);
}
If this is your structure:
<MainComponent>
<Button />
<Content />
</MainComponent>
and Content renders something like:
<div>
this is div 1
</div>
I would think you would need to pass a prop to Content that would tell you which div to render, then in Content's Render you manipulate the properties of Boolean logic to present a different component:
class Content extends Component {
render() {
return(
{
!this.props.RenderDiv2Bool &&
<div>
This is Div1 and it will be rendered
because RednerDiv2Bool is false.
</div>
}
{
this.props.renderDiv2Bool &&
<div>
This is Div2 and it will be rendered
because RednerDiv2Bool is true.
</div>
}
)
};
}
Not necessarily better but just another way to do it.

angularJs directive template removal

in every angular template we have to define a root html node, then inside it we can define the Html of our directive.
is there a way in angular to ignore that root node?
example :
my directive template :
<div class="space consuming div, and absolute positioning breaker">
<div class="content positioned relative to the directives parent 1"></div>
<div class="content positioned relative to the directives parent 2"></div>
<div class="content positioned relative to the directives parent 3"></div>
</div>
can we just set our template to be
<div class="content positioned relative to the directives parent 1"></div>
<div class="content positioned relative to the directives parent 2"></div>
<div class="content positioned relative to the directives parent 3"></div>
thanks!
You only need one root element if you are using replace: true in your template.
This is the case if you have defined custom element and are using then in your HTML in the following way:
<tabs>
<pane>1</pane>
<pane>2</pane>
</tabs>
In this case, replacing tabs with a template which has two roots will cause some confusion.
However, if you do not need replace: true, then you can set the directive on the element you want and assign a multi-root template on it. That template will be rendered inside the element which has the directive.
JS
var app = angular.module('plunker', []);
app.directive('myDirectiveOne', function() {
return {
template: '<p>Hello</p><p>World!</p>'
};
})
app.directive('myDirectiveTwo', function() {
return {
template: '<p>Hello</p><p>World!</p>',
replace: true
};
})
Template
<!-- works -->
<div my-directive-one></div>
<!-- has problem -->
<div my-directive-two></div>
E.g. http://plnkr.co/edit/jgEWsaxzfD4FkHcocJys?p=preview