Monday, February 4, 2013

How to prevent tab changing in PrimeFaces TabView when validation failed

Trying various approaches to the question above (with p:ajax event="tabChange" and so on), I came up with a clean and well working solution. The code below turns on the PrimeFaces TabView into a "wizard mode". That means, the user stays on the same tab when he / she is trying to switch tabs and has validation errors within the current tab. The main idea is to use p:remoteCommand for a deferred decision about tab switching. If no validation errors were present, the switching occurs by the TabView widget's method select.

XHTML
<p:tabView ... widgetVar="tv_widget" styleClass="tv_selector">
    ...
</p:tabView>
           
<p:remoteCommand name="tv_remoteCommand" process="@(.tv_selector)" update="@(.tv_selector)" global="false"
        oncomplete="handleTabChangeTV(xhr, status, args, tv_widget)"/>
           
<h:panelGroup id="tv_script" styleClass="tv_selector">
    <script type="text/javascript">
          $(function(){
              bindOnClickTV(tv_remoteCommand, tv_widget);
          });
    </script>
</h:panelGroup>
JavaScript
function bindOnClickTV(rc, widget) {
    // unbind PrimeFaces click handler and bind our own
    widget.jq.find('.ui-tabs-nav > li').unbind('click.tabview').
        off('click.custom-tabview').on('click.custom-tabview', function (e) {
            var element = $(this);
       
            if ($(e.target).is(':not(.ui-icon-close)')) {
                var index = element.index();
       
                if (!element.hasClass('ui-state-disabled') && index != widget.cfg.selected) {
                    // buffer clicked tab
                    widget.clickedTab = element.index();
       
                    // call remote command
                    rc();
                }
            }
       
            e.preventDefault();
        });
}

function handleTabChangeTV(xhr, status, args, widget) {
    if (!args.validationFailed) {
        widget.select(widget.clickedTab);
    }
}

3 comments:

  1. It works great. Thanks!

    ReplyDelete
  2. Tab View Provides more Events like addChild,removeChild,selectionChange,render.It's nice and helpful event for custom Software Developer.Thanks for sharing worth information.

    ReplyDelete
  3. If I understand correctly this will always process and update whole tabView? How about processing only the contents of the tab that was active before the click?

    ReplyDelete