Display Footer in Primefaces Template, When Fullpage of P:Layout Is Set to False

Display footer in PrimeFaces template, when fullPage of p:layout is set to false

To easily visualize what you ultimately need (and to confirm your needs for myself), here's in SSCCE flavor a pure HTML/CSS solution of what you're (apparently) asking for. The sticky footer solution is largely based on Ryan Fait's approach (a min-height:100% and a negative margin on the container element which covers everything but footer), it only doesn't support IE6/7 anymore (due to :after pseudoselector), hereby simplifying the HTML markup (no non-semantic clutter like <div id="pushfooter"> needed). Note: background colors are purely for visualization.

<!DOCTYPE html>
<html lang="en">
<head>
<title>Stack Overflow Question 22584920</title>
<style>
html, body {
height: 100%;
min-width: 800px;
margin: 0;
}
#container {
min-height: 100%;
margin: 0 auto -90px; /* Negative of #footer.height */
}
#header {
height: 135px;
background: pink;
}
#menu {
float: left;
width: 225px;
background: khaki;
}
#content {
margin-left: 225px; /* Same as #menu.width */
margin-right: 175px; /* Same as #side.width */
background: lemonchiffon;
padding: 1px 1em; /* Fixes collapsing margin of p's on div, feel free to remove it */
}
#side {
float: right;
width: 175px;
background: palegreen;
}
#footer, #container:after {
height: 90px;
}
#footer {
background: orange;
}
.clearfix:after {
display: block;
content: " ";
clear: both;
}
</style>
</head>
<body>
<div id="container" class="clearfix">
<div id="header">Header</div>
<div id="menu">Menu</div>
<div id="side">Side</div>
<div id="content">
<p>Content</p><p>Content</p><p>Content</p><p>Content</p><p>Content</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>

Note: due to the way how floats work, the <div id="side"> (the "east unit") has in the HTML markup to be placed before all non-floating elements at the same "row", such as the <div id="content"> (the "center unit"), otherwise it will be aligned relative to the bottom of the last non-floating element.

Now, in order to achieve exactly the same with the <p:layout> thing, which basically renders almost the same HTML structure, only with the footer still inside the container and the east unit after the center unit, you need to make sure that no one of the layout units are collapsible/closable/resizable (those attributes all already default to false and can thus be omitted for brevity) and that you apply the PrimeFaces-builtin clearfix style class ui-helper-clearfix on the container unit to clear the floats (otherwise the menu, content and side would overlap the footer when the screen is shrunk vertically):

<p:layout styleClass="ui-helper-clearfix">
<p:layoutUnit position="north" size="135">
<p>Header</p>
</p:layoutUnit>
<p:layoutUnit position="west" size="225" header="Menu Item">
<p>Menu</p>
</p:layoutUnit>
<p:layoutUnit position="center">
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
<p>Content</p>
</p:layoutUnit>
<p:layoutUnit position="east" size="175">
<p>Side</p>
</p:layoutUnit>
<p:layoutUnit position="south" size="90">
<p>Footer</p>
</p:layoutUnit>
</p:layout>

Then you can apply the following CSS in your PrimeFaces-override stylesheet to remove/override all "irrelevant" PrimeFaces-generated CSS properties on those layout units by setting the absolute positioning with fixed offsets/dimensions back to initial/default values (note: the exact purpose of !important is being able to override hardcoded/inline style properties from a true stylesheet on, there's in this particular case simply no other option as long as you don't want to rewrite PrimeFaces components and renderers). Key point is that you should end up with exactly the same HTML/CSS (defaults) as the SSCCE:

html, body {
height: 100%;
min-width: 800px;
margin: 0;
}
.ui-layout-container {
min-height: 100%;
height: auto !important;
margin: 5px;
margin-bottom: -90px; /* Negative of footer height. */
}
.ui-layout-unit {
position: static !important;
top: auto !important;
bottom: auto !important;
left: auto !important;
right: auto !important;
height: auto !important;
}
.ui-layout-unit-content {
display: block !important;
height: auto !important;
}
.ui-layout-west {
float: left;
margin: 5px 0 !important;
}
.ui-layout-center {
margin: 5px 0 !important;
margin-left: 230px !important; /* Menu width plus margin between panels. */
margin-right: 180px !important; /* Side width plus margin between panels. */
}
.ui-layout-east {
float: right;
margin: 5px 0 !important;
}
.ui-layout-container:after {
height: 85px; /* Footer height minus margin between panels. */
}
.ui-layout-south {
margin: 5px !important;
visibility: visible !important;
}

