2015-07-16 2 views
3

У меня есть p:accordionPanel, который представляет список элементов, и на каждой вкладке есть форма. При подаче любой из повторяющихся форм возможно, что дополнительные данные необходимы, а именно, когда вызывается p:dialog, предлагая пользователю ввести еще несколько данных. Этот диалог определяется вне панели аккордеона, потому что, в отличие от элементов из аккордеона, только один из них может отображаться одновременно, поэтому нет необходимости увеличивать HTML, повторяя его на каждой вкладке аккордеона.Как обновить компоненты AJAX на одной вкладке p: accordionPanel снаружи?

Определение аккордеона выглядит следующим образом (упрощенный, но со всеми соответствующими дескрипторами):

<p:accordionPanel id="myAccordion" value="#{managedBean.getAccordionList}" var="item" multiple="false" dynamic="true" cache="true"> 

    <p:ajax event="tabChange" listener="#{managedBean.processTabChange}"/> 

    <p:tab title="#{item.tabTitle}" id="itemTab"> 

     <h:form id="itemForm"> 

      <h:outputLabel for="itemName" value="Item Name:"/> 
      <p:inputText id="itemName" title="Item Name:" 
        maxlength="16" value="#{appeal.itemName}"> 
      </p:inputText> 

Следовательно, HTML-визуализации для itemName является myAccordion:0:itemForm:itemName в первую очередь, myAccordion:1:itemForm:itemName в секунду и т.д.

диалог определяется следующим образом:

<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto"> 
    <h:form id="commentForm"> 

     <h:outputLabel for="comment" value="Comment:"/> 

     <p:inputTextarea id="comment" title="Comment" 
       rows="6" cols="33" 
       value="#{managedBean.activeItem.comment}" 
       required="true"> 
      <f:ajax render="comment"/> 
     </p:inputTextarea> 

     <h:commandButton value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();"> 
      <f:ajax render="*** ??? ***"/> 
     </h:commandButton> 

    </h:form> 
</p:dialog> 

То, что я повторил ly failing at - попытки f:ajax обновить только одну вкладку на панели аккордеона, активную, из которой был выведен диалог. Я попытался с помощью

:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm:itemName 
:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm 
:myAccordion:#{managedBean.activeItem.displayIndex}:itemTab 

вместо *** ??? ***, но ни один из них не будет составлять:

javax.faces.FacesException: <f:ajax> contains an unknown id ':myAccordion:0:itemForm' - cannot locate it in the context of the component j_idt20 

Если я пропускаю индекс маркера (например, :myAccordion:itemForm:itemName) это компилировать, но он не делает ничего функционально. Класс сущности Item имеет getDisplayIndex, который точно возвращает индекс активной вкладки.

Моя проблема очень похожа на то, что описано в this question, что действительно не имеет хорошего ответа. Это может быть ограничение PrimeFaces?

+0

«Это может быть ограничение PrimeFaces?» Я бы сказал, нет. Это не имеет никакого смысла. – DavidS

+0

Я имел в виду ошибку, @DavidS – amphibient

+0

Одна вещь, которая мне интересна, - это то, что визуализируется для 'f: ajax'. Вы говорите, что пытаетесь использовать 'displayIndex' в атрибуте' render', но сам 'f: ajax' отображается только один раз. Например, для аналогичного примера со статической панелью аккордеона кнопка ajax отображается как «onclick =» mojarra.ab (это событие, «действие», 0, «форма: myaccordion: mytab2»), возвращает false «' , Может быть, вы уже учли это? – DavidS

ответ

0

Вы должны обновить commandButton в событии tabChange.

<p:ajax event="tabChange" listener="#{managedBean.processTabChange}" update=":commentForm:commandButtonId"/> 

render атрибут <f:ajax> внутри <h:commandButton> оценивается во время визуализации фазы, а не раньше AFAIK. Поэтому, если вы не обновите его, он всегда будет указывать на «0». Проверьте источник в своем инструменте разработчика браузера и проверьте свои запросы ajax (все, что нужно всегда сделать для отладки). Вы увидите полный clientId с параметром ': 0:', и вы не увидите, что он изменился на запросы ajax.

