Two submits in different forms don't work...
craig12980 Oct 7, 2010 3:37 AMHi
I'm using this environment:
- richfaces 3.3.3
- Spring 3.0.4 for bean handling
- facelets 1.1
- Mojarra 1.2_14
- JVM 1.6
- Tomcat 6.0.18
- Portlebbridge 1.0
- Liferay 5.2.3
What i'm trying to build is a kind of questionary html page where an user can answer to one or more question. Answer to these questions can be or single (only 1 can be choosen) or multiple (the user can choose one or more answer by selecting radio button)
Well if i display only 1 question all works pretty good. If i disply one more 1 question (let's say 2 questions) only 1 submit is done; the other one is not executed.
Maybe i'm missing something....do you have any suggestion? I'll paste all my code (except the template fecelet as it has only some HTML declarations):
showQuestion.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:fmt="http://java.sun.com/jstl/fmt"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:m="http://code.google.com/p/gmaps4jsf/"
xmlns:c="http://java.sun.com/jstl/core"
template="/templateRisposta.xhtml">
<ui:define name="visualizzazione">
<div class="messaggioQuestionario">
<h:outputText value="#{msg.questionMessage}" />
</div>
<rich:panel id="pannelloDomande" styleClass="no-background-panel-footer" rendered="#{not empty visualizzaDomandaCtrl.elencoDomande}">
<rich:jQuery selector="#tabellaRisult tr:odd" query="addClass('odd')" timing="onload" />
<rich:jQuery selector="#tabellaRisult tr:even" query="addClass('even')" timing="onload" />
<table id="tabellaElencoDomande" class="tabella-visualizza-domanda">
<a4j:repeat var="domandaWeb" id="repeaterElencoRisposte" binding="#{visualizzaDomandaCtrl.cmd.repeater}" value="#{visualizzaDomandaCtrl.elencoDomande}">
<c:set var="singola" value="#{domandaWeb.rispostaSingola}"/>
<tr>
<th class="testo-domanda">
<h:outputText value="#{domandaWeb.domanda.testoDomanda}"/>
</th>
</tr>
<tr>
<td class="elenco-risposte">
<a4j:include viewId="/rispostaSingola.xhtml" />
<a4j:include viewId="/rispostaMultipla.xhtml" />
</td>
</tr>
</a4j:repeat>
</table>
</rich:panel>
<c:if test="#{empty visualizzaDomandaCtrl.elencoDomande}">
<div class="elenco-risposte-corrette">#{msg.noQuestion}</div>
</c:if>
</ui:define>
</ui:composition>
rispostaMultipla.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j" xmlns:m="http://code.google.com/p/gmaps4jsf/" xmlns:c="http://java.sun.com/jstl/core" > <a4j:form ajaxSubmit="true" id="visualizzazioneQuestionarioRispostaMultipla" rendered="#{not domandaWeb.rispostaSingola}"> <c:choose> <c:when test="#{visualizzaDomandaCtrl.cmd.showAnswers}"> <a4j:region renderRegionOnly="true" id="regioneElencoRisposteMultiple"> <h:selectManyCheckbox styleClass="selezione-risposta" id="selezionaRisposte" value="#{domandaWeb.elencoRispo}" binding="#{visualizzaDomandaCtrl.cmd.repeaterRisposteMultiple}" layout="pageDirection"> <f:selectItems value="#{domandaWeb.elencoRispoSelIt}" /> </h:selectManyCheckbox> <a4j:commandButton action="#{visualizzaDomandaCtrl.saveRisposte}" immediate="true" reRender="visualizzazioneQuestionarioRispostaMultipla" value="#{msg.selezionaRisposte}"/> </a4j:region> </c:when> <c:otherwise> <c:choose> <c:when test="#{visualizzaDomandaCtrl.cmd.correctAnswer}"> <div class="messaggio-risposta">#{msg.rispostaCorretta}</div> </c:when> <c:otherwise> <div class="messaggio-risposta-errata">#{msg.risposteNonCorrette}</div> <a4j:repeat var="rispostaCorretta" id="repeaterRisposteCorrette" value="#{visualizzaDomandaCtrl.cmd.risposteCorrette}"> <div class="elenco-risposte-corrette"> ·  #{rispostaCorretta.testoRisposta}</div> </a4j:repeat> </c:otherwise> </c:choose> </c:otherwise> </c:choose> </a4j:form> </ui:composition>
rispostaSingola.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j" xmlns:m="http://code.google.com/p/gmaps4jsf/" xmlns:c="http://java.sun.com/jstl/core" > <a4j:form ajaxSubmit="true" id="visualizzazioneQuestionario" rendered="#{domandaWeb.rispostaSingola}"> <c:choose> <c:when test="#{visualizzaDomandaCtrl.cmd.showAnswers}"> <a4j:region renderRegionOnly="true" id="regioneElencoRisposte"> <h:selectOneRadio styleClass="selezione-risposta" id="selezionaRisposta" value="#{domandaWeb.elencoRispo}" binding="#{visualizzaDomandaCtrl.cmd.repeaterRisposte}" layout="pageDirection"> <f:selectItems value="#{domandaWeb.elencoRispoSelIt}" /> <a4j:support ajaxSingle="true" event="onclick" action="#{visualizzaDomandaCtrl.saveRisposta}" immediate="true" reRender="visualizzazioneQuestionario" /> </h:selectOneRadio> </a4j:region> </c:when> <c:otherwise> <c:choose> <c:when test="#{visualizzaDomandaCtrl.cmd.correctAnswer}"> <div class="messaggio-risposta">#{msg.rispostaCorretta}</div> </c:when> <c:otherwise> <div class="messaggio-risposta-errata">#{msg.rispostaNonCorretta}</div> <a4j:repeat var="rispostaCorretta" id="repeaterRisposteCorrette" value="#{visualizzaDomandaCtrl.cmd.risposteCorrette}"> <div class="elenco-risposte-corrette"> ·  #{rispostaCorretta.testoRisposta}</div> </a4j:repeat> </c:otherwise> </c:choose> </c:otherwise> </c:choose> </a4j:form> </ui:composition>
Java code of visualizzaDomandaCtrl(singleton spring bean)
package it.eng.tz.intranet.servizi.quiz.web.controller;
import it.eng.tz.intranet.servizi.quiz.dao.constants.IEngageQuizDaoConstants;
import it.eng.tz.intranet.servizi.quiz.dao.exception.EngageQuizException;
import it.eng.tz.intranet.servizi.quiz.dao.model.EngageRisposta;
import it.eng.tz.intranet.servizi.quiz.dao.model.EngageRisultato;
import it.eng.tz.intranet.servizi.quiz.web.commands.VisualizzaDomandaCommand;
import it.eng.tz.intranet.servizi.quiz.web.utility.ElencoDomandeContainer;
import it.eng.tz.intranet.servizi.quiz.web.utility.EngageWebDomanda;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.faces.component.UISelectMany;
import javax.faces.component.UISelectOne;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class VisualizzaDomandaController extends EngageAbstractQuizController {
private static Log logger = LogFactory.getLog(VisualizzaDomandaController.class.getName());
private VisualizzaDomandaCommand cmd;
private ElencoDomandeContainer dataContainer;
public List<EngageWebDomanda> getElencoDomande() throws Exception{
try {
//Controllo se sono valorizzate le domande; se si non faccio nulla altirmento le carico
if( getDataContainer().getElencoDomande() == null || getDataContainer().getElencoDomande().isEmpty() ){
getDataLoader().loadDefaultDatas();
}
List<EngageWebDomanda> result = getDataContainer().getElencoDomande();
if( getCmd().getDatas() == null || getCmd().getDatas().isEmpty() ){
Map<String, EngageRisposta> datas = Collections.synchronizedMap(new HashMap<String, EngageRisposta>());
List<String> idRisposteCorrette = Collections.synchronizedList(new ArrayList<String>());
for (EngageWebDomanda engageWebDomanda : result) {
Set<EngageRisposta> risposte = engageWebDomanda.getDomanda().getRisposte();
for (EngageRisposta engageRisposta : risposte) {
datas.put(String.valueOf(engageRisposta.getId()), engageRisposta);
if( engageRisposta.getRispostaCorretta().equals(IEngageQuizDaoConstants.RISPOSTA_CORRETTA) ){
idRisposteCorrette.add(String.valueOf(engageRisposta.getId()));
}
}
//Indico che l'utente può rispondere alla stessa domanda + volte se e solo se non si è in produzione e se dal file di configurazione
//viene esplicitato che bisogna evitare la risposta multipla.
if( getCostanti().isProduction() && getCostanti().isAvoidAnswerSameQuestion() ){
engageWebDomanda.setCanAnswer(getEntityMgr().canUserAnswer(getFacesUtil().getPrincipalName(), engageWebDomanda.getDomanda().getId()));
}else{
engageWebDomanda.setCanAnswer(true);
}
if( engageWebDomanda.getDomanda().getTipoDomanda().equals(IEngageQuizDaoConstants.RISPOSTA_SINGOLA) ){
engageWebDomanda.setRispostaSingola(true);
}else{
engageWebDomanda.setRispostaSingola(false);
}
getCmd().setDatas(datas);
getCmd().setIdRisposteCorrette(idRisposteCorrette);
}
}
return result;
} catch (Exception e) {
String msg = "Errore nel recuperare le domande; messaggio di errore: "+e.getMessage();
logger.fatal(msg, e);
throw e;
}
}
public void saveRisposta() throws Exception{
try {
//Siamo nel caso di domanda a risposta singola.
UISelectOne rispostaRepeter = getCmd().getRepeaterRisposte();
String choosenAnswer = (String)rispostaRepeter.getSubmittedValue();
salvaRisposta(choosenAnswer);
} catch (Exception e) {
String msg = "Errore nel salvataggio della risposta; messaggio di errore: "+e.getMessage();
logger.fatal(msg, e);
throw e;
}
}
public void saveRisposte() throws Exception{
try {
//Siamo nel caso di domanda a risposta multipla.
UISelectMany rispostaRepeterMultipla = getCmd().getRepeaterRisposteMultiple();
String[] submittedObjs = (String[]) rispostaRepeterMultipla.getSubmittedValue();
for (int i = 0; i < submittedObjs.length; i++) {
String choosenAnswer = submittedObjs[i];
salvaRisposta(choosenAnswer);
}
} catch (Exception e) {
String msg = "Errore nel salvataggio della risposta; messaggio di errore: "+e.getMessage();
logger.fatal(msg, e);
throw e;
}
}
public void setCmd(VisualizzaDomandaCommand cmd) {
this.cmd = cmd;
}
public VisualizzaDomandaCommand getCmd() {
return cmd;
}
public void setDataContainer(ElencoDomandeContainer dataContainer) {
this.dataContainer = dataContainer;
}
public ElencoDomandeContainer getDataContainer() {
return dataContainer;
}
private void salvaRisposta(String choosenAnswer) throws EngageQuizException{
EngageRisposta risposta = getCmd().getDatas().get(choosenAnswer);
EngageRisultato risultato = new EngageRisultato();
risultato.setCreatoDa(getFacesUtil().getPrincipalName());
risultato.addRisposta(risposta);
risultato.setCorretto(risposta.getRispostaCorretta());
getEntityMgr().createEntity(risultato);
getCmd().setShowAnswers(false);
//Controllo se l'utente ha scelto la risposta corretta o meno.
if( getCmd().getIdRisposteCorrette().contains(choosenAnswer) ){
//risposta corretta
getCmd().setCorrectAnswer(true);
}else{
//Risposta non corretta prendo la risposta corretta
EngageRisposta rispostaCorretta = getCmd().getDatas().get(getCmd().getIdRisposteCorrette().get(0));
List<EngageRisposta> risposteCorrette = Collections.synchronizedList(new ArrayList<EngageRisposta>(1));
risposteCorrette.add(rispostaCorretta);
getCmd().setRisposteCorrette(risposteCorrette);
//Nel caso di risposte multiple devo settare a false la proprieta altrimeni risultera all'utente l'aver risposto bene
getCmd().setCorrectAnswer(false);
}
}
}
Java code of the property cmd(spring bean with scope request and that uses the keepalive annotation):
package it.eng.tz.intranet.servizi.quiz.web.commands;
import it.eng.tz.intranet.servizi.quiz.dao.model.EngageRisposta;
import java.util.List;
import java.util.Map;
import javax.faces.component.UISelectMany;
import javax.faces.component.UISelectOne;
import org.ajax4jsf.component.UIRepeat;
import org.ajax4jsf.model.KeepAlive;
@KeepAlive
public class VisualizzaDomandaCommand {
private UIRepeat repeater;
private UISelectOne repeaterRisposte;
private UISelectMany repeaterRisposteMultiple;
private Map<String, EngageRisposta> datas;
private List<String> idRisposteCorrette;
private boolean showAnswers = true;
private boolean correctAnswer;
private List<EngageRisposta> risposteCorrette;
public void setRepeater(UIRepeat repeater) {
this.repeater = repeater;
}
public UIRepeat getRepeater() {
return repeater;
}
public void setRepeaterRisposte(UISelectOne repeaterRisposte) {
this.repeaterRisposte = repeaterRisposte;
}
public UISelectOne getRepeaterRisposte() {
return repeaterRisposte;
}
public void setDatas(Map<String, EngageRisposta> datas) {
this.datas = datas;
}
public Map<String, EngageRisposta> getDatas() {
return datas;
}
public void setShowAnswers(boolean showAnswers) {
this.showAnswers = showAnswers;
}
public boolean isShowAnswers() {
return showAnswers;
}
public void setIdRisposteCorrette(List<String> idRisposteCorrette) {
this.idRisposteCorrette = idRisposteCorrette;
}
public List<String> getIdRisposteCorrette() {
return idRisposteCorrette;
}
public void setCorrectAnswer(boolean correctAnswer) {
this.correctAnswer = correctAnswer;
}
public boolean isCorrectAnswer() {
return correctAnswer;
}
public void setRisposteCorrette(List<EngageRisposta> risposteCorrette) {
this.risposteCorrette = risposteCorrette;
}
public List<EngageRisposta> getRisposteCorrette() {
return risposteCorrette;
}
public void setRepeaterRisposteMultiple(UISelectMany repeaterRisposteMultiple) {
this.repeaterRisposteMultiple = repeaterRisposteMultiple;
}
public UISelectMany getRepeaterRisposteMultiple() {
return repeaterRisposteMultiple;
}
}
Regards,
Angelo