0
votes

I have a tabView that has 3 tabs, in each tab there is a panelGrid and dataTable, I would like to add a record to the dataTable from the panelGrid and when I do so I want the tabView to move to the next tab, and the same in the second tab, this is going fine, but my problem is when I select a record from the dataTable I want to change the panelGrid to the same information which were selected then move to the next tab and edit the information there, it works fine only if I added a new record the tab go to the next one, but when I go back and select another data from the dataTable it does not move to the next tab, I cant figure out what I am doing wrong.

Here is my tabs code:

    <h:form id="frmExamBank" widgetVar="accordionPanelWidget">
        <p:tabView widgetVar="tabWidget" id="tabsId"
            activeIndex="#{mbCoursesExamBank.activeIndexTab}">
            <p:tab title="Course Exam Bank" id="tab1">
                <ui:include src="/pages/instructors/test.xhtml" />
            </p:tab>
            <p:tab title="Course Exam Questions" id="tab2" disabled="true">
                <ui:include src="/pages/instructors/questions.xhtml" />
            </p:tab>
            <p:tab title="Course Exam Answers" id="tab3" disabled="true">
                <ui:include src="/pages/instructors/answers.xhtml" />
            </p:tab>
        </p:tabView>
    </h:form>

And here is my panelGrid:

    <p:panelGrid columns="4" id="pnlCoursesExamBankData">
        <f:facet name="header">
            <div align="center">#{msg2.get('course_exam_bank')}</div>
        </f:facet>

        <p:outputLabel value="#{msg2.get('course')}" for="course" />
        <p:selectOneMenu id="course" value="#{mbCoursesExamBank.entity.course}"
            required="true" converter="omnifaces.SelectItemsIndexConverter"
            label="#{msg2.get('course')}" filter="true" filterMatchMode="contains">
            <f:selectItems value="#{mbCourses.all}" var="course"
                itemLabel="#{course.fullName}" itemValue="#{course}" />
        </p:selectOneMenu>

        <p:outputLabel value="#{msg2.get('exam_category')}" for="examCategory" />
        <p:selectOneMenu id="examCategory"
            value="#{mbCoursesExamBank.entity.examCatogory}" required="true"
            converter="omnifaces.SelectItemsIndexConverter"
            label="#{msg2.get('exam_category')}">
            <f:selectItem itemLabel="#{msg2.get('select_category')}"
                itemValue="#{null}" noSelectionOption="true" />
            <f:selectItems value="#{mbExamCategory.all}" var="category"
                itemLabel="#{category.name}" itemValue="#{category}" />
        </p:selectOneMenu>

        <f:facet name="footer">
            <div align="center">
                <p:commandButton value="#{msg2.get('add')}"
                    action="#{mbCoursesExamBank.addCoursesExamBank()}"
                    update="@parent,@parent:tblCoursesExamBank,frmExamBank:tabsId"
                    process="@parent:pnlCoursesExamBankData" icon="btn-icon fa fa-plus" />
                <p:commandButton value="#{msg2.get('save')}"
                    action="#{mbCoursesExamBank.update()}"
                    update="@parent,@parent:tblCoursesExamBank"
                    process="@parent:pnlCoursesExamBankData"
                    icon="btn-icon fa fa-floppy-o" />
                <p:commandButton value="#{msg2.get('delete')}"
                    action="#{mbCoursesExamBank.delete()}"
                    update="@parent,@parent:tblCoursesExamBank"
                    process="@parent:pnlCoursesExamBankData"
                    icon="btn-icon fa fa-pencil" />

            </div>
        </f:facet>
    </p:panelGrid>

Here is my dataTable:

    <p:dataTable paginatorPosition="bottom" id="tblCoursesExamBank"
        value="#{mbCoursesExamBank.all}" var="bank" selectionMode="single"
        selection="#{mbCoursesExamBank.entity}" rowKey="#{bank.id}"
        rowIndexVar="rowIndex" paginator="true" rows="6">
        <p:ajax  event="rowSelect"
            update="@parent:pnlCoursesExamBankData,frmExamBank,frmExamBank:tabsId"
            process="@this" />
        <p:column headerText="#" width="10%">
                            #{rowIndex+1}
                        </p:column>
        <p:column headerText="#{msg2.get('course')}"
            filterBy="#{bank.course.name}" sortBy="#{bank.course.name}"
            filterMatchMode="contains">
                        #{bank.course.name}
                        </p:column>
        <p:column headerText="#{msg2.get('exam_catogory')}"
            filterBy="#{bank.examCatogory.name}"
            sortBy="#{bank.examCatogory.name}" filterMatchMode="contains">
                        #{bank.examCatogory.name}
                        </p:column>

    </p:dataTable>
1

1 Answers

0
votes

... my problem is when I select a record from the dataTable...it works fine only if I added a new record the tab go to the next one, but when I go back and select another data from the dataTable it does not move to the next tab...

As you've discovered, using multiple Primefaces tabs in the same view can be very tricky.

One (perhaps overcomplicated) approach to selecting between multiple tabs is to use an actionListener on the page bean. In your case, you could associate the listener to the data table event, rowSelect.

In the actionListener, call the client using Primefaces method: RequestContext.getCurrentInstance().execute("selectTab(desiredTabNumber)");

Note that the function name (selectTab) must actually exist in the client code, as follows:

<script type="text/javascript">
    function selectTab(index) {
      if(typeof tabWidget != 'undefined') {
         tabWidget.select(index);
      } else {
        alert("Can't select tab " + index);
      }
    }
</script>

(The following is an edit in response to your question about a better or simpler approach.)

Another (probably more reliable) approach would be to not try to manage the model state between multiple tabs on the same page. Instead, maybe use JSF Flow Scope to set up a series of pages:

The Faces Flows feature of JavaServer Faces technology allows you to create a set of pages with a scope, FlowScoped, that is greater than request scope but less than session scope. For example, you might want to create a series of pages for the checkout process in an online store. You could create a set of self-contained pages that could be transferred from one store to another as needed.