How to disable NgbTooltip if tooltip template is empty, in Angular2? - javascript

I'm showing an array of data inside a tooltip, so I used a template. My code looks like:
<ng-template #ToolTipTemplate>
<small *ngFor="let month of data.months; let first = first; let last = last"> {{ month.appliedMonthYear | utc | date:'MM/y' }}{{ last ? '' : ', ' }} </small>
</ng-template>
<span [ngbTooltip]="ToolTipTemplate">Months: {{data.months.length}}</span>
If data.months is empty I do not want the tooltip to appear. Currently if it's empty it shows the tooltip arrow only.
I've tried adding an *ngIf on the <small> tag inside the template, but that didn't work. I've also tried adding *ngIf into <ng-template> to no avail.

Ok, I was finally able to figure it out. Here's what I had to do
<span [ngbTooltip]="(data.months?.length) ? ToolTipTemplate : ''">Months: {{data.months.length}}</span>

You can take the element reference like #t="ngbTooltip" and then manually fire the tooltip. In your case fire it if required or don't show the tooltip at all.
<div
[ngbTooltip]="(data.months?.length) ? ToolTipTemplate : ''"
triggers="manual"
#t="ngbTooltip"
(mouseenter)="(data.months?.length) && t.open()"
(mouseleave)="t.close()">
show Tooltip
</div>

You can disable it with
<span [ngbTooltip]="ToolTipTemplate" [disableTooltip]="true">Months: {{data.months.length}}</span>
See docs for more info: https://ng-bootstrap.github.io/#/components/tooltip/api

Simple way of doing is
<div *ngIf='data.months.length > 0'>
<ng-template #ToolTipTemplate>
<small *ngFor="let month of data.months; let first = first; let last = last"> {{ month.appliedMonthYear | utc | date:'MM/y' }}{{ last ? '' : ', ' }} </small>
</ng-template>
<span [ngbTooltip]="ToolTipTemplate">Show Info</span>
</div>
<div *ngIf='data.months.length === 0'>
<span>Show Info</span>
</div>

You can use disableTooltip input attribute.
https://ng-bootstrap.github.io/#/components/tooltip/api

Related

Why is timeAgo returning null?

I am trying to get the update time iteratively whenever the dropdown opens but it is returning me null. how to make sure onchange event is triggered correctly.
This is what I have tried so far:
<x-nav-dropdown :text="$notificationIcon" :title="text('nav_notifications')" dropdownClass="notifications-dropdown" align="right">
#forelse(Auth::user()->notifications as $notification)
<x-dropdown-item :route="$notification->data['link']" :title="text($notification->data['link_title'])" onchange="getTime()" x-data="{timeAgo : 'null', getTime() {this.timeAgo = moment('{{ $notification->created_at->format('c') }}').locale('{{ str_replace('_', '-', cur_lang()->slug) }}').fromNow();} }" >
<span style="display: inline-block;">{{ text($notification->data['subject']) }}</span>
<time style="float: right;" x-text= timeAgo> </time>
</span>
<br/>
<small>{{ array_key_exists('data', $notification->data) && !empty($notification->data['data']) ? new \Illuminate\Support\HtmlString(vsprintf(text($notification->data['message']), $notification->data['data'])) : text($notification->data['message']) }}</small>
</x-dropdown-item>
#empty
<x-dropdown-item route="#" :title="text('notifications_none')">
{{ text('notifications_none') }}
</x-dropdown-item>
#endforelse
</x-nav-dropdown>
For example desired out should be:
"x"-minuets ago
Am I doing it right? Can I call the onchange event into bootstrap tags? Any kind of help in right direction?
Thanks in advance!

How to loop through unknow number of nested json object in Angular with ngFor?

I'm trying to display all the reply from this json :
https://www.reddit.com/r/AskReddit/comments/k8w43d/people_with_the_last_name_pepper_who_have.json
So, depending of the post im loading and the reply, my number of children will differ. How can I loop throught it until I reach the last reply with children (body[2].data.children) ?
Like this :
<div class="replies-box" *ngFor="let reply of comments.body[1].data.children">
<div class="reply-header">
<p class="reply-author"><b>From</b> : {{ reply.data.author }}</p>
<p class="reply-send"><b>Send</b> : {{ this.getDateReply(reply.data.created_utc) }}</p>
</div>
<div class="text-first-reply" [innerHTML]="this.getHtmlDecode(reply.data.body_html)">
</div>
</div>
I have only the first level of reply, is there a way to simply loop through them all ?
Thanks in advance.
I would use a recursion type of approach.
Develop a app-comment component and if comment has children, loop over the children and display the app-comment. That way it will loop over the comments until no more children
<div *ngIf='comment'>
<span *ngIf='comment.kind; else showComment'>Kind: {{ comment.kind }}</span>
<ng-template #showComment>
<span>{{ comment }}</span>
</ng-template>
<div>
<app-comment *ngFor='let child of comment.data?.children' [comment]='child'> </app-comment>
</div>
</div>
See this sample illustration
Simply use ngFor inside ngFor with help of ng-container (will not create extra dom elements)
<div class="replies-box">
<ng-container *ngFor="let commentBody of comments.body">
<ng-container *ngFor="let reply of commentBody.data.children">
<div class="reply-header">
<p class="reply-author">
<b>From</b> : {{ reply.data.author }}
</p>
<p class="reply-send">
<b>Send</b> : {{ this.getDateReply(reply.data.created_utc) }}
</p>
</div>
<div class="text-first-reply" [innerHTML]="this.getHtmlDecode(reply.data.body_html)">
</div>
</ng-container>
</ng-container>
</div>

How an i change the pagination-control numbers(1 2 3) to other values like 'Anything1 Anything2 ...' using ngFor* on array in ngx-pagination?

Is it possible to replace ngx-pagination's 'pagination-control'? By defaults, page numbers are showing like '1 2 3'. And I want to replace them with a string value in the array.
<pagination-controls (pageChange)="pageChange($event)" class="my-pagination"></pagination-controls>
The above code will display pagination numbers like
I want to replace the number with values from an array [Anything1, Anything2, Anything3].
Here my data is fixed and I know my page number count and its details.
You need to have look at custom template of ngx-pagination. In customization part you may try to add your Anything before {{page.label}}.
Custom Template example can be found here. http://michaelbromley.github.io/ngx-pagination/#/custom-template
<pagination-template #p="paginationApi"
[id]="config.id"
(pageChange)="config.currentPage = $event">
<div class="custom-pagination">
<div class="pagination-previous" [class.disabled]="p.isFirstPage()">
<a *ngIf="!p.isFirstPage()" (click)="p.previous()"> < </a>
</div>
<div *ngFor="let page of p.pages" [class.current]="p.getCurrent() === page.value">
<a (click)="p.setCurrent(page.value)" *ngIf="p.getCurrent() !== page.value">
<span>Anything{{ page.label }}</span>
</a>
<div *ngIf="p.getCurrent() === page.value">
<span>Anything{{ page.label }}</span>
</div>
</div>
<div class="pagination-next" [class.disabled]="p.isLastPage()">
<a *ngIf="!p.isLastPage()" (click)="p.next()"> > </a>
</div>
</div>
</pagination-template>

How to remove plain text URL from data content column name offilneURL?

