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