I'm using JSF 2.0. I'm using the
<h:messages>
tag to render error messages. I can use css to style my messages a little bit but I've create a composite component to render messages that can be closed and adding effects to them with some Jquery.
I've seen tutorials on how to customize the messages, but most of these rely on css and customizing the text output yet what I want to do is generate specific markup, something like
<myComp:fancyMessage text="etcetcetc error msg" type="error" />
instead of the regular message markup.
Is this possible?
EDIT:
I don't want to style up jsf messages. Neither add background nor change its style, but rather create my own message html markup. Here:
http://balusc.blogspot.com/2010/07/using-html-in-jsf-messages.html
I've found how to add html to your messages. What I want is to encapsule all the html in my composite component, and then just use my composite component in this way:
<mycomp:messages/>
or
<mycomp:message for="componentID" />
where message and messages both create their own html markup
Use FacesContext#getMessageList() inside ui:repeat. Each item is a FacesMessage which has several getters.
<ui:repeat value="#{facesContext.messageList}" var="facesMessage">
Severity: #{facesMessage.severity}<br />
Summary: #{facesMessage.summary}<br />
Detail: #{facesMessage.detail}<br />
<br />
</ui:repeat>
This allows for more fine-grained HTML markup around the messages.
And it also enables you to print them as HTML with help of <h:outputText escape="false">. I might need to expand and revise my blog article sooner or later :)
In reply to how to set your component as message renderer:
Your component needs to extend HtmlBasicRenderer.
Then you can add your renderer to faces-config.xml
<render-kit>
<renderer>
<component-family>javax.faces.Messages</component-family>
<renderer-type>javax.faces.Messages</renderer-type>
<renderer-class>com.mypackage.MessagesRenderer</renderer-class>
</renderer>
</render-kit>
I know it's been a while, but thought to share this alternate solution for the benefit of others. For composites, create a backing component with a getter, then iterate over the faces messages and call remove() after collecting each message. This will get you around the "messages queued" warning without the h:messages hack.
xhtml:
<composite:interface displayName="Messages Component"
shortDescription="Messages Component" componentType="com.company.dept.commons.ui.messages.Messages">
<composite:attribute name="styleClass" default="" type="java.lang.String" shortDescription="CSS style class for the component" />
</composite:interface>
<composite:implementation>
<div id="messagesComponent" class="#{cc.attrs.styleClass}">
<ui:repeat value="#{cc.messageList}" var="message">
#{message.severity} - #{message.detail}<br/>
</ui:repeat>
</div>
</composite:implementation>
Backing component:
#FacesComponent("com.company.dept.commons.ui.messages.Messages")
public class Messages extends UINamingContainer {
private List<FacesMessage> messages;
public List<FacesMessage> getMessageList() {
//preserve messages in case getter is called multiple times
if (messages == null) {
messages = new ArrayList<FacesMessage>();
}
Iterator<FacesMessage> messageItr = getFacesContext().getMessages();
while(messageItr.hasNext()) {
FacesMessage message = messageItr.next();
messages.add(message);
messageItr.remove();
}
return messages;
}
}
Note the componentType in the xhtml is set to the FacesComponent value in the code. Also, the reference to cc.messageList will trigger the call to getMessageList().
Hope this helps.
Related
how to make a custom text box in Google web toolkit(gwt) having balloon feature of displaying error messages?
i am using Google web toolkit(gwt) in java on eclipse and i don't see any function providing this functionality.
You should implement your own "composite". To "compose" a "balloon"/tooltip with the inputs of your form.
Here is an example of the ui.xml for a text area using Gwt-bootstrap. (Doing the same in plain GWT is straightforward, if not, I'll be glad to convert this example).
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<b:WellForm>
<b:Fieldset>
<b:ControlGroup>
<b:Label styleName="field_label" ui:field="label" />
<b:TextArea ui:field="myWidget"/>
<b:HelpInline ui:field="errorMessage" visible="false" />
</b:ControlGroup>
</b:Fieldset>
</b:WellForm>
If by "balloon" you mean "tooltip", then add a mouseOverHandler and a mouseOutHandler to display/hide the error message (HelpInline here, but could be any widget) when there is one to display.
If you are satisfied with this you should implement some inheritance mechanism to reuse everything around this tag
<b:TextArea b:id="textArea" ui:field="textArea"/>
for all kinds of widgets.
By using composite you can have a single line reused for all error messages ("balloons" or something else) for all your input widgets, and switch between HelpInline, Label, etc easily.
EDIT
The sample code with plain GWT
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HorizontalPanel ui:field="widgetContainer">
<g:Label styleName="field_label" ui:field="label" />
<g:TextArea ui:field="myWidget"/>
<g:Label ui:field="errorMessage" visible="false" />
</g:HorizontalPanel>
I suggest using a HorizontalPanel to display the field's label (ui:field="label"), the input field itself (ui:field="myWidget") and the error message (ui:field="errorMessage") on one line, but other kind of panels are also possible, or you can use CSS to position the elements as you want.
I'm new to JSF 2.0 and am trying to output a message to my page. I want to have a form that accepts some input, does some processing, and displays some output. Seems pretty simple right? However, I don't want to define a property in my backing bean to display the output via:
<h:outputText value="#{bean.property}" />
That approach seems very messy to me; I would need a member variable for every status message I want to display. I also don't want to bind the output display to a form variable as in:
<h:inputText id="someId" />
<h:message for="someId" />
because there is no corresponding form variable for my status result. Setting a message and using the global messages:
<h:messages globalOnly="true" />
doesn't work well either because I might need to update multiple elements on the page (not lump all my status messages into the same div).
Coming from Spring MVC, one can set arbitrary properties on the ModelAndView object that is passed to the View, and then access those properties from within the view. Is there a corresponding way of doing this in JSF?
Thank you.
In order to make arbitrary variables easily available to the view, you could define a Map in e.g. request scope by putting the following in faces-config.xml:
<managed-bean>
<description>Request scoped map for general usage</description>
<managed-bean-name>map</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
You can inject this map in your backing bean, or programmatically request it, and then put something in it. E.g.:
#ManagedBean
public class GeneralMapBacking {
#ManagedProperty("#{map}")
private Map<Object, Object> map;
public void onPreRenderView() {
map.put("foo", "bar");
}
public void setMap(Map<Object, Object> map) {
this.map = map;
}
}
You can reference this map via EL on your Facelet, e.g.:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:body>
<f:event listener="#{generalMapBacking.onPreRenderView}" type="preRenderView" />
#{map.foo}
</h:body>
</html>
Not sure I understand the question. I am also unfamiliar with Spring MVC and that example passed me by I must say.
However I think it basically sounds like you want to either construct the output serverside or use another component.
For example use a single <h:outputText>and use it with a getter that returns concatenated data.
Or perhaps you should use a <h:dataTable> to display your data?
Or maybe you want to output using some other component. It sounds like you just want a box with text and for that I myself would use the concatenated outputText.
For good looking output you might want to look into primefaces, richfaces or icefaces. I prefer primefaces myself and maybe this would look nice:
http://www.primefaces.org/showcase-labs/ui/dataListUnordered.jsf
I have an h:inputText element and an h:message for it:
<h:form id="cancelForm">
<h:inputText id="days" />
<h:message for="days" />
</h:form>
So when I open the page, JSF renders a "span" element for the error message. This is ok.
When I press submit the application goes to java and validates the fields:
// Some code
if (error) {
FacesContext.getCurrentInstance().addMessage("days", new FacesMessage("Error message"));
return error();
}
But after this JSF does not render the "span" for h:message.
Why?
days is just the simple ID for the inputText component. For the addMessage call you need the full ID (the client ID).
You can obtain the client ID by looking at the rendered HTML source code, or if all parent naming containers on your Facelet have IDs, guess it. It's typically all the parent IDs concatenated with : as a separator.
To always get the 100% correct ID, bind the inputComponent to your backing bean and in the code fragment you show above query it for its ID.
Finally, one word of advice: typically the kind of error checking and adding faces messages is done via a Validator and/or Converter. Doing this in a backing bean should not be your first approach.
I created a simple input field for an int variable. I want to add validation to it but, but i see no need to create my own validator for it, since the only thing i need is to avoid negative values and characters other than numbers.
So this is what i did:
<h:inputText id="price" value="#{placeAddControler.price}">
<f:validateLongRange minimum="0"/>
</h:inputText>
<h:outputText value="€" />
<br/>
<span style="color: red;"><b><h:message for="price"
showDetail="true" /></b></span>
When i try how it works this is the result for negative values:
And this is the result for characters:
Where in my project can i customize the text of those validation messages?
To change these values you basically have to define your own Resources file, override the properties you want custom messages for and register it in web.xml. This link seems to explain it well, so I've included this rather than try and rewrite the content.
For a simpler solution and as you are JSF 2 you can also use these attributes of the inputText component:
requiredMessage="I am a custom message"
converterMessage="I am a custom message"
validatorMessage="I am a custom message"
This will override any message which the validator itself spits out.
But I'd prefer the Resource bundle, as that promotes consistency of user visible error messages across your application.
You can register a message bundle and customize those messages. This is a pretty decent example/tutorial:
http://www.mkyong.com/jsf2/customize-validation-error-message-in-jsf-2-0/
i've beeing playing with zk a while and now comes serious things.
I've successfull integrated spring and zk and the routing
works as i use #controller annotation.so far so good
Now i needed to call a webservice which return a list of objects
import org.springframework.ui.Model;
//.....
#RequestMapping("/accounts/personal/list")
public String list(Model model){
try {
ArrayOfAccount result = port.getAccounts( null, 0, 20);
//i thought with this i can grab the result collection.
List<IAccount> accounts = result.getIAccount();
model.addAttribute("accounts", accounts);
} catch (Exception ex) {
// TODO handle custom exceptions here
}
return "accountslist";
}
the real problem is to get the object in the zul file.
<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/templates/mainlayout.zul"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<!--<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>-->
<!--<?variable-resolver class="org.zkoss.spring.init.WebflowVariableResolver"?>-->
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk xmlns="http://www.zkoss.org/2005/zul">
<window self="#{define(content)}" id="pAccountWin">
<label id="lblTest" value="click me" />
<div>
<listbox model="${c:l('accounts')}" id="lstAccount" multiple="true">
<listhead>
<listheader label="Account Name" />
<listheader label="Account Type" />
<listheader label="Mobile Phone" />
</listhead>
<listitem forEach="${c:l('accounts')}" value="${each}" >
<listcell label="${each.getAccountName()}" />
<listcell label="${each.getAccountType()}" />
<listcell label="${each.getMobilePhone()}" />
</listbox>
</div>
</window>
</zk>
it's not throwing an error but i feel like i'm not doing something right.And i also know that i can use GenrericForwardComposer to achieve the
same wihtout "hassle"(i believe).this confuses me about whether i'm doing the right thing.
question 1:
How can i achive what i was trying to do as in passing the accounts variable to the frontend?
question 2 :
What's the best way using ZKspring(no webflows)? Spring Controller to do the routing and ForwardComposer to handle the ajax behaviors (ie events)? for example should a write the code to handle the ajax call when going solely the Spring MVC way?
question 3:
i'm using listbox in this but i would need to do things from context menu on selected object.do you thing grid is suitable for it?
thanks for reading this.
Question 1 answer: ${c:l('accounts') will retrieve a label value with key accounts from i3label-properties file (normally used for internationalization in ZK). If you want to access a variable (normally a Java bean)
1. declare variable resolver at the top of your page using <variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?> directive
2. access Java bean in ZUML using EL expressions for. eg. ${accounts}
Question 2 answer: I would recommend doing it ZK MVC way i.e extend you controllers from ZK GenericForwardComposer to handle events. You can always use spring to handle the lifecycle of these controller using Spring framework.
Question 3 answer: I don't think there is any advantage using grid over listbox in this scenario. In any case you can popup context menu on either grid row select event or listbox listitem select event.