I have a JSP with a managed bean.
I want to display a message on the page, not related to any component, so, I do not need to use the "for" attribute.
My message code:
public void foo(ActionEvent event)
{
FacesContext context= FacesContext.getCurrentInstance();
if(true)
{
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("BMW.");
message.setDetail("BMW detail.");
context.addMessage("foo", message);
}
}
How do I display this message?
Sounds like the <ice:messages /> tag will be the right choice for you.
ICEfaces ice:messages TLD
Related
I am creating a form using form-components. I have email-field and UserName field. I want to send an email to the given email id on click of submit button. In the form I select my custom action type which invoke a servlet which is responsible to send an email. My custom action type has only forward.jsp as script file :
<%#page import="com.day.cq.wcm.foundation.forms.FormsConstants"%><sling:defineObjects/><%
System.out.println(":::::::::::::::"+resource.getPath());
FormsHelper.setForwardPath(slingRequest, resource.getPath() + ".custommail.html");
FormsHelper.setRedirectToReferrer(request, true);
%>
I can see my forward.jsp is getting called when i click submit button, as i can see resourcePath(content/geometrixx/en/toolbar/newsletter/jcr:content/par/start) in stdout.log. But servlet not getting call, In case i hit localhost:4502/content/geometrixx/en/toolbar/newsletter/jcr:content/par/start.custommail.html servlet gets invoke, don't know why its not invoking with FormsHelper.
And also how can we pass parameter i.e. email-field to servlet.
Any Idea.
Thanks
You need to have a servlet registered to your form start component and the proper selector. If you are using the foundation form this would be something like this:
#SlingServlet(resoruceTypes = "foundation/components/form/start", methods = "POST", selectors = "custommail", extenstions = "html", generateComponent = false)
public class CustomMailServlet extends SlingAllMethodsServlet {
#Override
protected void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException {
//your code here
}
}
Checkout this blog http://labs.sixdimensions.com/blog/2012-08-20/sending-email-adobe-cq-api/ to get and understanding of Email functionality in AEM.
I read that the renderURL will be responsible to execute the renderPhase only (That is the doView Method of the java class )
Now in one of the JSP i have a Hyper Link to navigate to the another page as shown
(This is the starting page of the Portlet)
<a href="<portlet:renderURL>
<portlet:param name="goto" value="IpByHourPage"/>
<portlet:param name="jspPage" value="/page2.jsp" />
</portlet:renderURL>">
Click here to go to Second Page
</a>
Now my question is that , is it possible taht instead of getting the parameters inside the page2.jsp and processing it , is it possible that to recieve these parameters inside the java file that is
I want to recieve this parameters inside the SecondPort as shown below .
For example
public class SecondPort extends MVCPortlet {
public void doView(RenderRequest renderRequest, RenderResponse renderResponse throws IOException, PortletException
{
// do something in this code here .
}
Yes, you can get your parameter set in <portlet:param> tag in your portlet class.
You can read that parameter in doView method by following :-
public class SecondPort extends MVCPortlet {
public void doView(RenderRequest renderRequest, RenderResponse renderResponse throws
IOException, PortletException
{
String goto = renderRequest.getParameter("goto");
String jspPage= renderRequest.getParameter("jspPage");
//Do something here....
}
like this..
In Wicket 1.4, I had a custom AbstractResourceStreamWriter (used in a custom kind of Link for streaming a file that gets generated on the fly):
private AbstractResourceStreamWriter resourceStreamWriter() {
return new AbstractResourceStreamWriter() {
#Override
public void write(OutputStream output) {
try {
reportService.generateReport(output, report);
} catch (ReportGenerationException e) {
// ...
}
}
#Override
public String getContentType() {
return CONTENT_TYPES.get(report.getOutputType());
}
};
}
In Wicket 1.5, the IResourceStreamWriter interface has been changed so that the method gets a Response instead of OutputStream. It is somewhat confusing that the IResourceStreamWriter javadocs still talk about OutputStream:
Special IResourceStream implementation that a Resource can return when
it directly wants to write to an output stream instead of return the
IResourceStream.getInputStream()
...
Implement this method to write the resource data directly the the
given OutputStream.
Anyway, I don't see a quick way of getting an OutputStream from the Response.
Given that I have a method (the call generateReport(output, report) in above code) which expects an OutputStream to write into, what's the simplest way to make this work again?
What about
ByteArrayOutputStream baos = new ByteArrayOutputStream();
reportService.generateReport(baos, report);
response.write(baos.toByteArray());
or something similar?
There is a org.apache.wicket.request.Response#getOutputStream(). But again I'm not sure this is the same as in 1.4.x. In 1.5 this will buffer what you write in the output stream. Where the javadoc says it shouldn't be buffered.
I'm trying to make my text fields erroneous when validation fails for a form component.
I'm adding an "error" value to my textfield class attribute which makes it red.
I do this by overriding the onValidate() method on the form and loping my components to see if they have errors.
#Override
protected void onValidate() {
super.onValidate();
Iterator<Component> compIter = iterator();
while(compIter.hasNext()) {
final Component comp = compIter.next();
if(comp instanceof AbstractTextComponent<?>) {
comp.add(new AttributeAppender("class", new Model<String>() {
#Override
public String getObject() {
return (comp.hasErrorMessage())?"error":"";
}
}, " "));
}
}
}
This works, but when I look at the generated HTML:
<input id="user_username" class="normal error error error" type="text" name="user.userName" value="stijn" maxlength="25" wicket:id="user.userName">
It generates the error value 3 times.
What am I doing wrong?
Is this the best way to accomplish this in wicket or are there better ways???
thx,
Koen
I don't know why it prints 3 times "error". Instead of writting your own tool you could use this one.
https://cwiki.apache.org/WICKET/automatic-styling-of-form-errors.html
If there's a form, and has a textbox and a button, how do you erase the content of the textbox after you submit the form?
<h:inputText id="name" value="#{bean.name}" />
<h:commandButton id="submit" value="Add Name" action="#{bean.submit}" />
After I enter a value in the textbox and submit, the value still appears in the textbox. I need to clear the content of the textbox once its been submitted. How can I achieve this?
Introduction
There are several ways to achieve this. The naive way is to simply null out the fields in backing bean. The insane way is to grab JS/jQuery for the job which does that after submit or even during page load. Those ways only introduces unnecessary code and indicates a thinking/design problem. All you want is just starting with a fresh request/page/view/bean. Like as you would get with a GET request.
POST-Redirect-GET
The best way is thus to just send a redirect after submit. You probably already ever heard of it: POST-Redirect-GET. It gives you a fresh new GET request after a POST request (a form submit), exactly as you intended. This has the additional benefit that the previously submitted data isn't re-submitted when the enduser ignorantly presses F5 afterwards and ignores the browser warning.
There are several ways to perform PRG in JSF.
Just return to same view with faces-redirect=true query string. Assuming a /page.xhtml, you could do so in action method:
public String submit() {
// ...
return "/page.xhtml?faces-redirect=true";
}
If you're still fiddling around with navigation cases the JSF 1.x way, then it's a matter of adding <redirect/> to the navigation case in question. See also How to make redirect using navigation-rule.
To make it more reusable, you can obtain the view ID programmatically:
public String submit() {
// ...
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
return view.getViewId() + "?faces-redirect=true";
}
Either way, if you've view parameters which needs to be retained in the request URL as well, then append &includeViewParams=true to the outcome. See also Retaining GET request query string parameters on JSF form submit.
If you're making use of some URL rewriting solution which runs outside JSF context, then you'd best grab the current request URL (with query string) and use ExternalContext#redirect() to redirect to exactly that.
public void submit() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
StringBuffer requestURL = ((HttpServletRequest) ec.getRequest()).getRequestURL();
String queryString = ((HttpServletRequest) ec.getRequest()).getQueryString();
ec.redirect((queryString == null) ? requestURL.toString() : requestURL.append('?').append(queryString).toString());
}
It's only a mess which should really be refactored to some utility class.
Request/View scoped bean
Note that this all works only nicely in combination with request or view scoped beans. If you've a session scoped bean tied to the form, then the bean wouldn't be recreated from scratch. You've then another problem which needs to be solved as well. Split it into a smaller session scoped one for the session scoped data and a view scoped one for the view scoped data. See also How to choose the right bean scope?
Faces Messages
If you've a faces message to be shown as result of successful action, then just make it a flash message. See also How to show faces message in the redirected page.
public String submit() {
// ...
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(clientId, message);
context.getExternalContext().getFlash().setKeepMessages(true);
return "/page.xhtml?faces-redirect=true";
}
Ajax
Only if you happen to have an ajax-only page on which a F5 would always trigger a fresh new GET request, then simply nulling out the model field(s) in action method shouldn't harm that much.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
Pure Java/JSF implementation for double submit prevention
You can blank out the property of the managed bean that should not be repainted when you render the response. This can be done done using code similar to the snippet posted below:
private String name;
public String getName(){return name;}
public void setName(String name){this.name=name};
public String submit()
{
//do some processing
...
// blank out the value of the name property
name = null;
// send the user back to the same page.
return null;
}
The reason for the current behavior can be found in how the JSF runtime processes requests. All JSF requests to a view are processed in accordance with the JSF standard request-response lifecyle. In accordance with the lifecyle, the managed bean contents are updated with the value from request (i.e. the value of DataForm.Name is set) before the application event (DataForm.submit) is executed. When the page is rendered in the Render Response phase, the current value of the bean is used to render the view back to the user. Unless the value is changed in an application event, the value will always be one that is applied from the request.
You can clear the form from the Bean method that gets called when the form is submitted;`
private String name;
private String description;
private BigDecimal price;
/*----------Properties ------------*/
/*-----Getter and Setter Methods---*/
public void save()throws SQLException{
String sql = "INSERT INTO tableName(name,description,price) VALUES (?,?,?)";
Connection conn = ds.getConnection();
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, getName());
pstmt.setString(2, getDescription());
pstmt.setBigDecimal(3, getPrice());
pstmt.executeUpdate();
} catch (SQLException e) {
e.getMessage();
e.toString();
}finally{
conn.close();
clear();
}
}//End Save Method
public void clear(){
setName(null);
setDescription(null);
setPrice(null);
}//end clear`
Notice that the clear() method is called from the save method after all the operations of the save method is complete. As an option you could perform the clearing only if the methods operation was successful...The method below is placed in the ProductController Class...
public String saveProduct(){
try {
product.save();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
The method call from the view/jsp would look like the Following:
<h:commandButton value="Save" action="#{productController.saveProduct}"/>
You can do it with jQuery.
I had the similar problem. I needed to clear popup window form.
<rich:popupPanel id="newProjectDialog" autosized="true"
header="Create new project">
<h:form id="newProjectForm">
<h:panelGrid columns="2">
<h:outputText value="Project name:" />
<h:inputText id="newProjectDialogProjectName"
value="#{userMain.newProject.projectName}" required="true" />
<h:outputText value="Project description:" />
<h:inputText id="newProjectDialogProjectDescription"
value="#{userMain.newProject.projectDescription}" required="true" />
</h:panelGrid>
<a4j:commandButton id="newProjectDialogSubmit" value="Submit"
oncomplete="#{rich:component('newProjectDialog')}.hide(); return false;"
render="projects" action="#{userMain.addNewProject}" />
<a4j:commandButton id="newProjectDialogCancel" value="Cancel"
onclick="#{rich:component('newProjectDialog')}.hide(); return false;" />
</h:form>
</rich:popupPanel>
jQuery code:
$('#newProjectForm').children('input').on('click', function(){$('#newProjectForm').find('table').find('input').val('');});
I added a code snippet how to reset all values for the current ViewRoot recursively for JSF 2 here:
Reset all fields in form
This works for submitted forms showing validation errors as well as for newly entered values in a form.