How to use ngIf inside a button? - html

I have a button
<button class="mx-2" mat-button type="button" (click)="close()"
name="buttonClose">
<mat-icon>cancel</mat-icon>
{{t('commonActions.cancel')}}
</button>
where i have to show the whole button when on PC but only show the button without commonActions.cancel when on mobile.
I use isMobile() function for that but i dont know where to place the ngIf, so that only the text gets added/removed, not the button or icon

You need to put the text in a text tag like (span, p ... ) and add the ngIf inside it , here's an example :
<button class="mx-2" mat-button type="button" (click)="close()"
name="buttonClose">
<mat-icon>cancel</mat-icon>
<span *ngIf="!isMobile()" >{{t('commonActions.cancel')}}</span>
</button>

your best option is to use <ng-container> in this case:
<ng-container *ngIf="!isMobile()">{{t('commonActions.cancel')}}</ng-container>

Related

how to style a selected mat-button in an angular application

I have an Angular application where the user has multiple choices with buttons and when a button is pressed another component will display. The component depends on the user's choice.
One thing I'm trying to implement is the styling of the buttons to make it clear which choice has been selected.
<div fxLayout="row" fxLayoutAlign="space-between center" fxFill>
<div *ngFor="let button of buttons">
<button
mat-stroked-button
*ngIf="button.type === 'button'"
(click)="buttonPressed()"
ngxScrollTo
>
{{ button.text }}
</button>
</div>
<div fxLayout="row" fxLayoutAlign="space-between center">
<div *ngIf="item.hasSomeProperty | isTypeButton">
<button mat-mini-fab (click)="buttonPressed()">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
I have also attached a picture of what im trying to achieve here:
Any help would be much appreciated.
Simply use [ngClass] or [ngStyle]:
<div *ngFor="let button of buttons">
<button
mat-stroked-button
*ngIf="button.type === 'button'"
[ngClass]="{'disabledButton': !button.selected}"
(click)="buttonPressed(button)"
ngxScrollTo
>
{{ button.text }}
</button>
</div>
Assuming that your button model contains the "selected" property (or you have some other model storing information which button was actually clicked):
buttonPressed(button: Button) {
// Mark only button as selected
this.buttons.forEach(b => b.selected = b === button);
}
And of course add some class in the css:
.disabledButton {
opacity: 0.75;
}
Note - writing this from top of my head (since no stackblitz was provided) so some adjustments might be needed.

Disable mat icon into mat-tree-node

I need the answer to this question: is it possible to disable a mat-icon within a mat-tree-node?
So let me show you my code. Seeing the present mat-tree-node:
<mat-tree [dataSource]="ListView" [treeControl]="treeControl">
<mat-tree-node
*matTreeNodeDef="let node"
matTreeNodePadding
matTreeNodePaddingIndent="20"
class="mat-tree-node node-level-last hover"
>
<button class="cursor-default" mat-icon-button disableRipple="true"></button>
<div class="zone-action">
<div > {{ node.item.name }} </div>
<div class="icon-hover" *ngIf="!node.item.CanVisualize">
<div *ngIf="isEnabled">
<mat-icon
svgIcon="pencil"
color="primary"
(click)="actionReport(node.item, 'update'); $event.stopPropagation()"
></mat-icon>
</div>
</div>
</div>
</mat-tree-node>
I would like to have access to a list openened by the selection of a mat-tree-node, but I can't for the moment. So you have the property-binding " {{ node.item.name }} " that displays an information relative to the object selected which you need to know so as to proceed into the navigation of the component and it is needed to disable or hide the mat-icon inside <div *ngIf="isEnabled">.
But adding a structural directive like an ng-if in the HTML parent Node erase the node.item.name, printing an empty field, which behavior is clearly not the one searched.
Suggestion
<button mat-icon-button ngIf="isEnabled" (click)="actionReport(node.item, 'update'); $event.stopPropagation()">
<mat-icon>favorite</mat-icon>
</button>
<button mat-icon-button ngIf="!isEnabled" disabled>
<mat-icon>favorite</mat-icon>
</button>
https://material.angular.io/components/button/examples
Firstly, you should use a <button mat-icon-button> instead of the <mat-icon> directive:
<button mat-icon-button (click)="onButtonClick()">
<mat-icon>pencil</mat-icon>
</button>
vs
<mat-icon (click)="onButtonClick()">pencil</mat-icon>
Secondly, you can use the disabled input that the MatButton class (essentially a directive for button[mat-*-button]) exposes:
<button mat-icon-button [disabled]="isEnabled">
<mat-icon svgIcon="pencil"></mat-icon>
</button>
Note that the <mat-icon> directive does not support the disabled input.

How to implement Buttons depending on a list?

