<f:ajax>包含一个未知的id无法在组件的上下文中找到它</f:ajax>

时间:2013-09-26 10:14:23

标签: ajax jsf jsf-2 event-handling selectmanycheckbox

每次用户从h:selectManyCheckbox更改选定值时,我都会尝试刷新布尔变量的状态。我有调查从DB动态加载。有两种类型的问题多选和单选。当其中一个问题的答案具有布尔值(需要额外答案)时,选择此选项后,应显示inputText。我成功地为单选题和SelectOneRadio创建了这个解决方案,它可以按照我的意愿工作。

不幸的是,它不适用于SelectManyCheckbox。当我将<f:ajax>标记放入<f:selectItems ... >时,它会抛出错误:

错误: javax.servlet.ServletException: <f:ajax> contains an unknown id 'podgladAnkietyForm:repeatLoop:2:selectBoxes' - cannot locate it in the context of the component selectBoxes

我认为这是<ui:repeat>的某种问题。当我尝试使用selectManyBox执行类似的代码但在ui:repeat循环之外它可以工作。此外,几乎相同的代码与<h:selectOneRadio>一起使用! 我尝试了要刷新的绑定组件,更改了绝对路径render=":podgladAnkietyForm:repeatLoop:#{loop.index}:selectBoxes",添加了额外的NamingContainer <f:subView>,但它也没有帮助。 当我删除<f:ajax>标记时,它可以正常工作。结果代码是:

结果HTML代码

        <input name="podgladAnkietyForm:repeatLoop:3:selectBoxes" id="podgladAnkietyForm:repeatLoop:3:selectBoxes:0" value="121" type="checkbox"><label for="podgladAnkietyForm:repeatLoop:3:selectBoxes:0" class=""> Answer content</label>

我不知道我可能做错了什么。有没有人有类似的问题? 我无法删除ui:repeat循环,因为它会加载来自DB的所有问题。一些解决方法?

JSF页面

        <h:form id="podgladAnkietyForm" prependId="true" >
            <ui:repeat value="#{fillSurvey.surveyQuestions}" var="surveyQuestion" varStatus="loop" id="repeatLoop">
                <br/>
                <h:outputText value=" Pytanie #{loop.index  + 1}" styleClass="naglowek" style="font-size: medium;" />
                <h:outputText value=" * odpowiedź obowiązkowa " rendered="#{surveyQuestion.question.isMandatory}" style="color: red; font: small bold"/><br/>
                <h:outputText value="#{surveyQuestion.question.content}" /> <br/>

                <h:panelGroup rendered="#{surveyQuestion.question.isMultiplechoice}" id="multiplechoiceGroup"  > 
                    <h:selectManyCheckbox value="#{surveyQuestion.answers}" id="selectBoxes" layout="pageDirection" required="#{surveyQuestion.question.isMandatory}">     
                        <f:selectItems value="#{surveyQuestion.optionsList}" var="entry" itemLabel="#{entry.content}" itemValue="#{entry.optionId}" id="multiplechoiceOption"   />
                        <f:ajax  />
                        <f:ajax event="click" execute="@this" listener="#{surveyQuestion.checkSelected}" render="selectBoxes" />
                    </h:selectManyCheckbox>     
                    <h:inputText label="Pytanie #{loop.index  + 1}" value="#{surveyQuestion.descriptionValue}" style="display: block;" rendered="#{surveyQuestion.haveDesc}" required="#{surveyQuestion.needDesc}" id="textField" />              
                </h:panelGroup>

                <!-- This part of code works perfectly - SelectOneRadio - After selecting option that require additional description TextInput is showed -->
                <h:panelGroup rendered="#{!surveyQuestion.question.isMultiplechoice}" id="selectOneGroup" >    
                    <h:selectOneRadio value="#{surveyQuestion.selectedItem}" id="selectOneID" layout="pageDirection">
                                <f:selectItems value="#{surveyQuestion.optionsList}" var="entry" itemLabel="#{entry.content}" itemValue="#{entry.optionId}" id="OneSelectOption"   />
                                <f:ajax event="click" execute="@this" render="selectOneGroup" listener="#{surveyQuestion.counter}"  />
                    </h:selectOneRadio>   
                    <h:inputText label="Pytanie #{loop.index  + 1}" value="#{surveyQuestion.descriptionValue}" style="display: block;" rendered="#{surveyQuestion.haveDesc}" required="#{surveyQuestion.needDesc}" size="40"/>              
                    <h:outputText value="#{surveyQuestion.testField}" />
                </h:panelGroup>

            </ui:repeat> 

            <br/><br/>
            <h:commandButton action="#{fillSurvey.validateSurvey()}" value="Validate" /> <br/>
        </h:form> 

支持Bean

public class SurveyQuestion implements Serializable {

Question question;
List<Options> optionsList;
List<String> answers;

boolean haveDesc;
boolean needDesc;
int selectedItem;
String descriptionValue;

int testField;

///Getters and setters

public void counter(AjaxBehaviorEvent e){
        for(Options opt: optionsList){
          if ( selectedItem == opt.getOptionId()) {  
            if(opt.getHaveDesc() || opt.getDescReqr()){        
                this.haveDesc = true;
                    if (opt.getDescReqr()) {
                        this.needDesc = true;
                    } else {
                        this.needDesc = false;
                    }
            } else {this.haveDesc = false; this.needDesc=false; }
          }
        } 
        testField++;
}
//its empty but it will look like the one above
public void checkSelected(AjaxBehaviorEvent e){
    testField++;
}
}

1 个答案:

答案 0 :(得分:2)

这个话题似乎有点过时,但无论如何......

您的f:ajax元素包含在ui:repeat元素中。我的代码中有相同的情况,帮助我的是这张票的答案:f:ajax within ui:repeat, unknown id for the component。简而言之,我必须使用正在渲染的组件的绝对ID,以冒号(:)开头。希望这对你也有帮助。