And finally add the following script in order to move the side (east unit) before the content (center unit), so that the floats go as intented, and to move the footer to end of body, so that it's outside the container element:

$(function() { 
$(".ui-layout-east").insertBefore(".ui-layout-center");
$(".ui-layout-south").appendTo("body");
});

Make sure that this script is re-executed when you do an ajax update with @all on the same view for some reason (which is at its own a bad idea though).

With this "solution" (I'd rather call it a hack and just throw it all away and go for a sane and clean HTML/CSS solution, if necessary with <p:panel>s instead of <div>s), it's still somewhat brittle; the auto-included layout.js script auto-adjusts the layout units on every window resize. But so far they don't seem to break anything in all modern browsers I tried (IE>8).

Primefaces template - south position doesn/t work

Except center layoutUnit, other layout units must have dimensions defined via size option. Try adding it to the south unit

How to prevent a p:menubar from being overlapped by the contents of a CSS template?

I found an answer but I dropped using <p:menubar> as well and instead chose a plain/vanilla HTML/CSS menu simply because <p:menubar> officially does not support clickable <p:submenu> inside it which also requires some JavaScript/jQuery tricks to make them clickable and even doing so does not function reliably.

To the answer, I was using the table layout on the header as mentioned in the question that was generated by using <p:panelGrid> which in turn renders an HTML table as follows.

<p:panelGrid styleClass="headerElipses">
<p:row>
<p:column rowspan="3">1</p:column>
<p:column rowspan="3">2</p:column>
<p:column>3</p:column>
<p:column>4</p:column>
<p:column>5</p:column>
<p:column>6</p:column>
<p:column>7</p:column>
<p:column>8</p:column>
<p:column>9</p:column>
<p:column>10</p:column>
<p:column>11</p:column>
<p:column rowspan="3">12</p:column>
</p:row>

<p:row>
<p:column colspan="5" rowspan="2">13</p:column>
<p:column rowspan="2">14</p:column>
<p:column>15</p:column>
<p:column>16</p:column>
<p:column>17</p:column>
</p:row>

<p:row>
<p:column>18</p:column>
<p:column>19</p:column>
<p:column>20</p:column>
</p:row>

<p:row>
<p:column>21</p:column>
<!-- Only the following column is associated with the question -->
<p:column colspan="10">22 The header menu goes here.</p:column>
<p:column>23</p:column>
</p:row>
</p:panelGrid>

Columns are given a fixed width. I dropped the whole CSS mess from this <p:panelGrid>.


The CSS class headerElipses (there is a spelling mistake, of course. A class name like header-ellipsis is not recognized by browsers. I don't know the reason).

.headerElipses {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}

.headerElipses td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

In this CSS class, overflow: hidden; is responsible that prevents the menu from being displayed over the centre container.

I simply overrode this style in the only table cell which holds the <p:menubar> as follows.

<p:column colspan="10" style="overflow: visible !important; white-space: normal !important;">
22 The header menu goes here.
</p:column>

In this cell, overflow: hidden; and white-space: nowrap; (including others) are not required at all.


Note : I don't use the <p:layout> (or <pe:layout>) thing which only supports a full page layout util now in which the following CSS attributes need to be overridden in the respective classes to prevent a <p:menubar> on the north unit from being hidden behind the centre unit content.

.ui-layout-north {
z-index: 20 !important;
overflow: visible !important;
}

.ui-layout-unit-content {
overflow:visible !important;
}

Smaller display of p:signature

I would convert the signature to an SVG (or PNG) which allows you to easily scale it down for displaying using CSS.

See also:

  • How to convert p:signature value to an image (or other serialised form)
  • https://primefaces.github.io/primefaces/8_0/#/components/signature?id=convert-to-binary

Removing gutters from p:layout

I just had the same problem.

What I did was using the following properties in the layoutUnit component:

collapsible="true" gutter="0"

It seems that gutter doesn't work unless you use it with collapsible.

The credit goes to the good people of Primefaces Forum:

Layout Unit Gutter Has No Effect @PrimefacesForum



Related Topics



Leave a reply



Submit