I face issue Cannot hide or remove URL exist as plain text on column name offilneUrl
I already do as link so that no need to plain text URL above
So I need to hide or remove or empty URL plain text above word page link .
<tbody>
<ng-container *ngFor="let repcon of ReportControl">
<tr *ngFor="let rep of contentBody">
<td *ngFor="let coln of headerCols">
<span>
{{rep[coln]}}
</span>
<div *ngIf="coln==repcon.fieldName">
<div *ngIf="repcon.columnType==1">
<a (click)="goToLink(rep.offilneURL)">page link</a>
</div>
</div>
</td>
</tr>
</ng-container>
</tbody>
I try as below
{{rep.offilneURL || " "}} but it repeated offlineURL with every row
so what i do to solve issue
see image below the text with green color that i need to remove because it .
post updated
structure of content body on ts file
this._displayreport.GetReportDetailsPaging(this.searchData).subscribe((data: any[]) => {
this.reportdetailslist = data;
this.headerCols = Object.keys(data[0]);
this.contentBody = data;
});
data structure for content body :
companyName: "Innovasic, Inc."
done: "0"
notImpacted: "0"
notificationDate: "2009-11-12"
offilneURL: "https://source.z2data.com/2019/1/13/8/55/47/351/662203977/21527_SPCN.PDF"
onlineURL: "N/A"
pending: "3"
reportDate: "2020-05-07"
revisionID: "272299243"
teamName: "MFG"
totalCount: 79
already have link
Updated post
https://stackblitz.com/edit/create-4ud1rg?file=app%2Fapp.component.html
according to my structure I need to change
<span *ngIf="coln != 'onlineURL'">
{{rep[coln]}}
</span>
to
<span *ngIf="coln != 'repcon.filedName'">
{{rep[coln]}}
</span>
It's just because:
<span>
{{rep[coln]}}
</span>
is still displaying the value regardless so just hide it if the column is the url
<span *ngIf="repcon.columnType != 1">
{{rep[coln]}}
</span>
Base on the content body structure and logic you shared, you can hide the link as follows.
Based on logic ==>
<span *ngIf="repcon.columnType!=1">
{{rep[coln]}}
</span>
I think you are showing the link based on the condition repcon.columnType==1, So check for converse to hide the offline link.
This can be handled in other way as well.
Based on structure ==>
<span *ngIf="coln != 'onlineURL'">
{{rep[coln]}}
</span>
Hope this helps.

AngularJS- Items within ng-repeat not updating on variable update

I have an array called altSegments, and based on $scope.firstSeg or $scope.lastSeg I'd like to display different parts of that same array. In most cases I change the altSegments array alltogether and it updates fine, but when I go from the same altSegments array to the same array but change the $scope.firstSeg and $scope.lastSeg it doesn't update properly.
I suspect it has something to do with altSegments not having changed and therefore AngularJS deciding that it's not worth it to go over the code again and re-display. How would I get around this?
<li ng-repeat="altseg in altSegments">
<!-- For multiflight home to first -->
<div ng-show="{{firstSeg}}" ng-repeat="flights in altseg.segment_details_1.leg_details">
<p class="small dark">
<strong>Flight:</strong> {{flights.Carrier}} {{ flights.FlightNumber}}
</p>
<p class="small dark">
<strong>Departure:</strong> {{flights.OriginName}} | {{flights.DepartureTime | splitDT }}
</p>
<p class="small dark">
<strong>Arrival:</strong> {{flights.DestinationName}} | {{flights.ArrivalTime | splitDT }}
</p>
</div>
<!-- For multiflight last to home -->
<div ng-show="{{lastSeg}}" ng-repeat="flights in altseg.segment_details_2.leg_details">
<p class="small dark">
<strong>Flight:</strong> {{flights.Carrier}} {{ flights.FlightNumber}}
</p>
<p class="small dark">
<strong>Departure:</strong> {{flights.OriginName}} | {{flights.DepartureTime | splitDT }}
</p>
<p class="small dark">
<strong>Arrival:</strong> {{flights.DestinationName}} | {{flights.ArrivalTime | splitDT }}
</p>
</div>
ng-show is an angular directive and evaluates angular code;
Therefore; you do not need : ng-show="{{firstSeg}}"
Remplace with : ng-show="firstSeg"
See full documentation of ng-show here: https://docs.angularjs.org/api/ng/directive/ngShow
it looks like you are using ng-show="{{firstSeg}}" this should be ng-show="firstSeg" ..
If still doesn't work,
Try to update the data from controller side in $scope.apply() ...
e.g :-
$scope.apply(function(){
list = updated_list; // put your updation of list here
});

Categories

Resources