+0

Я пробовал это, однако, есть проблема с обновлением ': commentForm: commandButtonId', и я думаю, это может быть потому, что у него есть вложенная проблема' f: ajax' – amphibient

+0

** какая **? Мы не ясновидящие. И попробовал 'p: commandButton'? – Kukeltje

+0

Хммм, теперь я вижу все виды комментариев, не знаю, почему я их не видел ... И обновленный вопрос. Возможно, это была одна и та же проблема/ограничение – Kukeltje

1

Я не знаю, какую версию Primfaces вы используете, но это кажется ошибкой в ​​Primefaces 5.1.1, где я мог бы воссоздать эту проблему. При обновлении до Primefaces 5.2, ajax EL мог внезапно найти ссылочный идентификатор. Я могу отправить MCVE, если это необходимо.

Edit: MCVE:

XHTML:

<h:form id="itemForm"> 
    <p:accordionPanel id="myAccordion" binding="#{accordionView}" value="#{playgroundController.users}" dynamic="true" activeIndex="#{playgroundView.activeIndex}" var="user" multiple="false"> 

     <p:ajax event="tabChange" update="commentDialogID"/> 

     <p:tab title="#{user.name}"> 
       <h:outputLabel for="itemName" value="Item Name:" /> 
       <p:inputText id="itemName" title="Item Name:" maxlength="16" 
        value="#{user.amount}"> 
       </p:inputText> 
       <p:commandButton value="showDialog" onclick="PF('commentDialog').show();"></p:commandButton> 
     </p:tab> 

    </p:accordionPanel> 
</h:form> 

<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto"> 
    <h:form id="commentForm"> 

     <h:outputLabel for="comment" value="Comment:"/> 

     <p:inputTextarea id="comment" title="Comment" 
       rows="6" cols="33" 
       value="#{playgroundView.activeIndex}" 
       required="true"> 
      <f:ajax render="comment"/> 
     </p:inputTextarea> 

     <p:commandButton value="Submit" onclick="PF('commentDialog').hide();" update=":itemForm:myAccordion:#{playgroundView.activeIndex}:itemName" ></p:commandButton> 

    </h:form> 
</p:dialog> 

PlaygroundView Bean:

Обратите внимание, что в этом примере activeIndex должен иметь начальное значение, от herwise этот EL:

update=":itemForm:myAccordion:#{playgroundView.activeIndex}:itemName" 

рассосется неправильно и выдаст ошибку, что он не может найти идентификатор ссылочного компонента. Это, конечно, имеет тот недостаток, что закладка первого будет открыта при загрузке страницы, но это другой вопрос

private String activeIndex = "0"; 

public String getActiveIndex() { 
    return activeIndex; 
} 

public void setActiveIndex(String activeIndex) { 
    this.activeIndex = activeIndex; 
} 

PlaygroundController Bean:

private List<User> users; 
@Override 
    public void initializeView() { 
    createUsers(); 
} 

public void createUsers() { 
     User user1 = new User(); 
     User user2 = new User(); 
     User user3 = new User(); 
     user1.setName("User123"); 
     user1.setAmount(1); 
     user2.setName("User456"); 
     user2.setAmount(2); 
     user3.setName("User12312345111111111111111111111111111"); 
     user3.setAmount(3); 
     List<User> userList = new ArrayList<User>(); 
     userList.add(user1); 
     userList.add(user2); 
     userList.add(user3); 
     users = userList; 
    } 

Пользователь:

public class User implements Serializable { 
    String name; 
    int amount = 0; 
} 
+0

Пожалуйста, сделайте это, поскольку мне все же нужен ответ. Afaics – Kukeltje

+0

По запросу - добавлен MCVE –

+0

, для чего стоит MCVE? – amphibient