2012-05-29 3 views
4

Я создаю простую страницу, которая после нажатия кнопки заменит одну группу Panel на другую. Во-первых, код:Оказание компонента вне области формы в JSF2

<h:body> 

    <ui:composition template="/elements/templateWithMenu.xhtml">   
     <ui:define name="content"> 
      <div class="rightContent"> 

       <h:panelGroup id="lol" rendered="#{test.firstStep.booleanValue()}"> 

        <h3>This should disappear</h3> 

        <h:form id="newPollForm1" rendered="#{test.firstStep.booleanValue()}"> 
         <fieldset> 
          <h:commandLink value="Next" action="#{test.firstStepCompleted()}" > 
           <f:ajax execute="@all" render="lol" /> 
          </h:commandLink> 
         </fieldset> 
        </h:form> 

       </h:panelGroup> 

       <h:panelGroup rendered="#{test.secondStep.booleanValue()}"> 
        Works! 
       </h:panelGroup> 

      </div>  
     </ui:define> 
    </ui:composition> 

</h:body> 

Бэк-бэнд просто устанавливает firstStep как false, а secondStep - как истинный.

Теперь, когда я попытался запустить это, я получил <f:ajax> contains an unknown id 'lol' - cannot locate it in the context of the component j_idt39. После небольшого поиска в Google я обнаружил, что для элементов вне области формы мне нужно использовать SEPARATOR_CHAR (:). Это не сработало. Поэтому я попытался использовать разные комбинации # {component} и # {cc}, но ничего не работает. Я даже нашел this удивительное объяснение, но опять же я потерпел неудачу. Если я использую @all, все будет нормально (одна панель заменяется на другую), но мне действительно нужно отобразить конкретный компонент.

Помощь? Пожалуйста?

+0

Как вы использовали 'SEPARATOR_CHAR (:)'? Не можете ли вы просто использовать CSS \ js для достижения этого? –

+0

': lol' и несколько других ': something: somethingElse: lol' (я удалил прикрепленный xhtml столько, сколько мог). – Misa

ответ

5

Вместо этого вам необходимо обновить общий родительский <div class="rightContent">. Это всегда оказано и, таким образом, гарантирует, что JavaScript/Ajax может получить доступ к своим детям. Замените его на <h:panelGroup layout="block"> и дайте ему id.

<h:panelGroup layout="block" id="content" class="rightContent"> 
    <h:panelGroup rendered="#{test.firstStep}"> 
     <h3>This should disappear</h3> 
     <h:form id="newPollForm1"> 
      <fieldset> 
       <h:commandLink value="Next" action="#{test.firstStepCompleted()}" > 
        <f:ajax execute="@form" render=":content" /> 
       </h:commandLink> 
      </fieldset> 
     </h:form> 
    </h:panelGroup> 

    <h:panelGroup rendered="#{test.secondStep}"> 
     Works! 
    </h:panelGroup> 
</h:panelGroup> 

Используя этот Test.java класс:

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 

@ManagedBean 
@ViewScoped 
public class Test { 
    private int number = 0; 

    public void firstStepCompleted() { 
     number++; 
    } 

    public boolean isFirstStep() { 
     return number == 0; 
    } 

    public boolean isSecondStep() { 
     return number == 1; 
    } 
} 

Обратите внимание, что я удалил лишние Boolean#booleanValue() звонки и дублированный rendered contition на форме.

Если это все еще не работает, то /elements/templateWithMenu.xhtml, по-видимому, содержит другой компонент контейнера именования, который добавил его идентификатор. Для тех, кто еще не запомнил все компоненты именования контейнеров, простой способ определить реальный правильный идентификатор клиента - открыть страницу в браузере, rightclick и Просмотреть исходный код, а затем найти созданный JSF элемент HTML и выполнить его id значение атрибута (и префикс его : в <f:ajax render>).

+0

ЭТО РАБОТАЕТ (шаблон не был проблемой)! Спасибо. Просто, чтобы быть уверенным в дальнейших ссылках, как получилось, что «lol» не был общим родителем, или в этом случае, будет ли он работать, если я использую id = «content» во второй панели Panel, а на первом? – Misa

+0

Вот как работает JavaScript/ajax. JavaScript требует, чтобы обновляемый элемент ** всегда ** отображался JSF (и, следовательно, не имеет условия «rendered» в источнике JSF). В противном случае JavaScript не сможет получить к нему доступ и манипулировать его дочерними элементами. JavaScript никогда не удалит весь элемент, только манипулирует/удаляет его дочерние элементы. – BalusC

+0

Получил это. Благодаря! – Misa