我目前正在尝试实现一个动态调查页面,其中包含用户(大型应用程序的一部分)定义的页面,部分和问题。用户可以定义不同的问题类型,这些问题类型将呈现不同的组件(无线电,文本区域,文本字段,选择列表等)。此应用当前已部署在Wildfly 16 / Java 8 / JSF 2.3 / Servlet 4中。
由于用户可以为单选按钮定义一组特定的值和关联的图像,因此我需要自定义单选按钮的输出。因此,我的选择是使用group
中可用的新selectoneradio
属性。在多层ui:repeat
中使用此新属性会导致行为不稳定。
为了说明问题,以下示例已简化并创建。
Class
package test; import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.annotation.PostConstruct; import javax.faces.view.ViewScoped; import javax.inject.Named; @Named("test") @ViewScoped public class Test implements Serializable { private static final long serialVersionUID = 1L; private static Map<String, Map<String, String>> questionMap = new TreeMap<>(); private static Map<String, String> fixedValuesMap = new TreeMap<>(); private Map<String, String> answerMap = new TreeMap<>(); private List<String> sections = Arrays.asList("Section_1", "Section_2", "Section_3", "Section_4"); static { fixedValuesMap.put("1", "Value 1"); fixedValuesMap.put("2", "Value 2"); fixedValuesMap.put("3", "Value 3"); fixedValuesMap.put("4", "Value 4"); fixedValuesMap.put("5", "Value 5"); Map<String, String> sec1questions = new TreeMap<>(); sec1questions.put("1", "Question 1"); sec1questions.put("2", "Question 2"); sec1questions.put("3", "Question 3"); questionMap.put("Section_1", sec1questions); Map<String, String> sec2questions = new TreeMap<>(); sec2questions.put("4", "Question 4"); questionMap.put("Section_2", sec2questions); Map<String, String> sec3questions = new TreeMap<>(); sec3questions.put("5", "Question 5"); questionMap.put("Section_3", sec3questions); Map<String, String> sec4questions = new TreeMap<>(); sec4questions.put("6", "Question 6"); questionMap.put("Section_4", sec4questions); } public Test() { } @PostConstruct private void init() { answerMap.put("1", null); answerMap.put("2", null); answerMap.put("3", null); answerMap.put("4", null); answerMap.put("5", null); answerMap.put("6", null); } public String getQuestionType(String index) { switch(index) { case "1": return "RADIO_BUTTON"; case "2": return "RADIO_BUTTON"; case "3": return "RADIO_BUTTON"; case "4": return "TEXT_AREA"; case "5": return "RADIO_BUTTON"; case "6": return "FREE_TEXT"; default: return "FREE_TEXT"; } } public Map<String, String> getQuestions(String section) { return questionMap.get(section); } public Map<String, String> getAnswerMap() { return answerMap; } public Map<String, String> getFixedValues() { return fixedValuesMap; } public List<String> getSections() { return sections; } public void changeRadio(String questionKey, String questionValue) { answerMap.put(questionKey, questionValue); } public String submit() { for(Map.Entry<String, String> entry : answerMap.entrySet()) System.out.println("ENTRY: " + entry.getKey() + " - " + entry.getValue()); return null; } }
XHTML
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:a="http://xmlns.jcp.org/jsf/passthrough"> <h:head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> <meta name="description" content="My Test"/> <link rel="stylesheet" href="#{request.contextPath}/resources/bootstrap/css/bootstrap.min.css" /> <title>My Test</title> </h:head> <h:body> <div class="container-fluid"> <div class="row"> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">UI Repeat Test</h1> </div> <h:form role="form" prependId="false"> <div class="row mx-2"> <ui:repeat var="sec" value="#{test.sections}"> <div class="col-12"> <ui:repeat var="question" value="#{test.getQuestions(sec)}"> <div> <div class="col-12"> <div class="form-group"> <label for="answer">#{question.key} - #{question.value}</label> <div class="col-12"> <h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'FREE_TEXT'}" layout="block"> <h:inputText value="#{test.answerMap[question.key]}" styleClass="form-control"/> </h:panelGroup> <h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'TEXT_AREA'}" layout="block"> <h:inputTextarea value="#{test.answerMap[question.key]}" styleClass="form-control" rows="2" /> </h:panelGroup> <h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'RADIO_BUTTON'}" layout="block"> <table class="radio-label checkbox"> <tbody> <tr> <ui:repeat var="item" value="#{test.fixedValues.entrySet()}"> <td class="text-center grid-margin"> <h:selectOneRadio group="#{question.key}" value="#{test.answerMap[question.key]}" layout="lineDirection" styleClass="checkbox" > <f:selectItem itemValue="#{item.key}" itemLabel="#{item.value}" /> </h:selectOneRadio> </td> </ui:repeat> </tr> </tbody> </table> </h:panelGroup> </div> </div> </div> </div> </ui:repeat> </div> </ui:repeat> </div> <div class="row mx-2 my-2"> <div class="col-12"> <h:commandButton value="Test Me" type="submit" action="#{test.submit}" styleClass="btn btn-primary" /> </div> </div> </h:form> </main> </div> </div> <script src="#{request.contextPath}/resources/jquery/jquery.slim.min.js"></script> <script src="#{request.contextPath}/resources/bootstrap/js/bootstrap.bundle.min.js"></script> </h:body> </html>
提交表单时,仅存储最后一个单选按钮和文本字段值。如果我替换了selectItems ui:repeat
<table class="radio-label checkbox"> <tbody> <tr> <ui:repeat var="item" value="#{test.fixedValues.entrySet()}"> <td class="text-center grid-margin"> <h:selectOneRadio group="#{question.key}" value="#{test.answerMap[question.key]}" layout="lineDirection" styleClass="checkbox" > <f:selectItem itemValue="#{item.key}" itemLabel="#{item.value}" /> </h:selectOneRadio> </td> </ui:repeat> </tr> </tbody> </table>
with
<h:selectOneRadio value="#{test.answerMap[question.key]}" layout="lineDirection" > <f:selectItems value="#{test.fixedValues.entrySet()}" var="item" itemLabel="#{item.key}" itemValue="#{item.value}" /> </h:selectOneRadio>
一切正常。
我确实需要使用第一个选项,因此可以将一些图像添加到单选按钮值中。我想念什么吗?
我目前正在尝试实现一个动态调查页面,其中包含用户(大型应用程序的一部分)定义的页面,部分和问题。用户可以定义不同的问题类型,...