How to assign the first element context with default value? - html

I am using the follwing code to display some values from the array
<div class="row">
<div class="column" *ngFor="let card of cards; let i=index">
<div class="card">
<h3>Card {{card.id}}</h3>
<p>{{card.text}}</p>
</div>
</div>
</div>
But I would like to set the first one is a button with given hard code text. It shouldn't from the array.
I think that probably using ngClass to compare when the index is 0. But not sure how?

Angular has the first and last variables out of the box.
I can't clearly understand what you are asking, but I think you want to show a button only on the first? You can also target the last like below.
<div class="row">
<div class="column" *ngFor="let card of cards; let i=index let first = first; let last = last">
<div class="card">
<h3>Card {{card.id}}</h3>
<p>{{card.text}}</p>
<ng-container *ngIf="first"><button>first item only</button></ng-container>
<ng-container *ngIf="last"><button>last item only</button></ng-container>
</div>
</div>
</div>

You might try something like this:
<div class="row">
<div class="column" *ngFor="let card of cards; let i=index">
<div
class="card"
(click)="((i === 0) || (i === cards.length)) && yourClickEvent($event)"
>
<h3>Card {{ (i === 0) ? 'Your Hard code ID' : card.id }}</h3>
<p>{{card.text}}</p>
</div>
</div>
</div>
The condition in the click event above, will check if its either the first or last card and then implement your click functionality.. so is the case with the ID
Is this what you are trying to achieve?

Related

PrimeNg - Toggle div inline inside ng-template loop

I'm working with PrimeNg picklist and here is what i have:
The focus is on the first row, don't mind the other rows not having the radio button (it's uncompleted testdata).
What i'm trying to achieve is that when you click on the first option 'Good:Stock', the little dropdown to the right with A1 appears. When you select 'Bad', it disappears.
The problem now is that when i select 'Good' for one item, the dropdown will appear for every record in the loop.
I want it to appear only for the item where i selected the radiobutton.
All help is welcome! Ask away if you need more code but i don't think the .ts file matters for now.
Here is what the code looks like:
<label for="productGroup">Select product</label>
<div class="form-group" id="productGroup">
<div class="row">
<div class="col">
<p-pickList [source]="products"
(onMoveToTarget)="onMoveToTarget()"
[target]="selectedProducts" sourceHeader="Available" targetHeader="Selected"
[responsive]="true" filterBy="description,productNumber"
dragdrop="true" dragdropScope="products" [showTargetControls]="false" [showSourceControls]="false"
sourceFilterPlaceholder="Search product in Available"
targetFilterPlaceholder="Search product in Selected"
[sourceStyle]="{'height':'33vh'}" [targetStyle]="{'height':'33vh'}">
<ng-template let-product pTemplate="item">
<div id="product" class="row ui-helper-clearfix">
<div class="col-1 padding-0 brighten">
<img (mouseover)="getProductImage(product)"
[escape]="false"
pTooltip='<img style="max-height: 100%; max-width: 100%" src="{{base64String}}">'
tooltipPosition="right"
src="assets/eye-icon.png" style="max-width: 100%; width: 80%;">
</div>
<div class="col-4">
<div class="row">{{product.description}}</div>
<br>
<div class="row">{{product.productNumber}}</div>
</div>
<div class="col-4" *ngIf="inbound && product.goodLabel && product.badLabelInWarranty &&!hqAdmin&&!carStock">
<div class="row">
<p-radioButton (onClick)="toggleProjects(true, product.id)" name="{{product.productNumber}}"
label="Good: {{product.goodLabel.name}}"
[value]="product.goodLabel" [(ngModel)]="product.quality">
</p-radioButton>
<p-radioButton name="{{product.productNumber}}"
label="Bad: {{product.badLabelInWarranty.name}}/{{product.badLabelOutOfWarranty.name}}"
[value]="product.badLabelInWarranty" [(ngModel)]="product.quality"
(onClick)="toggleProjects(false, product.id)">
</p-radioButton>
</div>
</div>
<div class="col-2 nopadding" *ngIf="goodSelected">
<p-dropdown id="dropdownInput"
[autoWidth]="false"
[options]="projectLabelSelectItems">
</p-dropdown>
</div>
</ng-template>
</p-pickList>
</div>
</div>
</div>
What is happening in you case suppose lets take an example you have 10 rows and your are maintaining one single variable for all row so what happen when the value of that flag become true or false drop-down from all the rows will show or hide.
So what is suggest in the collection take one property extra for this drop-down column.
<div class="col-2 nopadding" *ngIf="goodSelected">
<p-dropdown id="dropdownInput"
[autoWidth]="false"
[options]="projectLabelSelectItems">
</p-dropdown>
</div>
Here goodSelected is single variable insted of add one vriable in property
<div class="col-2 nopadding" *ngIf="product.goodSelected">
<p-dropdown id="dropdownInput"
[autoWidth]="false"
[options]="projectLabelSelectItems">
</p-dropdown>
</div>
And on toggle make goodSelected selected value true or false of selected row only.

