Domanda

I need to show error and warning messages in a dialog when it is showing. If dialog is not showing I need to show the messages in the container page

I have set a template using facelets in all views: template="/WEB-INF/templates/template.xhtml"> with this content:

<f:view locale="#{loginBB.localeCode}">
    <p:messages autoUpdate="true" closable="true" id="globalMessages" />
    <ui:insert name="content" />
</f:view>

In all dialogs I have the following:

<p:messages autoUpdate="true" closable="true" id="dialogMessages" />

When a dialog is showing the error messages appear in the dialog and in the view that hold it, but I need that only appears in the dialog.

What I am doing wrong? I don't know what to do

EDIT: According to the BalusC answer I did the following:

Template:

<f:view locale="#{loginBB.localeCode}">
    <ui:insert name="dialogs" />
    <p:messages autoUpdate="true" closable="true" redisplay="false" />
    <ui:insert name="content" />
</f:view>

View:

<ui:define name="content">
    ...
</ui:define>

<ui:define name="dialogs">
    <h:form id="formX">
        <p:dialog ... >
        </p:dialog>
    </h:form>
</ui:define>

When the dialog is opened it show the message in the dialog. This is OK. But when the dialog is closed, it doesn't show the message in the main page

È stato utile?

Soluzione

That gets tricky if the both <p:messages> components have an autoUpdate="true". It would be doable if only the page's <p:messages> is auto-updated. If you can ensure that the page's <p:messages> appears in JSF component tree after the dialog's <p:messages>, then it's a matter of setting the redisplay attribute of page's <p:messages> to false and making sure that each of the dialog's actions updates the dialog's own form with therein the <p:messages>.

<p:dialog>
    <h:form>
        <p:messages />
        ...
        <p:commandButton ... update="@form" />
    </h:form>
</p:dialog>
<p:messages autoUpdate="true" redisplay="false" />

No additional JS is necessary. You may only need to alter your templates to have an <ui:define name="dialogs"> above the page's <p:messages> so that all your dialogs end up there. Or, alternatively, use CSS to position the page's <p:messages> absolutely. Or, maybe, use JS to relocate the page's <p:messages> to there where you'd like to have it in HTML DOM.

Altri suggerimenti

I have developed, lets say a "nasty" way.

page.xhtml

<p:dialog widgetVar="dialog" >
   <p:messages autoUpdate="true" />
</p:dialog>
<p:messages autoUpdate="true" />

page.js

$(document).ready(function() {
   /**
   * Hook onShow event
   */
   dialog.cfg.onShow = function onShowDialog() {
       $(".ui-messages").not('.ui-dialog .ui-messages').hide()
   }

   /**
   * Hook onHide event
   */
   dialog.cfg.onHide = function onHideDialog() {
       $(".ui-messages").not('.ui-dialog .ui-messages').show()
   }

})

OR if you want to apply this on all the dialogs.

But you MUST NOT define any widgetVar attribute for any dialog you have.

$(document).ready(function() {
   $('.ui-dialog').each(function() {
       widgetName = 'widget_' + $(this).attr('id').replace(/\:/g, '_');
       dialog = window[widgetName];

       dialog.cfg.onShow = function onShowDialog() {
           $(".ui-messages").not('.ui-dialog .ui-messages').hide()
       }

       dialog.cfg.onHide = function onHideDialog() {
           $(".ui-messages").not('.ui-dialog .ui-messages').show()
       }
   })
})

and the magic happens.


Note: if you update the dialog, you would lose the events, you need to re-run the script.


demo

I think that is not possible when you render the whole page, because every <p:messages/> tag will display the message.

But you could update dialog messages via ajax and render only that part of page, so the global messages wont be rendered again.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top