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>
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();
}
Most helpful comment
Ok - I found a work-around: Hook into the postShow function and use css to make the content scrollable: