Вкладка JSF и атрибут обновления данных для изменения идентификатора вкладки

У меня есть tabView с 3 вкладками, на каждой вкладке есть panelGrid и dataTable, я хотел бы добавить запись в dataTable из panelGrid, и когда я это сделаю, я хочу, чтобы tabView переместился на следующую вкладку, а то же самое на второй вкладке, все идет нормально, но моя проблема в том, что когда я выбираю запись из dataTable, я хочу изменить PanelGrid на ту же информацию, которая была выбрана, затем перейти на следующую вкладку и отредактировать информацию там, это работает хорошо, только если я добавил новую запись, вкладка перейдет к следующей, но когда я вернусь и выберу другие данные из dataTable, она не перейдет на следующую вкладку, я не могу понять, что я делаю неправильно.

Вот мой код вкладок:

    <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>

А вот моя панельная сетка:

    <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>

Вот моя таблица данных:

    <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>

person Khaled    schedule 01.03.2017    source источник


Ответы (1)


... моя проблема в том, что когда я выбираю запись из dataTable... она работает нормально, только если я добавил новую запись, вкладка переходит к следующей, но когда я возвращаюсь и выбираю другие данные из dataTable, он не переходит на следующую вкладку...

Как вы уже поняли, использование нескольких вкладок Primefaces в одном представлении может быть очень сложным.

Один (возможно, чрезмерно сложный) подход к выбору между несколькими вкладками заключается в использовании actionListener в bean-компоненте страницы. В вашем случае вы можете связать слушателя с событием таблицы данных, rowSelect.

В actionListener вызовите клиента с помощью метода Primefaces: RequestContext.getCurrentInstance().execute("selectTab(desiredTabNumber)");

Обратите внимание, что имя функции (selectTab) должно фактически существовать в клиентском коде, как показано ниже:

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

(Ниже приведен ответ на ваш вопрос о лучшем или более простом подходе.)

Другой (вероятно, более надежный) подход — не пытаться управлять состоянием модели между несколькими вкладками на одной странице. Вместо этого можно использовать JSF Flow Scope для настройки серии страниц:

Функция Faces Flows технологии JavaServer Faces позволяет создавать набор страниц с областью действия FlowScoped, которая больше области запроса, но меньше области действия сеанса. Например, вы можете создать серию страниц для оформления заказа в интернет-магазине. Вы можете создать набор автономных страниц, которые можно будет переносить из одного магазина в другой по мере необходимости.

person J Slick    schedule 02.03.2017
comment
спасибо, приятель, не могли бы вы предложить лучший или более простой подход к выполнению моей задачи? - person Khaled; 02.03.2017