Overflow the PrimeNG DialogModule with the CalendarModule - css

I want to build an Edit popup dialog with an input form in Angular2 using the PrimeNG widgets. I run into trouble with dynamic content of that dialog box (see screenshot).
I've naïvely been trying to wrap the CalendarModule in a div that is positioned above the other elements. (see Angular Template HTML below)
<p-dialog [(visible)]="display" [modal]="true" [resizable]="false">
...
<table class="ui-datatable-responsive">
<tbody>
<tr>
...
</tr>
<tr>
<td class="ui-cell-data">Start By:</td>
<td class="ui-cell-data">
<div [style]="generateSafeStyle('position:relative; z-index:1000')">
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="value"></p-calendar>
</div>
</td>
</tr>
</tbody>
...
</table>
</p-dialog>
However it seems the DialogModule frames all its content. Is there a hack to overflow that frame?
How would you handle that?
Thank you.
P.S: The generateSafeStyle Function just uses an injected DomSanitizer and works fine.
generateSafeStyle(style:string):SafeStyle{
return this.sanitizer.bypassSecurityTrustStyle(style);
}

just use appendTo="body", it will show calendar above all, even if it is in table, popup or scroll panel
<p-calendar [(ngModel)]="invariable.value" dateFormat="mm/dd/yy" required appendTo="body" readonly></p-calendar>

So I would guess things have changed since this was originally asked, but I found that if I added
[contentStyle]="{'overflow': 'visible'}"
to the p-dialog it allowed the calendar popup to overflow the dialog border.

The only thing that worked so far were the following style options:
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="dueDate" [style]="{'position': 'fixed', 'overflow': 'visible', 'z-index': '999'}">
This however smashed up the table. So I got rid of the table and used flexboxes to align the elements. Looks better anyway like this.

It's related to overflow:auto on .ui-dialog-content
In dialog there is a div with class .ui-dialog-content make overflow:visible in that div and it will fix this problem.

If you check official PrimeNG Calendar documentation, you will find list of attributes for calendar component, among them there's style attribute which you can use to add needed CSS:
<p-calendar dateFormat="dd.mm.yy" [(ngModel)]="value"
[style]="{ 'position': 'relative', 'z-index': '1000' }"></p-calendar>

I found a better solution for this. Just add a method on click listeners and select element ui date picker
(click)="modifyStyle()"
In ts file import elementRef and Renderer2
constructor(private ele: ElementRef, private ren: Renderer2)
{}
modifyStyle()
{
let ui = this.ele.nativeElement.querySelector(".ui-datepicker");
if(ui)
this.ren.setStyle(ui, "top", "unset")
}
That's it.

Related

How to set Height of p-table to window height

Problem:
I'm trying to set the height of a prime p-table in angular. I already searched the net and found so many results but none worked so far (probably due to this problem beeing around for many years and changes to the framework disabled certain solutions).
I already tried two approaches the first is in the code below. The second is setting the height of the parent div of the p-table to innerWindowHeight and setting scrollheight of p-table to flex (doesn't work either).
Tools: Angular 14.2.0 and PrimeNG 14.1.1 in a fresh project
I have the following html code in app.component.html:
<div>
<p-table #table
(window:resize)="onResize()"
[value]="data"
[paginator]="true"
[showCurrentPageReport]="true"
[scrollable]="true"
[scrollHeight]="tableScrollHeight"
[rows]="10"
[rowsPerPageOptions]="rowsPerPage"
styleClass="p-datatable-gridlines p-datatable-striped p-datatable-sm"
currentPageReportTemplate="{first} to {last} of {totalRecords} records">
<ng-template pTemplate="header">
<tr>
<th>Date</th>
<th>ID</th>
<th>Description</th>
<th>Value</th>
<th>Tax</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-entry>
<tr>
<td>{{entry.date}}</td>
<td>{{entry.id}}</td>
<td>{{entry.description}}</td>
<td>{{entry.value}}</td>
<td>{{entry.tax}}</td>
</tr>
</ng-template>
</p-table>
</div>
And the following app.component.ts :
import {Component} from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Testapp';
data: any[];
tableScrollHeight: string = "700px";
rowsPerPage: number[] = [5, 10, 20, 50];
constructor() {
this.data = [];
let entry: any = {};
entry.description = "First entry";
this.data.push(entry);
}
onResize() {
this.tableScrollHeight = window.innerHeight + 'px';
}
}
Behaviour I want to implement:
What I want is, that the Paginator stays at the bottom of the window even if the table is empty or dosen't have enough entries to fill the window and that the table is scrollable (header staying at top) as soon as the table rows are bigger than the screen size.
To clarify what I want to acomplish here a screenshot how it looks:
How it looks right now
And here a screenshot how I want it to look:
What it should look like
Question:
Is it possible to acomplish this in a clean way?
Like suggested in the comment I added a stackblitz : https://angular-ivy-sfk7pw.stackblitz.io
Edit:
I found that if you set scrollHeight of table a div inside the table (generated from primeng) with class p-datatable-wrapper gets the style "max-height: XXXpx" where as XXX is the value from tableScrollHeight. I could probably write a CSS selector to change the style to min-width but that's probably not a good Idea since I would have to access the dom from the typscript file and search for the auto generated div.
Maybe you can try to add this style to your css/scss, but this is not a best practice.
.p-datatable-wrapper {
min-height: calc(100vh - 90px);
}
Note: 100vh is your screen height and 90px it's an example your pagination height.
That's it. I hope it can help.

Angular 6: Update NG Style with function

I'm here today because I'm wondering something about the NG Style with Angular (my version being the 6). How can i update [ngStyle] when I use a function to return a value.
As always, here is a simplified example of my problem:
I generate div from an array of objects.
For each section, there are two div: one on the left and one on the right.
The size of the left div changes depending on the content, so it can do both 50px and 125px.
I want the right div to fit the size of the one on his left, always half that size (2 in getLeftDivHeight).
Obviously, this will be done in each section (Container).
How can I make the ngStyle update when the div's height to the left changes (due to resizing, adding content, or page display time)? )
Here is the code:
HTML
<section class = "Container" *ngFor="let oneContent of allContent">
<div id = "{{oneContent.id}}" style="float: left">
<p> {{oneContent.Content}} </ p>
</div>
<div style="float: right" [ngStyle]="height: getLeftDivHeight(oneContent.id, 2)">
</div>
</div>
Typescript (only the related function)
getLeftDivHeight(id: string, divisionNumber: number): string {
height = document.GetElementById(id).getBoundingClientRect().height /
divisionNumber;
return height + 'px';
}
Note that I am not looking for an HTML solution, but an Angular one, the code above is just an example to explain my problem.
Thank you in advance
You could return the whole style string, for example height: 100px, from the getLeftDivHeight method
getLeftDivHeight(id: string, divisionNumber: number): string {
height = document.GetElementById(id).getBoundingClientRect().height / divisionNumber;
return `height: ${height}px`;
}
or you could use the below syntax in the template
[style.height.px]="getLeftDivHeight(parameters)"
return only numerical height value from the method.
So, I finally manage to do it, using a directive.
I used ElementRef to access the HTML Object of my right div.
import {ElementRef,Renderer} from '#angular/core';
constructor(private el: ElementRef,public renderer: Renderer) {}
Then, I used Dom to access the left div height
this.el.nativeElement.parentElement.childElement[0].clientHeight;
Then I use this.renderer.setElementStyle() to apply style
I also learn that use offscrollheight to do the math is not a good idea !

Ng class not working for ng-table

I want to change background color of table row after selecting it. It works well for normal table. When i tried it to ng-table then only few styles are applied from ng-class not all styles are managed to apply including background color.
My [enter link description here][1].
[1]: http://plnkr.co/edit/O6PzlHXEhOyheNS8BbAT?p=preview
I am giving working example for it on above link,
here ng class work for making font bold of row content but not changing row's background.
Problem is not with ng-table. In fact problem is with class "table-striped" inside
"<table id="t1" ng-table="tableParams" show-filter="true" class="table table-condensed table-bordered table-striped">"
If you remove "table-striped", it works fine.
To go into the deep of how to override custom css over bootstrap css, you can follow below link. This link is very specific to this issue only.
custom css being overridden by bootstrap css
"https://stackoverflow.com/questions/19768794/custom-css-being-overridden-by-bootstrap-css"
Hope this helps.
Try to avoid $index in filtered lists. Try this instead:
<tr ng-repeat="user in userLocations" ng-class="{'selected':user.selected}" ng-dblclick="deselectAll(); user.selected = true;">
$scope.deselectAll = function(){
for(var i; i < userLocations.length i++;){
userLocations[i].selected = false;
}
}

HTML5's 'data-' attribute overriding CSS 'content' property

I've looked far and wide and have been unable to find an explanation to this behavior.
Why does HTML5's data- attribute override my CSS content property on a common element?
So for example, I have the following element defined:
<th data-module-field="name" class="sortable sorted desc" data-bind="click:sort">Name</th>
And my CSS class is as follows:
.sortable.sorted.desc:after {
content: url(../Images/desc.gif);
margin-left: 3px;
}
With the data-module-field attribute set, the content image defined in the CSS class doesn't show up. However, if I remove the data- portion of this attribute (as follows), the content image displays correctly.
<th module-field="name" class="sortable sorted desc" data-bind="click:sort">Name</th>
Can anyone explain why this behavior occurs?

ExtJS: the magic of hidden columns

I wonder how ExtJS makes columns hidden without any visible CSS changes!
The problem that I had - I can't set the CSS rule to hide children icon in that hidden column. F.e. if the hidden td had class 'hidden', I can use something like that:
td.hidden img {display:none;}
But in this case I can do it only in renderer with manipulating grid.columns[col].isHidden().
renderer: function(value,td,record,row,col,store,view) {
return grid.columns[col].isHidden() ? '' : someFunctionToRenderColumn();
},
It's ok, but then if I show hidden column it will not refresh grid and shows empty column. Of course I can add one more event for show/hide that column, but it is so difficult! Has it any simple way?
It gives them a width of 0px:
<colgroup>
<col class="x-grid-cell-gridcolumn-1023" style="width: 0px;">
</colgroup>
... and that should hide your img too. Except if you've given them an absolute positionning or something. You should try to position your img using float, margin and padding. Or you will have to toggle the 'hidden' class yourself using the hide and show event of the column.
You can hide columns by targeting the corresponding col element. No need to put classes on each of the individual tds.
Here's a fiddle I made earlier: http://jsfiddle.net/MrLister/MupLH/
which has
<table>
<col><col class="invisible"><col>
...
and the CSS:
.invisible {visibility:collapse}
But you don't even need a class; you can also use col:nth-child(2) if you know the column number.

Resources