简体   繁体   中英

Primefaces Notification bar working selectively

I'm having an odd problem with Notification bar in Primefaces. Actually, Notification bar itself displays on page load without problems, and buttons for open/hide work fine.

Problem is in JavaScript call for hiding Notification bar - it doesnt work. It doesn't work even if I exclude setTimeout and call hide function directly. Situation is same even with button for displaying Bar - button works, but it is not working from JavaScript.

And I checked, if I put alert in JavaScript it displays without problems, so functions are working.

Any ideas?

Thanks!

    <h:form>

        ...

        <p:notificationBar position="top" effect="slide" 
                  styleClass="top" widgetVar="bar" autoDisplay="true">

           <p:commandButton id="barOff" onclick="PF('bar').hide()" 
                  type="button" icon="ui-icon-arrow-1-n"/>
           <h:outputText value="Some text" style="font-size:36px;" />

        </p:notificationBar>

        <p:commandButton id="barOn" value="Show" onclick="PF('bar').show()" 
                  type="button" icon="ui-icon-arrow-1-s"/>

     </h:form>


     <script type="text/javascript">

        function load() {
            setTimeout(close(), 3000);
        }

        function close() {
            document.getElementById('barOff').click();
        }

        document.getElementsByTagName('body')[0].onload = load();
    </script>

barOn and barOff <p:commandButton> are in a naming container, so in order to select them, you have to either:

  • prefix their id with the naming container id
  • add prependId="false" to the naming container ( see note below )

Edit: note about component ids and UINamingContainer From BalusC's blog :

Render IDs are resolved relative to the parent UINamingContainer component. Examples of UINamingContainer components are <h:form> , <h:dataTable> , <ui:repeat> , etc. It are those components which prepends the client ID of their children with its own client ID.

[...]

The absolute render ID needs to be the full client ID prefixed with ":". So if the render target is by itself nested in another UINamingContainer component, then you need to give it a fixed ID and include its ID as well.

When using prependId="false" on a UINamingContainer, the ID of components inside it is rendered as-is in the DOM. This is somehow an easy way out that should be avoided since it can lead easily to have accidentally multiple components with the same ID in the DOM. It is better to use fully-qualified IDs.

Taking this precaution into account, just add an id to the form and use it as prefix to qualify its children components:

<h:form id="notification-form">

and

function close() {
   document.getElementById('notification-form:barOff').click();
}

or simply (without the need to reference IDs):

function close() {
   PF('bar').hide();
}

See also:

UIForm with prependId="false" breaks <f:ajax render>

After working with console.log() as @Zim proposed, I founded that notification bar isn't available at the moment of the page load - I was getting undefined object. After making a delay with setTimeout() , Notification bar started opening. That delay could be as small as 10ms, or even less. It even worked with values like 1ms, or even 0! Now, Notification bar opens perfectly.

Here is modified code that works as expected:

<h:form id="forma">

    ...

    <p:notificationBar position="top" effect="slide"
                   styleClass="top" widgetVar="bar">

        <p:commandButton id="barOff" onclick="PF('bar').hide()" 
                         type="button" icon="ui-icon-arrow-1-n"/>

        <h:outputText value="Text!" style="font-size:36px;" />

   </p:notificationBar>


   <p:commandButton id="barOn" value="Show" onclick="PF('bar').show()" 
                  type="button" icon="ui-icon-arrow-1-s"/>

</h:form>

<script type="text/javascript">

        function load() {
            setTimeout(function() { open(); }, 10);
        }

        function open() {
            PF('bar').show();
            setTimeout(function() { close(); }, 6000);
        }

        function close() {
            PF('bar').hide();
        }

       document.getElementsByTagName('body')[0].onload = load();

</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM