Angular 8 ngIf creates empty element when false - html

I have a problem with Anguar8 and ngIf:
I have a code that creates div which loads some images and their details to a page from a json with conditon:
HTML Code:
<div class="row" >
<div class="col-md-2 col-6 col-sm-4" style="margin-bottom: 1em;" *ngFor="let item of product; let i=index"> <br>
<div class="box" *ngIf="i>35">
<img [src]="item.photo" alt="image slide" style="display: block; width: 100%;">
<div class="text-center">
<h6>{{item.name}}</h6>
<h6>MRP : ₹ {{item.price}}</h6>
</div>
</div>
</div>
</div>
The problem is, that angular creates an empty div with this comment in it:
<div _ngcontent-oio-c3="" class="col-md-2 col-6 col-sm-4" style="margin-bottom: 1em;"><br _ngcontent-oio-c3=""><!--bindings={
"ng-reflect-ng-if": "false"
}--></div>

You may write *ngFor="let item of product | slice:0:35;".
Reference https://angular.io/api/common/SlicePipe

There are two options:
1.You can filter the list using pipe to avoid
2.You can try this should not create any template
<div *ngIf="i>35; else noData">
{{data}}
</div>
<ng-template #noData>
</ng-template>

Related

modal button to display images in angular

In my project I want to show images when I click the button. How I can configure the method openModal() on (click) to do this?
The IMG are taken from assets directory, and change based on your code (B1, B2) choice.
<!-- OPERATION -->
<div class="card my-5">
<div class="card-header" style="text-align: center; font-size: 20px;">
<p><strong>Operation</strong></p>
</div>
<div class="card-body">
<form>
<div class="form-group">
<tr *ngFor="let arr of varOperation; index as i">
<td>
Code: {{arr.operation.code}}
- {{arr.operation.description}}
</td>
<button style="margin-left: 20px; float: right;" class="btn btn-primary" (click)="viewCodeOperation(arr.operation.code)" (click)="openModal()">
Go
</button>
</tr>
</div>
</form>
</div>
</div>
<!-- IMAGES -->
<div class="overflow-auto">
<div *ngIf="imgB1">
<img src="assets\images\B1.jpg">
</div>
<div *ngIf="imgB2">
<img src="assets\images\B2.jpg">
</div>
</div>
viewCodeOperation(code: string) {
this.imgB1 = false
this.imgB2 = false
console.log(code)
if(code == "B1"){
this.imgB1 = true
}
else if(code == "B2"){
this.imgB2 = true
}
}
openModal() {
}
You can try using a library like this https://github.com/maximelafarie/ngx-smart-modal one to set up modals in angular.

How to make a Textbox editable on click and add a button to the side Angular