I want to generate and display as many buttons depending on the number of elements in my list. Can someone tell me how I can implement that?
Currently it is hardcoded like the below code. But often I only have a list with only button 1 and 2. And then I dont need the button 3 and button 4.
Thanks for your help!
list=[button1, button2, button3, button4]
<div class="tabs_item_categories">
<button class="tab_item_category" (click)="button1_active()">
Button1
</button>
<button class="tab_item_category" (click)="button2_active()">
Button2
</button>
<button class="tab_item_category"(click)="button3_active()">
Button3
</button>
<button class="tab_item_category" (click)="button4_active()">
Button4
</button>
</div>
You iterate with *ngFor structural directive in angular:
<div class="tabs_item_categories">
<button class="tab_item_category"
*ngFor="let buttonConfig of buttonConfigs"
(click)="buttonConfig.onClick()">
{{buttonConfig.label}}
</button>
</div>
and in your typescript:
buttonConfigs = [
{
label: 'Button 1',
onClick: this.doSomethingOnButton1Click
},
...
];
doSomethingOnButton1Click is lambda in the component.

Clicking on submenu, in a sidebar, go to a url with Material Design using Angular 4

I am working on a book collection program and I have a static sidebar which will have options and when you click on some of the options it sends you to a url.
I can't get the going to url part to work.
So I just have a sidenav, then a menu item called Store and then a submenu with an item called Amazon.
There may be typos, as I typed this as the code is on a different computer. Basically, how do I get where a submenu will send me to a url? I can do it from the menu item.
<md-sidenav #sidenav mode="side" opened="true" class="app-sidenav">
<md-nav-list>
<button md-list-item>Book Choices</button>
<button md-button>
<span md-list-item
[mdMenuTriggerFor]="amazon">Stores</span></button>
</md-nav-list>
</md-sidenav>
<md-menu #amazon>
<button md-button>
<span md-menu-item>
<span (click)="'http://amazon.com'">Amazon</span>
</span>
</button>
</md-menu>
You cannot navigate to a url using this expression (click)="'http://amazon.com'". You need to use window.location.href or window.open method. Here is how you can do that:
<md-menu #amazon>
<button md-button>
<span md-menu-item>
<span (click)="gotoUrl('http://www.amazon.com')">Amazon</span>
</span>
</button>
</md-menu>
in your typescript code, define the gotoUrl() method:
gotoUrl(url:string){
window.location.href=url;
}
if you want to open the url in a new tab in the browser, then use this code:
gotoUrl(url:string){
window.open(url, "_blank");
}
So while you can use (click) events in angular, if all you need to do is navigate to another url you can always just use good old html and an anchor link. If that's all your looking for keep it simple
<md-menu #amazon>
<button md-button>
<a md-menu-item href="http://amazon.com">
Amazon
</a>
</button>
</md-menu>
If you still want to use a click you can, and the answer below was correct it just had a typo
So add a method in your component like:
goToUrl(url: string) {
window.open(url);
}
And then in your view
<md-menu #amazon>
<button md-button>
<span md-menu-item (click)="goToUrl('http://amazon.com')">
Amazon
</span>
</button>
</md-menu>
this thing (click)="'http://amazon.com'" does nothing at all since you just passed a string.
have you tried (click)="window.open('http://amazon.com', '_blank')"?
or create a function that does the window.open(parameter)
openlink(url: string)
{
window.open(string, "_blank");
}
// HTML attribute
(click)="openlink('http://amazon.com')"

Line break in ngFor loop

I have an ngFor that creates several PrimeNG buttons. Right now, the buttons appear directly after each other on the same row - I would like each button to display on its on line vertically. How do you go about doing that? Here is my ngFor code:
<button pButton type="button"
*ngFor="let atrConfig of atrConfigs; let i = index"
(click)="selectConfiguration(atrConfig)" label = "">
Name: {{atrConfig.name}} <br />
</button>
You should use a ng-container tag which groups elements but doesn't get rendered in the DOM tree as a node.
<ng-container *ngFor="let atrConfig of atrConfigs; let i = index" >
<button pButton type="button"
(click)="selectConfiguration(atrConfig)" label = ""> Name: {{atrConfig.name}}
</button>
<br />
</ng-container>
In this example, it may be just as simple to use CSS, but ng-container can be very useful if you don't want a surrounding div e.g. populating a table
Just add a css class with display: block to your button.
Or add it inline like the next example:
<button pButton type="button" style="display: block;"
*ngFor="let atrConfig of atrConfigs; let i = index"
(click)="selectConfiguration(atrConfig)" label = "">
Name: {{atrConfig.name}} <br />
</button>
I don't have idea if the pButton directive adds styles to the button that can override the display value.