I have below code
<p-tabView #tabview *ngIf="mycondtion" class="page" [scrollable]="scrollable">
<ng-container *ngFor="let list of lists">
<p-contextMenu [target]="link" [model]="items"> </p-contextMenu>
<p-tabPanel [header]="list.listName" #link>
<app-data-module [List]="list"></app-data-module>
</p-tabPanel>
</ng-container>
on rightclick of tabpanel, it should show the context menu, but its not showing, i dont know what am i missing here? please help
You might be able to use header template (instead of a "header="). Something like this:
<p-tabView #tabview *ngIf="mycondtion" class="page" [scrollable]="scrollable">
<p-tabPanel *ngFor="let list of lists">
<ng-template pTemplate="header">
<!-- Here is where all the header content will go, including the context menu -->
<div #link>{{list.name}}</div>
<p-contextMenu [target]="link" [model]="items"</p-contextMenu>
</ng-template>
<!-- Here is where the content of the tab will go -->
<app-data-module [List]="list"></app-data-module>
</p-tabPanel>
</p-tabView>
The main flaw here is, the context menu only appears when right-clicking on the <div>; clicking anywhere else in the tab header still won't work. I've not found a way around that, but hopefully this will help get you in the right direction.
Related
I would like to use DragDropModule for my angular application so I can move panels that are stored inside templates (for practical purposes as well as for recursive plotting of child elements).
The problem that I have is that cdkDrag can't find the correct cdkDropList to drop into if cdkDrag is hidden within a template and is not directly nested under the HTML element. Example:
<div
cdkDropList
[cdkDropListData]="expanded.activities"
(cdkDropListDropped)="dropActivity($event)">
<div *ngFor="let activity of expanded.activities">
<ng-container [ngTemplateOutlet]="orangeProgramActivity"></ng-container>
</div>
</div>
<ng-template #orangeProgramActivity>
<div cdkDrag>This is just a test</div>
</ng-template>
With this code example, the orangeProgramActivity can be dragged anywhere but doesn't drop into the correct dropList as cdkDrag keyword can't find any droplist within its own template.
In the second example, everything works correctly and the item gets dropped into correct dropList:
<div
cdkDropList
[cdkDropListData]="expanded.activities"
(cdkDropListDropped)="dropActivity($event)">
<div *ngFor="let activity of expanded.activities">
<div cdkDrag>This is just a test</div>
</div>
</div>
I would like to achieve the same functionality as in the second example, but with the use of templates because I really need them for recursion. Unfortunately, I can't reveal the whole code as my employer wouldn't be happy with that.
All I need is some static reference for my cdkDrag that is inside a template, to point onto a correct element with dropList that is outside of the template.
These are the only solutions that I found on the internet and they don't seem to work for me:
Material 7 Drag and Drop ng-template incompatibility
CdkDragDrop and ngTemplateOutlet
This is my first question on Stack Overflow and I'm new to angular, so I'm sorry for any confusion in my post, and thanks for any help in advance!
This might not work for all use cases, but you could just write it like this:
<div
cdkDropList
[cdkDropListData]="expanded.activities"
(cdkDropListDropped)="dropActivity($event)">
<div *ngFor="let activity of expanded.activities" cdkDrag>
<ng-container [ngTemplateOutlet]="orangeProgramActivity"></ng-container>
</div>
</div>
<ng-template #orangeProgramActivity>
<div>This is just a test</div>
</ng-template>
I was lucky that I only need to reorder elements inside an array in which they are and I don't need to transfer them into other containers. So for my "root" activities, I used your simple solution to wrap it all in a draggable element.
<div cdkDropList [cdkDropListData]="expanded.activities" (cdkDropListDropped)="dropActivity($event)">
<!-- For every object in array make a container with template and an icon that will serve as a handle -->
<div *ngFor="let activity of expanded.activities">
<div cdkDrag>
<div cdkDragHandle>
<!-- Handle icon from FontAwesome -->
<i class="fas fa-grip-vertical"></i>
</div>
<!-- Container with a template that we need -->
<ng-container [ngTemplateOutlet]="orangeProgramActivity" [ngTemplateOutletContext]="{act: activity}"></ng-container>
</div>
<!-- Recursive template for children -->
<ng-container [ngTemplateOutlet]="childActivitiesRecursion" [ngTemplateOutletContext]="{act: activity}"></ng-container>
</div>
And for my recursion, I created a droplist inside a template that serves only for reordering these children activities.
(I had problems with pasting template so the ng-template tag is not terminated at the end of the code)
<ng-template let-act="act" #childActivitiesRecursion>
<!-- Droplist inside a template for reordering child activites -->
<div cdkDropList [cdkDropListData]="act.childActivities" (cdkDropListDropped)="dropActivity($event)">
<!-- Iterates through all child activities -->
<div *ngFor="let childActivity of act.childActivities">
<div cdkDrag>
<div cdkDragHandle>
<i class="fas fa-grip-vertical"></i>
</div>
<!-- Different template for child activities -->
<ng-container [ngTemplateOutlet]="blueProgramActivity" [ngTemplateOutletContext]="{act: childActivity}"></ng-container>
</div>
<!-- Recursion for even deeper child activites -->
<ng-container [ngTemplateOutlet]="childActivitiesRecursion" [ngTemplateOutletContext]="{act: childActivity}"></ng-container>
</div>
</div>
I will accept Richard's answer as a solution because if you are able to solve it like this, it's definitely the most elegant solution you can do. But there would be still an issue if you needed to transfer items into different containers after using templates for recursion!
I'm trying to close and open a new div in a ng-template element. When I try this my code breaks.
<div class="row">
<ng-template ngFor let-i="index" let-data [ngForOf]="dataArray">
<app-user-dashboard-gauge [gaugeData]="data" class="col"></app-user-dashboard-gauge>
<ng-template [ngIf]="i === 3">
</div>
<div class="row">
</ng-template>
</ng-template>
</div>
I'm trying to do this inside a ngFor to preserve my bootstrap rows. Does anyone know how to fix this or maybe another solution?
Edit: Ok I think I want that clear on what I wanted to happen. I update my code block and will try to explain it better. On the third iteration of my for loop I want the row div to be closed and a new one to open. And the rest of the <app-user-dashboard-gauge> to go in the second row div.
Okay I fixed it. It might not be the best or the nicest looking but i split the incomming data into two parts and made another for loop for the secend group of data.
<div style="background-color: #202020">
<div class="row">
<ng-template ngFor let-data [ngForOf]="dataArray1">
<app-user-dashboard-gauge [gaugeData]="data" class="col"></app-user-dashboard-gauge>
</ng-template>
</div>
<div class="row">
<ng-template ngFor let-data [ngForOf]="dataArray2">
<app-user-dashboard-gauge [gaugeData]="data" class="col"></app-user-dashboard-gauge>
</ng-template>
</div>
</div>
Im still open for feedback if someone knows a better solution but this fix will suffice for now.
<ng-container *ngIf="i !== 3">
<div class="row">
</div>
</ng-container>
I use ngb-tabset in a component which is under a single div section. This div tag is displayed based on a condition to be true. When the condition is false, a different section is displayed.
<div *ngIf="showAllTabs">
<ngb-tabset>
<ngb-tab id="heading-1">
<ng-template ngbTabTitle>
<div>HEADING 1</div>
</ng-template>
</ngb-tab>
<ngb-tab id="heading-2">
<ng-template ngbTabTitle>
<div>HEADING 2</div>
</ng-template>
</ngb-tab>
</ngb-tabset>
</div>
<div *ngIf="!showAllTabs">
<!-- Some other work -->
</div>
The issue is, if for instance,the active tab is "heading-2", and when the division tag is hidden and shown again, the active tab is set to the first tab (heading-1) automatically. How to not allow this?
The reason was because of the structural directive "ngIf". ngIf removes the elements from the DOM and so, when the ngIf turns out to be true, the elements are rendered newly which causes the default tab to be made visible. This can be solved by programming the tab selection by storing the id of the tab in a variable and enabling it each time the DOM elements are rendered back.
I am trying to display data on each and every tab, but the issue is the data I have is relatably large to fit in a single screen.
I am looking for a way to make tabs scrollable so that I can scroll on the data.
Is there any way to add buttons on the edges of the tabs or add a horizontal scrollbar to make it scrollable?
Something like this, which is responsive too.
Thanks
You can solve it through Angular material Tabs. Here, is the documentation of angular.
https://material.angular.io/components/tabs/examples
Remember, you have to import MatTabModule on your angular module, like below:
I have added it on my project and a sample image is like below:
Additionally, if you want to add a button instead of text, you can do it also. Here is a sample image for you:
Here, sample code for this is
<mat-tab-group>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="example-tab-icon">thumb_up</mat-icon>
First
</ng-template>
Content 1
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="example-tab-icon">thumb_up</mat-icon>
Second
</ng-template>
Content 2
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="example-tab-icon">thumb_up</mat-icon>
Third
</ng-template>
Content 3
</mat-tab>
</mat-tab-group>
You can use any mat-icon class here to change the button icon. You can use this link https://material.io/resources/icons/?style=baseline .
Hopefully, it will solve your problem.
I have a tabView and a list of tab-panels.
Based on runtime conditions, I need to hide and unhide one of the tab panels.
Can not find a way to do this using looking at their docs or here.
Any suggestions?
In general is there a way to dynamically add and remove tab panels?
Code I am using now that is not working, my test syntax must be wrong:
<div [ngSwitch]="isNEC">
<ng-template ngSwitchCase="'true'">
<p-tabView>
<p-tabPanel header="Detail">
<linechart #linechart></linechart>
</p-tabPanel>
<p-tabPanel header="Assessment">
Coming soon to a theater near you !!!!
</p-tabPanel>
</p-tabView>
</ng-template>
<ng-template ngSwitchCase="'false'">
<p-tabView>
<p-tabPanel header="Detail">
<linechart #linechart></linechart>
</p-tabPanel>
</p-tabView>
</ng-template>
</div>
unless I put a switch default, nothing ever shows up.
isNEC is a component public attribute of type string
all is well, I just needed to check for 'true' and not "'true'"