I am trying to add a feature just like stack overflow comments where clicking on the edit link the div transforms to a text box and we get a submit button .
But the problem is i have multiple comments which i am populating via ngFor how do i remove the property readonly from the selected div in which the edit has been clicked .
This is what i have tried.
<div class="tab-content">
<div id="email" class="tab-pane active">
<div *ngFor="let i of comments; let index = index" [#flyInOut]>
<div class="well">
<input type=”text” value="{{i.comment}}" [readonly]="false" /><span>
Edited <time>{{today | amDifference: i.createdAt :'minutes'
: false}}</time> before
</span><a><i
class="align remove glyphicon glyphicon-remove-sign glyphicon-white"
(click)="edit(index)"></i></a>
</div>
</div>
</div>
</div>
I also i would love to have something like checking time i have already done the backend part of same how to only enable the edit button for the comment where the amDifference is less than 5 mins and then we show a delete option.
You can use ngIf-Else to provide a second template to show like such:
<div class="tab-content">
<div id="email" class="tab-pane active">
<div *ngFor="let i of comments; let index = index" [#flyInOut]>
<div *ngIf="i.editMode; else editBlock" class="well">
<!-- Show stuff here -->
<a>
<i class="align remove glyphicon glyphicon-remove-sign glyphicon-white"
(click)="i.editMode=true">
</i>
</a>
</div>
<ng-template #editblock>
<div class="well">
<!-- Edit stuff here -->
<input type="button" (click)="i.editMode=false" value="Done"/>
</div>
</ng-template>
</div>
</div>
</div>

add class to the element when clicked from ng-repeat

I just want to add a tooltip to the element which is clicked.
Tooltip is added to all repeat elements when clicked. Please help me.
<div ng-repeat="item in listOfMenu" class="repeat_container">
<div ng-repeat="menu in item" class="repeat_block" ng-click="getTool(menu,menu.pricelist.length)" >
<div class="shadow img_cont">
<img src="{{menu.itemimage}}" class="item_img">
<div ng-repeat="innerItem in menu.pricelist | limitTo:1">
{{innerItem.itemprice}}
</div>
</div>
<div>
{{menu.menuitemname}}
</div>
<div ng-repeat="menu in addToCart" class="add_circle" ng-show="circle">
{{menu.quantity}}
</div>
</div>
</div>
Change the div in:
<div ng-repeat="menu in item" class="repeat_block" ng-click="getTool(menu,menu.pricelist.length)" ng-class="{'clicked': menu.clicked}">
In getTool method
menu.clicked = true;
but you should put clicked:false to all others menu in items

How do I identify Xpath when there are multiple elements with the same attributes and text?

I need to click on the link that says "Customer One". Currently I am using
//div[contains(#class,'client-info') and contains(div/text(),'Customer')]
Using Firepath, this returns four seperate elements (I have attached code that includes two of them), and I think that is why Selenium Webdriver is unable to find the element I would like to click.
I Need to click the very last instance of this xpath, but it doesn't appear possible to be any more specific, as they have the same class and inner text!
<div class="wg-client-row-mobile hidden-sm hidden-md hidden-lg">
<div class="row">
<div class="col-xs-11">
<span class="icon icon-user" ng-class="{'icon-user': !wgClientItemCtrl.client.isAnOrganization, 'icon-business': wgClientItemCtrl.client.isAnOrganization}"/>
<div class="client-info">
<div class="client-name not-long-text ng-binding">Customer One</div>
<!-- <div class="client-age not-long-text" ng-if="!wgClientItemCtrl.client.isAnOrganization">{{wgClientItemCtrl.client.gender}}, {{wgClientItemCtrl.client.calculatedAge | notAvailable}}</div> -->
<!-- ngIf: !wgClientItemCtrl.client.isAnOrganization -->
<div class="client-age not-long-text ng-binding ng-scope" ng-if="!wgClientItemCtrl.client.isAnOrganization">
<!-- end ngIf: !wgClientItemCtrl.client.isAnOrganization -->
<!-- ngIf: wgClientItemCtrl.client.isAnOrganization -->
<div class="client-age not-long-text ng-binding">
</div>
</div>
<div class="favorite-right-container">
</div>
</div>
<div class="wg-client-row-desktop hidden-xs hidden-is">
<div class="row content">
<div class="col-sm-4">
<div class="icon icon-user" ng-class="{'icon-user': !wgClientItemCtrl.client.isAnOrganization, 'icon-business': wgClientItemCtrl.client.isAnOrganization}"/>
<div class="client-info">
<div class="client-name not-long-text ng-binding">Customer One</div>
</div>
You can use last() to get the last instance matched by the inner XPath :
(//div[contains(#class,'client-info') and contains(div/text(),'Customer')])[last()]

Angular ng-repeat that works fine in FF somehow comments out in Chrome

I've got this code in the jsp (sized down a bit):
<div class="popup default" ng-app="interview" ng-init="employeeId = '${employee.id}'; findTimelineEntries(); getAddInterviewRights(); getEditInterviewRights();" ng-controller="TimelineCtrl">
<div class="box-wrapper edit" ng-show="hasAddInterviewRights">
<div class="box">
<div class="pointer"></div>
<div class="box-content">
<div class="icon close" ></div>
<div class="form-item">
<!-- cut -->
</div>
</div>
<div class="form" id="convo">
<div class="form-item">
<!-- cut -->
</div>
<div class="form-break"></div>
<div class="form-item">
<div class="label">
<div class="fi-content">
Currently open goals
</div>
</div>
<div class="value">
<div class="editable" ng-repeat="goal in interviewForm.goals" ng-click="openEditable($event.target)">
<div class="icon edit"></div>
<div class="icon close" ng-click="closeEditable($event.target)"></div>
{{goal.shortDescription}}
<div class="ed-content">
<div class="form-item">
<div class="label">
<div class="fi-content">
Deadline
</div>
</div>
<div class="value">
<input type="text" ng-model="goal.dueDate" ui-date="dateOptions" size="15" />
</div>
</div>
<div class="form-item">
<div class="label">
<div class="fi-content">
Status
</div>
</div>
<div class="value select">
<select ng-model="goal.status" ng-options="code as description for (code, description) in goalStatusses"></select>
</div>
</div>
<div class="form-item">
<div class="label">
<div class="fi-content">
Comment
</div>
</div>
<div class="value">
<div class="fi-content">
<table class="plain">
<tr ng-repeat="progress in goal.progresses">
<td>{{progress.progressDate | date: 'dd-MM-yyyy'}}</td>
<td>{{progress.progressReport}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="editable">
<div class="icon add"></div>
<div class="icon close" ng-click="closeEditable($event.target)"></div>
Add a new goal
And it works in Firefox (20.0.1) just like it should: It shows 2 current goals and the option to add a new goal. But somehow the same jsp doesn't work that well in Chrome (27) as it just shows the option to add a new goal
When looking into the HTML with the Developer Tools I see that the ng-repeat is commented out by Chrome, but why would it do that??
I googled on ng-repeat getting commented out, but the answer there was that the div using the ng-repeat was not inside the div with the ng-controller, but that's certainly not the case with my code
The HTML taken from the Developer Tools:
<div class="value">
<!-- ngRepeat: goal in interviewForm.goals -->
<div class="editable">
<div class=icon add"></div>
<div class=icon close" ng-click="closeEditable($event.target)" style="dispay:none;"></div>
Add new goal
I've checked other browsers and it doesn't work in Safari (5.1) either and also doesn't work in IE8 although a colleague says it does work in his IE9
Well, I finally found what was going wrong and it actually was a
$('.select .option').click(function() {
var choice = $(this).text();
etc.
that had to be changed into
$(".select #itemAddSelector").change(function(){
var selectedOption = $(this).children(":selected");
var choice = $(selectedOption).text();
etc.
As the function that retrieves the goals from the controller was never called in Chrome, because Chrome doesn't process a jQuery click event on an option (Click event on select option element in chrome).
So it just commented in the HTML about ng-repeat saying it had tried to iterate over the goal objects, but there were no objects present ... pfff, I've been looking in the wrong direction for too long.