schlebe
schlebe

Reputation: 3715

How to display HEIGHT variable FIX header panel using JSF and Primefaces?

I use Primefaces 6.2 <p:layout> to display a FIX header (that is always displayed on top of page).

But the header sometimes is to high and I need reduce it DYNAMICALLY.

I decide to replace Header panel with a toggleable panel like this

<p:layout id="PageLayout" fullPage="true">

    <p:layoutUnit position="north">
        <p:panel id="TitlePanel" toggleable="true" header="Title">
            <p:ajax event="toggle" update=":PageLayout"/>
        </panel>    
        ... others panels with context, status, date, time, etc ...
    </p:layoutUnit>

    <p:layoutUnit id="ContentBloc" position="center">
        ... web page with specific data
    </p:layoutUnit>

</p:layout>

This work well except that the position of the ContentBloc is never updated.

When I click on toggle Button, the content of header's panel is hidden but the vertical position of the ContentBloc is never changed !

I used update attribute in <p:ajax> element but this has no effect.

Question: How can I do to UPDATE ContentBloc position ?

Remark: On Chrome, if after having clicked on Toggle button, I load Developer Console, the display is immediately correct !

Remark: if in maximize my Chrome Windows the display is also correct !

Upvotes: 1

Views: 746

Answers (1)

schlebe
schlebe

Reputation: 3715

After searching a lot, I have found the following tricky solution

<div id="PageHeader" style="position:absolute; left:0; top:0; width:100%;"> 
    <p:panel id="TitlePanel" toggleable="true">
        <p:ajax event="toggle" oncomplete="toggleTitlePanel()"/>
        <f:facet name="header">
            <p:outputLabel value="#{pageTitle}" escape="false" style="font-size:200%;"/>
        </f:facet>
        ... others panels with context, status, date, time, etc ...
    </p:panel>
</div>

<div id="ContentPanel" style="position:fixed;
                              left:0;
                              overflow-x:auto;
                              overflow-y:auto;
                             ">
    ... web page with specific data
</div>

For this code to work, I have

  1. added "toggle" event to position ContentPanel.
  2. added some JQuery event when page is loaded

The javascript code linked to toggle event is the following

function fixHeaderHeight()
    {
    var iHeight = document.getElementById("PageHeader").offsetHeight;
    document.getElementById("ContentPanel").style.top = iHeight + "px";
    }

function toggleTitlePanel()
    {
    setTimeout(function(){ fixHeaderHeight(); }, 500);
    }

The fixHeaderHeight() function CANNOT be called direclty because size parameter has not been changed when toggleTitlePanel() is called. So active function is call indirectly using setTimeout() function.

To position correctly ContentPanel the first time it is displayed and when screen size is changed, mimized, maximized, I have already added some javascript code.

<script>
    function setContentTopPosition(div)
        {
        var iHeight = document.getElementById("PageHeader").style.height;
        div.style.top = iHeight;
        }

    function onLoadPage()
        {
        fixHeaderHeight();
        }

    function onResizeWindow()
        {
        fixHeaderHeight();
        }
</script>    

The JQuery events are initialized just before </body> element in .ready() function.

<script type="text/javascript">

    jQuery(document).ready(function()
        {
        onLoadPage();

        jQuery("#PageHeader").resize(function()
            {
            onResizeWindow();
            });
        });

    jQuery(window).resize(function()
        {
        onResizeWindow();
        });

</script>

Now, Header and Content panels are correctly displayed

  1. when I display this page for the first time
  2. when I change windows size
  3. when I click on MINUS button to collapse Header panel
  4. List item when I click pn PLUS button to expand Header panel

I hope only that this solution will be helpfull for others.

Upvotes: 1

Related Questions