Set P-Tree height based on available screen height

UI Components for Angular
ankushb
Posts: 16
Joined: 31 Jan 2021, 18:27

23 May 2021, 12:49

Hello,

I have a simple page with header, content and footer. I want the PTree control to take all the screen space that remains after header and footer (which contains a Submit button)

The Header height is dynamic i.e changes based on user setting. I am using P Tree with filter in the Content area and I want the control to take the remaining height of the screen. I don't want to show the browser scroll bar as it makes the bottom Submit button disappear. I am ok with the scroller on the ptree control.

I tried variety of things but I am not able to acheive that,

Please Please can you help. Happy to do whatever it takes to get this working correctly.

Regards,
Ankush

PhilHuhn
Posts: 177
Joined: 19 Sep 2018, 02:52
Location: Ann Arbor, Michigan USA
Contact:

24 May 2021, 15:05

You did not mention what version of the PrimeNG library and what CSS library you are using. I google 'javascript set control height to remaining space' and found many items. I tend to look on StackOverflow mostly. The following is one of them:

Code: Select all

https://stackoverflow.com/questions/90178/make-a-div-fill-the-height-of-the-remaining-screen-space

yigitfindikli
Posts: 449
Joined: 08 Aug 2018, 14:09

26 May 2021, 10:25

ankushb wrote:
23 May 2021, 12:49
Hello,

I have a simple page with header, content and footer. I want the PTree control to take all the screen space that remains after header and footer (which contains a Submit button)

The Header height is dynamic i.e changes based on user setting. I am using P Tree with filter in the Content area and I want the control to take the remaining height of the screen. I don't want to show the browser scroll bar as it makes the bottom Submit button disappear. I am ok with the scroller on the ptree control.

I tried variety of things but I am not able to acheive that,

Please Please can you help. Happy to do whatever it takes to get this working correctly.

Regards,
Ankush
Hi,

Can you create an example using with https://stackblitz.com/edit/primeng-tree-demo.

Regards.

ankushb
Posts: 16
Joined: 31 Jan 2021, 18:27

01 Jun 2021, 16:54

Hello,

Here is the example https://stackblitz.com/edit/primeng-tre ... onent.html

Issues to resolve
==============
1. The Next Button that appears at the bottom of the tree must always be visible to the user, notice that as you start expanding the categories, the tree pushes the button down eventually making it disappear from the user view - I dont want this behaviour and want the Next button always visible to the user.
2. In order to solve the above issue, I understand that I can set scrollHeight on tree, however that will restrict the height of the tree to specifix pixels, I want the tree to use all the remaining space on the screen with the Next Button appearing at the bottom of the screen, such that the tree gets maximum screen estate. I dont want to see browser scroll bar but ok to see the scroll bar inside the tree control as the user expands categories.

Thank you in advance, i am hoping i can get this issue resolved. Example pasted above and here as well https://stackblitz.com/edit/primeng-tre ... onent.html

Best Regards,
Ankush

PhilHuhn
Posts: 177
Joined: 19 Sep 2018, 02:52
Location: Ann Arbor, Michigan USA
Contact:

04 Jun 2021, 03:53

Hey:

It seems to me you have to calculate the space. I calculated the following from my view:
Card: 289
Title: 33
Cnt: 216
Sub: subDiv 44
Btn: btnDiv 22
View:

Code: Select all

<p-card id='p' header="My Card">
	<div id='subDiv' class="p-card-subtitle">
		Expand the Tree or use Search Filter below to select the correct sub-category and click Next.
	</div>
	<div id='contentDiv'>
		Content
		<br />
		<br />
		<br />
		<br />
		End
	</div>
	<div id='btnDiv' class="p-grid p-nogutter p-justify-end p-mt-3">
		<button styleClass="p-button-lg" label="Next: Add Details"
		icon="pi pi-angle-right" iconPos="right"></button>
	</div>
</p-card>

Code: Select all

constructor(
	private _elementRef: ElementRef,
	...
) { }
@ViewChild( 'p' ) card: Card;
ngAfterViewInit(): void {
	const controls = this._elementRef.nativeElement.querySelectorAll( '#p' );
	const crd: any = controls[0].children[0];
	const ttl: any = controls[0].children[0].children[0].children[0];
	const cnt: any = controls[0].children[0].children[0].children[1];
	const sub: any = controls[0].children[0].children[0].children[1].children[0];
	const btn: any = controls[0].children[0].children[0].children[1].children[2];
	console.warn( `Card: ${crd.id} ${crd.offsetHeight}` );
	console.warn( `Title: ${ttl.id} ${ttl.offsetHeight}` );
	console.warn( `Cnt: ${cnt.id} ${cnt.offsetHeight}` );
	console.warn( `Sub: ${sub.id} ${sub.offsetHeight}` );
	console.warn( `Btn: ${btn.id} ${btn.offsetHeight}` );
	console.warn( controls );
}
My content height is the total. You could use the contentDiv height.

ankushb
Posts: 16
Joined: 31 Jan 2021, 18:27

05 Jun 2021, 15:00

Thanks PhilHuhn for your reply and thanks for suggesting that i will have to calculate height in the code..

However i am not quite following the code that you have pasted, so would appreciate if you can update the code here https://stackblitz.com/edit/primeng-tre ... onent.html.

This is one of the most critical function that we need in the system so really keen on doing whatever it takes to get this resolved in the right way.

Any ideas options you suggest are most welcome.

Regards,
Ankush

PhilHuhn
Posts: 177
Joined: 19 Sep 2018, 02:52
Location: Ann Arbor, Michigan USA
Contact:

