I'm trying to use Google ReCaptcha in my jsf project.
I've successfully render the gui like this:
<h:form id="contact-form" class="contact-form">
<p:panelGrid styleClass="submitGrid" columns="2">
<div class="g-recaptcha" data-theme="dark" data-sitekey="my-site-Key"></div>
<p class="contact-submit">
<p:commandButton id="contact-submit" styleClass="submit" value="Send" action="#{questionaryBean.validation()}" update="contact-submit,confirmDlg, contact-form" oncomplete="PF('dlg').show()"/>
</p>
</p:panelGrid>
</h:form>
And here's my backing bean:
public void save(){
Map<String,String> requestParams = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
requestParams.get("reportKey");
for(String key:requestParams.keySet()){
System.out.println("key:"+key+" value:"+requestParams.get(key));
}
}
As you can see, I printed all of the request parameters, but I can't see g-recaptcha-response here. And of course if I use String gRecaptchaResponse=requestParams.get("g-recaptcha-response"); ,the String gRecaptchaResponse is null.
Am I doing something wrong?
Related
Currently developping a Java8 web app with JSF and primefaces, and I am succeeding in posting a new form with an Oracle Database. But I think, if there is an error for a reason or another, I would like to inform the user by, instead of redirecting him to another page, just showing him a dialog and say something like "something went wrong, try again later".
So is it possible ? I think I have to combine the following commandButton that output a dialog message with the other commandButton in my form.xhtml. But action and onclick a note compatible, aren't they?
Edit : a growl message could also fit if it is easier
<p:commandButton value="Valider l'enquête" type="button" onclick="PF('dlg2').show();" icon="fa fa-plus-circle"/>
<p:dialog header="Modal Dialog" widgetVar="dlg2" modal="true" height="100">
<h:outputText value="This is a Modal Dialog." />
</p:dialog>
form.xhtml
<h:form>
<div id="postFormulaire" class="ui-g">
<div class="ui-g-5"></div>
<p:selectOneMenu id="comiteMenu" value="#{enquete.idComite}">
<f:selectItems value="#{sessionScope.utilisateur.comites}" var="comite" itemLabel="#{comite}" itemValue="#{comite.idComite}" />
</p:selectOneMenu>
<div class="ui-g-5"></div>
<ui:repeat id="repeater" value="#{enquete.questionsReponses}" var="questResp" class="ui-g-12">
<div class="ui-g-12"><b>#{questResp.question.titreQuestion}</b> #{questResp.question.question} </div>
<div class="ui-g-1"/>
<p:inputTextarea class="ui-g-9" id="reponse" value="#{questResp.reponse.commentaire}" label="f"></p:inputTextarea>
<div class="ui-g-2"/>
<div class="ui-g-2"/><p:separator id="separator" class="ui-g-8" /><div class="ui-g-2"/>
</ui:repeat>
<div class="ui-g-5"/><p:commandButton id="validerForm" class="ui-g-2" icon="fa fa-plus-circle" value="Valider l'enquête"
action="#{enquete.postNewForm()}" process="#form"></p:commandButton><div class="ui-g-5"/>
</div>
</h:form>
#Named
#RequestScoped
public class Enquete implements Serializable {
private List<QuestionReponse> questionsReponses;
private int idUser;
private int idComite;
#PostConstruct
private void init() {
questionsReponses = new ArrayList<>();
List<Question> questions = EnqueteDAO.loadQuestions();
for(int i=0; i< questions.size();i++) {
this.questionsReponses.add(new QuestionReponse(questions.get(i), new Reponse(questions.get(i).getIdQuestion())));
}
}
//validate form
public String postNewForm() {
boolean success = EnqueteDAO.create(questionsReponses, idComite); // this method will return a boolean true if the request has succeeded and false if it did not
return (success ? "../admin.xhtml?faces-redirect=true" : "#" ); //if it succeeded but what to return if not
}
}
I took the example from https://stackoverflow.com/a/3180885/242042 just tweaked it for my needs.
Here's my bean:
#ManagedBean
#ViewScoped
public class ParticipantBean implements
Serializable {
private boolean edit;
private List<Participant> list;
private Participant participant = new Participant();
#Inject
private transient ParticipantDAO participantDAO;
public void add() {
System.out.println("Calling add");
participantDAO.save(participant);
init();
}
public void delete(final Participant participant) {
participant.getAudit().cancel();
participantDAO.save(participant);
init();
}
public void edit(final Participant participant) {
this.participant = participantDAO.get(participant.getId());
edit = true;
}
public void fire() {
System.out.println("fired");
}
public List<Participant> getList() {
return list;
}
public Participant getParticipant() {
return participant;
}
#PostConstruct
public void init() {
list = participantDAO.getAll();
participant = new Participant(); // Reset placeholder.
}
public boolean isInEdit() {
return edit;
}
public void saveParticipant() {
System.out.println("Calling save");
participantDAO.save(participant);
System.out.println("Done Calling save");
init();
edit = false;
}
}
And my JSF file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Really simple CRUD</title>
</h:head>
<h:body>
<h3>List items</h3>
<h:form rendered="#{not empty participantBean.list}">
<h:dataTable value="#{participantBean.list}" var="item">
<h:column><f:facet name="header">ID</f:facet>#{item.id}</h:column>
<h:column><f:facet name="header">Name</f:facet>#{item.name}</h:column>
<h:column><h:commandButton value="edit" action="#{participantBean.edit(item)}" /></h:column>
<h:column><h:commandButton value="delete" action="#{participantBean.delete(item)}" /></h:column>
<h:column><h:commandButton value="fire" action="#{participantBean.fire}" /></h:column>
</h:dataTable>
</h:form>
<h:panelGroup rendered="#{empty participantBean.list}">
<p>Table is empty! Please add new items.</p>
</h:panelGroup>
<h:panelGroup rendered="#{!participantBean.inEdit}">
<h3>Add item</h3>
<h:form>
<p>Name: <h:inputText value="#{participantBean.participant.name}" /></p>
<p><h:commandButton value="add" action="#{participantBean.add}" /></p>
<p><h:commandButton value="fire" action="#{participantBean.fire}" /></p>
</h:form>
</h:panelGroup>
<h:panelGroup rendered="#{participantBean.inEdit}">
<h3>Edit item #{participantBean.participant.id}</h3>
<h:form>
<p>Name: <h:inputText value="#{participantBean.participant.name}" /></p>
<p><h:commandButton value="save" action="#{participantBean.saveParticipant}" /></p>
<p><h:commandButton value="add" action="#{participantBean.add}" /></p>
<p><h:commandButton value="fire" action="#{participantBean.fire}" /></p>
</h:form>
</h:panelGroup>
</h:body>
</html>
So it is quite similar, but what I don't understand is why on the "edit" it does not want to invoke the actions. (i.e. I don't see anything on SystemOut.log)
I was looking at the answer https://stackoverflow.com/a/13327382/242042 to see if there was anything to merit it, but I found that the "System.out.println()" events do not even get fired. The control is there.
One thing I did notice was the commandButtons reload the screen while inEdit
I have eliminated "Prime Faces" as well and I am testing on WebSphere 9.0.0.3. The code is in https://github.com/trajano/jee/tree/no-prime-faces
I also have tried reordering the form such that the edit block is in the form like so but it still the actions do not fire.
<h:form rendered="#{not empty participantBean.list}">
<h:dataTable value="#{participantBean.list}" var="item">
<h:column><f:facet name="header">ID</f:facet>#{item.id}</h:column>
<h:column><f:facet name="header">Name</f:facet>#{item.name}</h:column>
<h:column><h:commandButton value="edit" action="#{participantBean.edit(item)}" /></h:column>
<h:column><h:commandButton value="delete" action="#{participantBean.delete(item)}" /></h:column>
</h:dataTable>
<h:panelGroup rendered="#{participantBean.inEdit}">
<h3>Edit item #{participantBean.participant.id}</h3>
<p>Name: <h:inputText value="#{participantBean.participant.name}" /></p>
<p><h:commandButton value="save" action="#{participantBean.saveParticipant}" /></p>
<p><h:commandButton value="add" action="#{participantBean.add}" /></p>
</h:panelGroup>
</h:form>
I also tried having edit() written this way to get the participant that was on the original list that way it will have the proper optimistic lock #Version
public void edit(final Participant participant) {
this.participant = participant;
edit = true;
}
In JSF 2.2 there are two annotations in different packages named #ViewScoped
javax.faces.bean.ViewScoped ← correct one
javax.faces.view.ViewScoped ← incorrect one introduced with JSF 2.2 (which was what I was using when I wrote the question)
To limit it to JSF 2.2 as per #Jasper de Vries 's comment. The annotations need to change to
#javax.inject.Named
#javax.faces.view.ViewScoped
I have h:selectBooleanCheckbox but it passes 'false' to the validator. always.
<h:panelGroup id="tncPanel">
<label>
<h:selectBooleanCheckbox id="tncSelection" value="#{businessBean.tncSelection}">
<f:validator validatorId="checkboxValidator"/>
<f:attribute name="label" value="Please agree terms and conditions."/>
</h:selectBooleanCheckbox>
I have read and agreed to all the
<a href="#" data-toggle="modal" data-target="#modal-term-and-conditions">
Terms and Conditions.
</a>
</label>
</h:panelGroup>
<h:panelGroup id="buttonPanel">
<h:commandLink id="nextButton" action="#{businessBean.goNext}">
Submit
</h:commandLink>
</h:panelGroup>
Why I have panelGroup here is, based on logic in top of page, I have a logic to display/not the button and checkbox
This is my Validator.
#FacesValidator("checkboxValidator")
public class CheckboxValidator implements Validator {
private static final String DEFAULT_LABEL = "Please confirm the address.";
#Override
public void validate(FacesContext context, UIComponent component, Object value){
String checkBoxValue = String.valueOf(((HtmlSelectBooleanCheckbox) component).getSubmittedValue());
System.out.println("checkBoxValue " + checkBoxValue);
System.out.println("value2: " + value);
String label = String.valueOf(component.getAttributes().get("label"));
if ("null".equals(label)) {
label = DEFAULT_LABEL;
}
if("false".equalsIgnoreCase(checkBoxValue)){
FacesMessage msg = new FacesMessage(null, label);
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(msg);
}
}
}
Validator sysout always prints checkBoxValue false
UPDATE
After comment on Balusc, I add another sysout to print directly the parameter value. But still it's printing as value2: false.
There is a bug related to this situation , When you render a container that holds a from from another form you the rendered form loses its view state ,Thus form is submitted to no destination solution is to render the form container and the form its self from the other form
For example that won't work :
<h:panelGroup id="panel">
<h:form>
<h:commandButton value="Submit" rendered="#{not testAction.flag}">
<f:ajax render=":panel" listener="#{testAction.submit()}"/>
</h:commandButton>
</h:form>
<h:panelGroup id="panel">
<h:form id="secondForm" rendered="#{testAction.flag}">
<h:selectBooleanCheckbox id="checkBox" value="#{testAction.boolVal}">
<f:validator validatorId="checkboxValidator"/>
</h:selectBooleanCheckbox>
<h:commandButton value="Go" action="#{testAction.go()}"/>
</h:form>
</h:panelGroup>
Second form submit will be like this :
secondForm won't have its view state the form is submitted but with no destination on the server cuz the view object is not fetched on the server that requires the javax.faces.ViewState value to be fetched by what you have to do here is to render form as well in the f:ajax:
<f:ajax render=":panel :secondForm" listener="#{testAction.submit()}"/>
That inform server to backup the second form rendered with the javax.faces.ViewState
Refer to that post : Rendering other form by ajax causes its view state to be lost, how do I add this back? for more info
Hope that was the problem :)
I have a form like the following picture.
In the above picture you can see a green add button. When I click on it, it create a new row in a datatable via send a <f:ajax> to backing bean and render <h:datatable>.
Until now all thing is good. But i Except when I click on a cross button inside of each row, that row removed. but it have a bug. for example when I click on the third row cross button, it removes this row from backing bean but not from my ui.
in the following you can see my backing bean and .xhtml file.
#ManagedBean(name = "AddPollContorler")
#ViewScoped
public class AddPollControl {
private List<Answer> answers = new ArrayList<Answer>();
#PostConstruct
public void init(){
answers.add(new Answer());
answers.add(new Answer());
}
public List<Answer> getAnswers() {
return answers;
}
public void setAnswers(List<Answer> answers) {
this.answers = answers;
}
public void addAnswer() {
answers.add(new Answer());
}
public void removeAnswer() {
String index=FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("index");
if (StringUtil.isNumber(index))
answers.remove(Integer.parseInt(index));
}
}
.xhtml :
<div class="panel panel-success rgt">
<div class="panel-heading rgt">
<div style="float: left;">
<h:commandLink styleClass="btn btn-success table-button" action="#{AddPollContorler.addAnswer}">
<h:graphicImage library="img" name="add.png" styleClass=" table-icon" />
<f:ajax execute="answers" render="answers"></f:ajax>
</h:commandLink>
</div>
<h4><h:outputText value="#{msg['protected.poll.add.answers']}"/></h4>
</div>
<div class="form-margin">
<h:dataTable value="#{AddPollContorler.answers}" var="answer" id="answers" style="width:100%;">
<h:column >
<div class="input-group poll-answer" style="margin: 5px;">
<span class="input-group-addon no-left-radius"><h:outputText value="#{CounterControler.index+1}" /></span>
<h:inputText value="#{answer.text}" styleClass="form-control no-radius"/>
<div class="input-group-addon no-right-radius poll-answer-remove" >
<h:commandLink action="#{AddPollContorler.removeAnswer}">
<h:graphicImage library="img" name="cross.png" />
<f:param name="index" value="#{CounterControler.last}" />
<f:ajax render="answers answers" />
</h:commandLink>
</div>
</div>
</h:column>
</h:dataTable>
</div>
</div>
update: 2013/06/12
#ManagedBean(name="CounterControler")
public class CounterControl {
private int index=0;
public int getIndex(){
return index++;
}
public int getLast(){
return index-1;
}
}
your code does look pretty good already. How does the CounterControler internally work? (no source given) Alternatives to send the current object might be
to give the object directly as the parameter (you need a fitting converter for that),
give it as direct parameter (action="#{AddPollContorler.removeAnswer(answer)}, works from EL 2.2 on), or
directly get the current object out of the given ActionEvent
The last point would look like
xhtml
<h:commandLink action="#{AddPollContorler.removeAnswer}">
<h:graphicImage library="img" name="cross.png" />
<f:ajax render="answers" />
</h:commandLink>
managed bean
public void removeAnswer(ActionEvent ev) {
Answer selectedItem = null;
try {
UIDataTable objHtmlDataTable = retrieveDataTable(
(UIComponent)ev.getSource());
selectedItem = (Answer) objHtmlDataTable.getRowData();
answers.remove(answer);
} catch (NullPointerException e) {
// somehow couldn't find the element
}
}
private static UIDataTable retrieveDataTable(UIComponent component) {
if (component instanceof UIDataTable) {
return (UIDataTable) component;
}
if (component.getParent() == null) {
return null;
}
return retrieveDataTable(component.getParent());
}
I like that one because it takes most logic out of the frontend. Hope you get your rows cleaned with one of that tactics.
Also, you only need to mention answers once in <f:ajax render="answers" />
EDIT: Even I don't know why - wrapping a <h:panelGroup layout="block" id=" answersWrapper"> around the <h:dataTable> and rendering that panelGroup worked for me.
<h:form id="myForm">
<h:panelGroup id="answerWrapper" layout="block">
<rich:dataTable value="#{myTestBean.answers}" var="answer" id="answers">
<h:column >
<h:outputText value="#{answer}"/>
<h:commandButton id="button" action="#{myTestBean.doTheAction}">
<f:ajax render=":myForm:answerWrapper" />
</h:commandButton>
</h:column>
</rich:dataTable>
</h:panelGroup>
</h:form>
Im implementing a login in a JSF application and have a problem with the redirection.
I want to make available the login form in every xhtml in the app, but after the login success or fail I want to keep the user in the same page they were when clicked on login.
I have tried to return null in the managedBean methong but that doesnt work because it not refreshes the webPage, I need the page to be refreshed for the view logic to work.
This is the login form:
<h:form id="loginForm" rendered="#{!loginBean.estaLogueado()}">
<p:panel header="#{msg.header_login}">
<h:outputLabel for="login" value="#{msg.login}"/>
<p:inputText id="login" value="#{loginBean.usuario}"></p:inputText><br/>
<h:outputLabel for="pwd" value="#{msg.password}"/>
<p:inputText id="pwd" type="password" value="#{loginBean.password}"></p:inputText><br/>
<p:commandButton action="#{loginBean.login()}" value="Login"/>
</p:panel>
</h:form>
<h:form id="logoutForm" rendered="#{loginBean.estaLogueado()}">
Bienvenido #{loginBean.nombreUsuario}!!<br/>
<p:commandButton action="#{loginBean.logout()}" value="Desconectar"/>
</h:form>
And this is the method in the action attribute:
public String login(){
currentUser = gu.login(usuario, password);
return null;
}
There is a way to return to the xhtml where the user loged, not being a fixed xhtml like "login.xhtml"??
Just redirect to the request URI.
public void login() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(((HttpServletRequest) ec.getRequest()).getRequestURI());
}
As far as i am concern there is 2 ways for this purpose.
You should define the components which need to be updated in update attribute of caller commandButton.
You should do a real refresh by adding ?faces-redirect=true to return value of action.
First solution.
<h:form id="loginForm" rendered="#{!loginBean.estaLogueado()}">
<p:panel header="#{msg.header_login}">
<h:outputLabel for="login" value="#{msg.login}"/>
<p:inputText id="login" value="#{loginBean.usuario}"></p:inputText><br/>
<h:outputLabel for="pwd" value="#{msg.password}"/>
<p:inputText id="pwd" type="password" value="#{loginBean.password}"></p:inputText><br/>
<p:commandButton action="#{loginBean.login()}" value="Login" update=":loginForm :logoutForm"/>
</p:panel>
</h:form>
<h:form id="logoutForm" rendered="#{loginBean.estaLogueado()}">
Bienvenido #{loginBean.nombreUsuario}!!<br/>
<p:commandButton action="#{loginBean.logout()}" update=":loginForm :logoutForm" value="Desconectar"/>
</h:form>
the update attribute will update the components.
Second solution
Add ?faces-redirect=true to your return value of action method for a real refresh
public String login(){
currentUser = gu.login(usuario, password);
return "login?faces-redirect=true";
}