Primefaces: fitViewport in dialog does consider header/footer height

Created on 22 Nov 2015  路  5Comments  路  Source: primefaces/primefaces

The facelets page below should show a dialog with a content, that is to large to fit on the window. It is expected, that the dialog content is sized, so that header an footer fit the window.

Currently after clicking on "Show Dialog" the dialog is correctly opened, but the footer is invisible (outside the window to the south). When the dialog is resized, the dialog snaps to the right size.

The test was done with:

primefaces 5.3
payara 4.1.153

Client browsers Firefox 42, Chromium 45 and IE 11

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
    <h:head>
        <title>Demo fitViewport</title>
    </h:head>
    <h:body>
        <h:form>
            <p:commandButton  type="button" onclick="PF( 'Test' ).show()" value="Show Dialog"/>

            <p:dialog id="Test" widgetVar="Test" header="Test" fitViewport="true" modal="true">
                <div style="height: 2000px">
                    Demo content
                </div>
                <f:facet name="footer">
                    <p:commandButton type="button" onclick="PF( 'Test' ).hide()" value="Hide Dialog"/>
                </f:facet>
            </p:dialog>
        </h:form>
    </h:body>
</html>
defect

Most helpful comment

Ok - I found a work-around: Hook into the postShow function and use css to make the content scrollable:

var origPostShow = PrimeFaces.widget.Dialog.prototype.postShow;

PrimeFaces.widget.Dialog.prototype.postShow = function () {
    this.initSize();
    origPostShow.apply( this );
};

PrimeFaces.widget.Dialog.prototype.fitViewport = function () {
    var winHeight = $( window ).height();
    var contentPadding = this.content.innerHeight() - this.content.height();

    this.content.css("max-height", (winHeight - this.titlebar.outerHeight() - contentPadding - this.footer.outerHeight()) + "px" );
    this.content.css("overflow", "auto");
};

All 5 comments

Ok - I found a work-around: Hook into the postShow function and use css to make the content scrollable:

var origPostShow = PrimeFaces.widget.Dialog.prototype.postShow;

PrimeFaces.widget.Dialog.prototype.postShow = function () {
    this.initSize();
    origPostShow.apply( this );
};

PrimeFaces.widget.Dialog.prototype.fitViewport = function () {
    var winHeight = $( window ).height();
    var contentPadding = this.content.innerHeight() - this.content.height();

    this.content.css("max-height", (winHeight - this.titlebar.outerHeight() - contentPadding - this.footer.outerHeight()) + "px" );
    this.content.css("overflow", "auto");
};

good @matthiasblaesing , I had seen this problem and solved in a very similar way

`//Considers the footer size in the calculation if exists footer
PrimeFaces.widget.Dialog.prototype.fitViewport = function() {
var winHeight = $(window).height();
contentPadding = this.content.innerHeight() - this.content.height();
if (this.jq.innerHeight() > winHeight) {
this.content.height(winHeight - this.titlebar.innerHeight() - contentPadding - (this.footer ? this.footer.innerHeight() : 0));
}
};

//Saves the postShow event in a new event to be used later
PrimeFaces.widget.Dialog.prototype.origPostShow = PrimeFaces.widget.Dialog.prototype.postShow;

//Overwrite the event postShow calling fitViewport event
PrimeFaces.widget.Dialog.prototype.postShow = function () {
this.fitViewport();
this.origPostShow();
};`

Same Problem here. Thanks a lot for your work-arounds! An official fix would be nice!

There is still a Problem when the window is resized (e.g. screen is rotated on mobile).

In fitViewport function there is a problem with getting right sizes if the dialog has dynamic = "true", because dialog is hidden.

my solution was:
var innerPadding; var titleHeight; if (!this.isVisible()) { this.jq.show();//show to get size(for hidden is not right size) titleHeight = this.titlebar.innerHeight(); innerPadding = this.content.innerHeight() - this.content.height(); this.jq.hide();//hide after getting size } else { titleHeight = this.titlebar.innerHeight(); innerPadding = this.content.innerHeight() - this.content.height(); }

Was this page helpful?
0 / 5 - 0 ratings

Related issues

melloware picture melloware  路  5Comments

djmj picture djmj  路  5Comments

cnsgithub picture cnsgithub  路  4Comments

el-duderino5 picture el-duderino5  路  3Comments

richmondspears picture richmondspears  路  5Comments