05 Jun 2021, 18:36

Hey:
Card: 305
Title: 32
Cnt: contentDiv 107
Sub: subDiv 64
Btn: btnDiv 6

Code: Select all

import { Component, ElementRef, ViewChild } from '@angular/core';
import { Card } from 'primeng/card';

@Component({
  selector: 'app-root',
  template: `
<p-card id='p' header="My Card">
	<div id='subDiv' class="p-card-subtitle">
		Expand the Tree or use Search Filter below to select the correct sub-category and click Next.
	</div>
	<div id='contentDiv'>
		Content
		<br />
		<br />
		<br />
		<br />
		End
	</div>
	<div id='btnDiv' class="p-grid p-nogutter p-justify-end p-mt-3">
		<button styleClass="p-button-lg" label="Next: Add Details"
		icon="pi pi-angle-right" iconPos="right"></button>
	</div>
</p-card>`
})
export class AppComponent { 
  constructor(
    private _elementRef: ElementRef
  ) { }
  @ViewChild( 'p' ) card: Card;
  ngAfterViewInit(): void {
    const controls = this._elementRef.nativeElement.querySelectorAll( '#p' );
    const crd: any = controls[0].children[0];
    const ttl: any = controls[0].children[0].children[0].children[0];
    const sub: any = controls[0].children[0].children[0].children[1].children[0];
    const cnt: any = controls[0].children[0].children[0].children[1].children[1];
    const btn: any = controls[0].children[0].children[0].children[1].children[2];
    console.warn( controls );
    console.warn( `Card: ${crd.id} ${crd.offsetHeight}` );
    console.warn( `Title: ${ttl.id} ${ttl.offsetHeight}` );
    console.warn( `Cnt: ${cnt.id} ${cnt.offsetHeight}` );
    console.warn( `Sub: ${sub.id} ${sub.offsetHeight}` );
    console.warn( `Btn: ${btn.id} ${btn.offsetHeight}` );
  }
}
Between Dev Tools using Elements and Console tabs, and figure out the spacing.

ankushb
Posts: 16
Joined: 31 Jan 2021, 18:27

08 Jun 2021, 17:13

Sorry but you are not getting me and i am not following what you are saying. Note that the size will change based on device so i need to set the size dynamically.

Please can i ask you to update the code on the stack blitz link that i have shared earlier on one of your moderators request ?


Regards,
Ankush

PhilHuhn
Posts: 177
Joined: 19 Sep 2018, 02:52
Location: Ann Arbor, Michigan USA
Contact:

09 Jun 2021, 17:42

Hey:
I am not in any way associated with Primefaces. I am a fellow Angular developer.

Code: Select all

  <p-tree [value]="files1" [filter]="true"
    scrollHeight='{{treeScrollHeight}}px'></p-tree>

Code: Select all

import { Component, OnInit, AfterViewInit, HostListener } from '@angular/core';
import {NodeService} from './nodeservice';
import {TreeNode} from 'primeng/api';
//
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit, AfterViewInit { 
    files1: TreeNode[];
    files2: TreeNode[];
    viewportHeight: number = 0;
    treeScrollHeight: number = 180;
    constructor(private nodeService: NodeService) { }

    ngOnInit() {
        this.nodeService.getFiles().then(files => this.files1 = files);
        this.nodeService.getFiles().then(files => this.files2 = files);
    }
    ngAfterViewInit() {
        this.treeScrollHeight = this.calculateTreeHeight( );
    }
    @HostListener('window:resize', ['$event'])
    onResize( event: any ) {
        if( this.viewportHeight !== window.innerHeight ) {
            console.log( `${window.innerWidth} ${window.innerHeight}` );
            // pseudo debounce, consider using debounce
            if( Math.abs(this.viewportHeight - window.innerHeight) > 3 ) {
                this.viewportHeight = window.innerHeight;
                this.treeScrollHeight = this.calculateTreeHeight( );
            }
        }
    }
    calculateNonTreeHeight( ): number {
        // height: sum of margins, title, sub-title, button, etc
        return 260;
    }
    calculateTreeHeight( ): number {
        let height: number = this.viewportHeight - this.calculateNonTreeHeight( );
        if( height < 180 ) {
            height = 180;
        }
        console.log( `Tree height: ${height}` );
        return height;
    }


    expandAll(){
        this.files2.forEach( node => {
            this.expandRecursive(node, true);
        } );
    }

    collapseAll(){
        this.files2.forEach( node => {
            this.expandRecursive(node, false);
        } );
    }
    
    private expandRecursive(node:TreeNode, isExpand:boolean){
        node.expanded = isExpand;
        if (node.children){
            node.children.forEach( childNode => {
                this.expandRecursive(childNode, isExpand);
            } );
        }
    }
}
You need to add the other stuff too. @ViewChild to calculate the header, title, sub-title, button and margin heights.

ankushb
Posts: 16
Joined: 31 Jan 2021, 18:27

12 Jun 2021, 17:39

Thank you, I think i am now following what you are saying as follows
a) Have the scrollHeight bound to a variable e.g. treeScrollHeight
b) Get the ViewPort height which is = window.innerHeight. This will give me Total available height
c) Get the height of header using @ViewChild
d) Get the height of footer using @ViewChild
e) Set treeScrollHeight = ViewPortHeight - HeaderHeight - FooterHeight.

Is that Correct. Am i missing anything ? Thanks a ton for your help.

Regards,
Ankush

Post Reply

Return to “PrimeNG”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 17 guests