Scroll p:messages into view when it is updated and (error) messages are present

前端 未结 4 1250
暖寄归人
暖寄归人 2021-01-05 18:58

I am working with PrimeFaces messages, I want my whole page to scroll to top when p:messages is rendered.

相关标签:
4条回答
  • 2021-01-05 19:44

    Lets say that your button is causing the messages to appear.

    XHTML

    <p:commandButton value="Save" 
                     oncomplete="scrollToFirstMessage()" />
    

    javascript

    //javascript function which scroll to the first message in page   
    function scrollToFirstMessage() {
         try {
            PrimeFaces.scrollTo($('.ui-message :first-child').eq(0).parent().attr('id'));
         } catch(err) {
           //No Message was found!
         }
      }
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-05 19:44

    There are valid answers already that show how to scroll to the p:messages component, but they all require you to execute code in a backing bean. This requires you to do / call the same in each action. None show how to scroll to the messages component when it is rendered (updated).

    You can implement a phase listener and check messages are present and if the messages component's clientId is present in the PartialViewContext renderIds:

    These client identifiers are used to identify components that will be processed during the render phase of the request processing lifecycle.

    Your listener can look something like this:

    public class MessagesUpdateListener implements PhaseListener {
    
      private final String MESSAGES_ID = "yourMessagesClientId";
    
      @Override
      public void afterPhase(PhaseEvent event) {
        // Empty
      }
    
      @Override
      public void beforePhase(PhaseEvent event) {
        FacesContext fc = FacesContext.getCurrentInstance();
        if (!fc.getMessageList().isEmpty() &&
            fc.getPartialViewContext().getRenderIds().contains(MESSAGES_ID)) {
          RequestContext.getCurrentInstance().scrollTo(MESSAGES_ID);
        }
      }
    
      @Override
      public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
      }
    
    }
    

    Make sure to register it in your faces-config.xml:

    <lifecycle>
      <phase-listener>your.MessagesUpdateListener</phase-listener>
    </lifecycle>
    

    Tested with XHTML:

    <h:form id="main">
    
      <p:messages id="messages" />
      <p:inputText id="text1" required="true" />
    
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
      this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
    
      <p:commandButton value="Update" update="messages text1"/>
      <p:commandButton value="No update"/>
    
    </h:form>
    

    To check for global messages, use:

    fc.getMessageList(null).isEmpty()
    

    See also:

    • Add global message when field validation fails
    0 讨论(0)
  • 2021-01-05 19:47

    Deprecated with PrimeFaces < 6.2

    In you backing bean (that one which produces the messages), you should know when you render a p:message. If so simply execute this:

    RequestContext.getCurrentInstance().execute("window.scrollTo(0,0);");
    

    Update:

    With the newer PrimeFaces versions (>= 6.2), the approach to execute Javascript on the client side is (by using x and y coordinates):

    PrimeFaces instance = PrimeFaces.current();
    instance.execute("window.scrollTo(0,0);");
    

    To scroll to an element use the element's clientId:

    PrimeFaces instance = PrimeFaces.current();
    instance.scrollTo("myElementsClientId");
    

    Find more information here:

    • http://de.selfhtml.org/javascript/objekte/window.htm#scroll_to
    • examples with jQuery for smooth scrolling as well: Scroll to the top of the page using JavaScript/jQuery?
    0 讨论(0)
  • 2021-01-05 19:47

    Assign an ID to your p:message component

    <p:messages autoUpdate="true" id="myMessage" />
    

    Then, in your backing bean call RequestContext.scrollTo method:

    • in PrimeFaces >= 6.0:

      PrimeFaces.current().scrollTo("myMessage")
      
    • in Primefaces < 6.0:

      RequestContext context = RequestContext.getCurrentInstance();
      context.scrollTo("myMessage");
      

      which is deprecated in PrimeFaces 6.0

    0 讨论(0)
提交回复
热议问题