scroll to the tag by its value/content after clicking on a link

I have a link whose value is coming from an api and Details of that link are displayed later in the page.
I want to scroll down to specific details. Details are also coming from an api so I can not write an id to each and every detail available.
e.g. HTML
<div class="row ml-0 mr-0 pb-2" *ngFor="let advance of advanceDetails">
<div class="col-4 dl-value"><a (click)="scroll()">{{advance.AdvNumber}}</a></div>
</div>
This is where I want to scroll:
<div class="row ml-0 mr-0" *ngFor="let advance of advanceDetails">
<div class="col-5">
<label class="dl-label">Advance Number</label>
<p class="dl-value">{{advance.AdvNumber}}</p>
</div>
<div class="col-5">
<label class="dl-label">Other Details</label>
<p class="dl-value">{{advance.details}}</p>
</div>
</div>
I want to scroll down by value of advance number. what will be inside scroll() function in ts? Any help would be appreciated. Thanks in advance :)
It’s not the cleanest way, but you can set a unique id to each item with ngFor indexes.
Then, get the element by id with the unique ID (and check if the element exist), finally scroll to it with scrollIntoView function.
Component.html
<div class="list" *ngFor="let advance of advanceDetails; let i = index">
<div class="list-item" id="advanced-{{i}}">
<p>{{advance.details}}</p>
</div>
</div>
Component.ts
scroll(id : any) {
const advancedItemSelected = document.getElementById('advanced-' + id);
if (advancedItemSelected) {
advancedItemSelected.scrollIntoView(true);
}
}

Can you extract part of HTML to template and call it from more than one place

I have duplicate code in my HTML. When I have it in Java i mark the code in IntelliJ and select "extract method" => "replace 2 occurrences".
I want to do the same for HTML and have the following solution, but I think its ugly:
<ng-template #banner1>
stuff...
</ng-template>
<ng-template #banner2>
other stuff...
</ng-template>
<div class="row tight">
<div class="col-sm-6 hidden-print">
<ng-container *ngIf="false; else banner1"></ng-container>
</div>
<div class="col-sm-6 hidden-print">
<div class="col-sm-7">
<ng-container *ngIf="false; else banner2"></ng-container>
</div>
<div class="col-sm-5">
stuff3...
</div>
</div>
<div class="col-sm-8 visible-print">
<ng-container *ngIf="false; else banner1"></ng-container>
</div>
<div class="col-sm-4 visible-print">
<ng-container *ngIf="false; else banner2"></ng-container>
</div>
</div>
The code above WORKS (if I have copy/paste it correctly) but it needs improvement...
The whole reason for the duplicated code is that I want different styling for the code when printing on paper and then viewing on screen.
I don't like this part:
<ng-container *ngIf="false; else banner1"></ng-container>
I want something like
<ng-inject template="banner1"></ng-inject>
or something even better.
There's ngTemplateOutlet directive that can help you with this. The syntax is very simple - <ng-container *ngTemplateOutlet="yourTemplate"></ng-container>
Example - https://stackblitz.com/edit/angular-xh9ebz
You can use property bindings concept something like
TS Side
htmlOfStuff = "<h1>HTML CODE</h1>";
HTML side
<div [innerHtml]="htmlOfStuff"></div>

Add class with [ngClass] depending on local html condition

I have used [ngClass] in the past, applying classes depending on the Boolean value of a variable held in the javascript/typescript before. However I am wondering if it is possible to apply it based on a local HTML boolean value or not?
ie.
<div class="card" *ngFor="let item of data" #panel ngClass="{expanded: isExpanded}">
<div class="header">
<div class="itemName">Text</div>
<div class="itemDir">Some more text</div>
<mat-icon *ngIf="!panel.isExpanded" (click)="panel.isExpanded=true">edit</mat-icon>
<mat-icon *ngIf="panel.isExpanded" (click)="panel.isExpanded=false">cancel</mat-icon>
</div>
</div>
Here, I am displaying one of two icons, depending on the local isExpanded variable defined within the HTML and not the backend.
I am wanting to apply a class based on this value... is it possible?
Here is what I am working on
use like [class.expanded]="isExpanded". binding to class.expanded trumps the class attribute
<div class="card" *ngFor="let item of data" #panel [class.expanded]="panel.isExpanded" [class.notExpanded]="!panel.isExpanded">
you can use *ngIf="true as isExpanded" to make variable on the template
<div class="card" *ngFor="let item of [1,2,3,4];" >
<div class="header" *ngIf="true as isExpanded" ngClass="{expanded: !isExpanded}">
<div class="itemName">Text</div>
<div class="itemDir">Some more text</div>
<div *ngIf="isExpanded" (click)="isExpanded=!isExpanded">edit</div>
<div *ngIf="!isExpanded" (click)="isExpanded=!isExpanded">cancel</div>
</div>
</div>
stackblitz demo πŸ‘πŸ‘
<div class="card" *ngFor="let item of data" #panel ngClass="{expanded: isExpanded}">
<div class="header">
<div class="itemName">{{item.name}}</div>
<div class="itemDir">{{item.directory}}</div>
<mat-icon *ngIf="!isExpanded;else other_content" (click)="isExpanded=true">edit</mat-icon>
<ng-template #other_content>Other Icon goes here</ng-template>
</div>
You can refer the above code which use If and else by template referenced variable which properly toggle between both icon and non Icon

ng-if and col col-50 don't seem to go together?

I am trying to generate a table using angular code in HTML. Now I seem to have how I want the table to look which is how I have set up this code:
<div class="row">
<div class="col col-25">Date</div>
<div class="col col-50">Name of Customer</div>
<div class="col col-25">Hours Used</div>
</div>
What I have done is generated a list in angular code (which is done correctly) and I have ordered them in a certain way with Date being the first entry and Hours Used being the last. To generate the table in HTML, I use this code:
<div class="row">
<div ng-repeat="B in ConvertToTableRow(T) track by $index">
<div class="col col-25" ng-if="$index == 0">
{{ B }} &nbsp
</div>
<div class="col col-50" ng-if="$index == 1">
{{ B }} &nbsp
</div>
<div class="col col-25" ng-if="$index == 2">
{{ B }} &nbsp
</div>
</div>
</div>
Everything in the first row works well and styled to what I need it to be but the second entry (when the index is 1) will never style its table to a col-50 but instead will stick with a col-25. Now I have tested to see the if the values are equal to 1 or 2 but it seems that is working correctly and the infomation is also coming out correctly but its just not styling correctly.
Is it possible to style a table this way using Angular and HTML?
Would it not be better to use ng-class? I think there's an even better way, but this is just off the top of my head. I hope this helps! :) Documentation for ng-class
<div class="row">
<div ng-repeat="B in ConvertToTableRow(T) track by $index">
<div class="col" ng-class="{'col-25': $index % 3 !== 1, 'col-50': $index % 3 === 1}">
{{ B }} &nbsp
</div>
</div>
</div>