How to show primefaces icon error programatically? - primefaces

i have input field and message icon component as follows:
<h:form id="myForm" >
<p:inputText id="email" />
<p:message id="iconMessage" for="email" display="icon" />
and i have a submit button that checks in server side for email existence in database, and if it exists i want to make the error icon appears as follows:
FacesContext.getCurrentInstance().addMessage("myForm:email",
new FacesMessage(FacesMessage.SEVERITY_ERROR, "", ""));
but the error icon won't render, please advise how to fix that.

You have to update the component:
RequestContext.getCurrentInstance().update("myForm:email");
from
org.primefaces.context.RequestContext;
But I would advise specifying a validator instead:
<p:inputText id="email" validator="{yourBean.validateEmail}" />
and in your managed bean:
public void validateEmail(FacesContext context, UIComponent component, Object value) {
String email = value.toString();
//check if email exists in DB
FacesContext.getCurrentInstance().addMessage(component.getClientId(context),
new FacesMessage(FacesMessage.SEVERITY_ERROR, "", ""));
}
}

Related

Primefaces KeyFilter: Not working after calling "ajax update" on h:inputText

Prime faces p:keyFilter stops working when an ajax update happens on h:inputText. Please have a look at the following example.
Expected Behavior:
p:keyFilter should allow only alphabets and numbers in inputText at any point of time.
Steps to reproduce:
1) Go directly to "Project Key" field and try entering special characters.. it will not allow.. the filter works this time.
2) Now go to "Project Name" field and then click on "Project Key". This time try entering special characters. It allows to enter. The filter does not work now.
Sample xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</h:head>
<h:form>
<h:outputText value="Project Name:"></h:outputText>
<h:inputText id="projectName" value="#{testBean.projectName}" >
<p:ajax event="blur" listener="#{testBean.updateKey()}" update="projectKey" process="#form"></p:ajax>
</h:inputText>
<br/>
<h:outputText value="Project Key:"></h:outputText>
<h:inputText id="projectKey" value="#{testBean.projectKey}" label="Project Key" size="29" maxlength="10">
</h:inputText>
<p:keyFilter for="projectKey" mask="alphanum" />
</h:form>
</html>
Sample Managed Bean:
import javax.faces.bean.ManagedBean;
import javax.persistence.Entity;
#ManagedBean(name="testBean")
#Entity
public class Test {
private String projectName;
private String projectKey;
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getProjectKey() {
return projectKey;
}
public void setProjectKey(String projectKey) {
this.projectKey = projectKey;
}
public void updateKey()
{
if(projectName.equals("Shivani"))
{
projectKey = "SK";
}
}
}
This error was reported to PrimeFaces: https://github.com/primefaces/primefaces/issues/3596
The bug was in the Jquery KeyFilter Plugin itself here: https://github.com/akzhan/jquery-keyfilter/issues/7
The patch has been applied and will be in PrimeFaces 6.3 and higher.
The PrimeFaces keyfilter is applied when the keyFilter is 'rendered'. The way it is applied can be seen in the source of the keyfilter.js.
In the PrimeFaces showcase (and documentation) you'll see two examples:
<p:inputText id="text1" value="....">
<p:keyFilter regEx="/[ABC]/i"/>
</p:inputText>
<h:outputText value="KeyFilter with mask on a h:inputText"/>
<h:inputText id="text2" value="..."/>
<p:keyFilter for="text2" mask="num" />
One where the p:keyFilter is nested and one where the for attribute is used. The latter will not be automatically reapplied after an update of the input, but the former will.
If you do need the non-nested way, make sure you update both the input and the keyfilter by either explicitly updating both, or nesting them both in e.g. a h:panelgroup id="inputAndFilter" and updating that.
<h:panelgroup id="inputAndFilter">
<h:inputText id="text2" value="..."/>
<p:keyFilter for="text2" mask="num" />
</ui:panelgroup>

Customizing a p:growl message

<h:form id="aform">
<p:growl id="debug-growl" showSummary="true" showDetail="true" sticky="false" />
<p:inputText id="expression" value="#{debug.expression}"
required ="true" requiredMessage="Value is required" />
...
If user did not provide an input and submit the form then a pop-up appears and it contains two lines of info.
Value is required
Value is required
I would like to change the subject of the pop-up (a bold part of it) to Error for instance.
How can I make it?
The bold part of your growl message is the summary message, like a heading. The other one is the detail message. You can disable the one or the other. You've set both on true.
You can define and personalize your message by FacesContext as follows:
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Validation error", "Value is required");
Source: http://www.primefaces.org/showcase/ui/message/growl.xhtml
I hope this helps!

Scroll p:messages into view when it is updated and (error) messages are present

I am working with PrimeFaces messages, I want my whole page to scroll to top when p:messages is rendered.
Assign an ID to your p:message component
<p:messages autoUpdate="true" id="myMessage" />
Then, in your backing bean call RequestContext.scrollTo method:
in PrimeFaces >= 6.0:
PrimeFaces.current().scrollTo("myMessage")
in Primefaces < 6.0:
RequestContext context = RequestContext.getCurrentInstance();
context.scrollTo("myMessage");
which is deprecated in PrimeFaces 6.0
Deprecated with PrimeFaces < 6.2
In you backing bean (that one which produces the messages), you should know when you render a p:message. If so simply execute this:
RequestContext.getCurrentInstance().execute("window.scrollTo(0,0);");
Update:
With the newer PrimeFaces versions (>= 6.2), the approach to execute Javascript on the client side is (by using x and y coordinates):
PrimeFaces instance = PrimeFaces.current();
instance.execute("window.scrollTo(0,0);");
To scroll to an element use the element's clientId:
PrimeFaces instance = PrimeFaces.current();
instance.scrollTo("myElementsClientId");
Find more information here:
http://de.selfhtml.org/javascript/objekte/window.htm#scroll_to
examples with jQuery for smooth scrolling as well: Scroll to the top of the page using JavaScript/jQuery?
Lets say that your button is causing the messages to appear.
XHTML
<p:commandButton value="Save"
oncomplete="scrollToFirstMessage()" />
javascript
//javascript function which scroll to the first message in page
function scrollToFirstMessage() {
try {
PrimeFaces.scrollTo($('.ui-message :first-child').eq(0).parent().attr('id'));
} catch(err) {
//No Message was found!
}
}
Hope this helps.
There are valid answers already that show how to scroll to the p:messages component, but they all require you to execute code in a backing bean. This requires you to do / call the same in each action. None show how to scroll to the messages component when it is rendered (updated).
You can implement a phase listener and check messages are present and if the messages component's clientId is present in the PartialViewContext renderIds:
These client identifiers are used to identify components that will be processed during the render phase of the request processing lifecycle.
Your listener can look something like this:
public class MessagesUpdateListener implements PhaseListener {
private final String MESSAGES_ID = "yourMessagesClientId";
#Override
public void afterPhase(PhaseEvent event) {
// Empty
}
#Override
public void beforePhase(PhaseEvent event) {
FacesContext fc = FacesContext.getCurrentInstance();
if (!fc.getMessageList().isEmpty() &&
fc.getPartialViewContext().getRenderIds().contains(MESSAGES_ID)) {
RequestContext.getCurrentInstance().scrollTo(MESSAGES_ID);
}
}
#Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
}
Make sure to register it in your faces-config.xml:
<lifecycle>
<phase-listener>your.MessagesUpdateListener</phase-listener>
</lifecycle>
Tested with XHTML:
<h:form id="main">
<p:messages id="messages" />
<p:inputText id="text1" required="true" />
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
this<br/>is<br/>a<br/>long<br/>page<br/>this<br/>is<br/>a<br/>long<br/>page<br/>
<p:commandButton value="Update" update="messages text1"/>
<p:commandButton value="No update"/>
</h:form>
To check for global messages, use:
fc.getMessageList(null).isEmpty()
See also:
Add global message when field validation fails

PrimeFaces <f:attribute not working correctly with p:galleria attribute

I have issue when trying to make command link from inside p:galleria component
The problem is despite the fact at run time the link value value="Show present #{present.name} #{present.presentId}" contains the correct value of the id as example value="Show present Foo 1" , when pressing the command link it sends the wrong id of the second object every time
<h:form>
<p:galleria value="#{presentBean.allPresentList}" var="present" panelWidth="500" panelHeight="313" showCaption="true">
<f:facet name="content">
<h:commandLink value="Show present #{present.name} #{present.presentId}" action="pretty:present" actionListener="#{presentBean.setPresentObj}">
<f:attribute name="present" value="#{present.presentId}"/>
</h:commandLink>
</f:facet>
</p:galleria>
</h:form>
#ManagedBean(name="presentBean")
#SessionScoped
public class PresentBean implements Serializable{
ArrayList<Present> allUserPresentList = new ArrayList<Present>();
#PostConstruct
private void usersPresent(){
PresentDao presentDao = new PresentDaoImpl();
allPresentList = (ArrayList<Present>) presentDao.findAllPresents();
}
public ArrayList<Present> getAllUserPresentList() {
return allUserPresentList;
}
public void setAllUserPresentList(ArrayList<Present> allUserPresentList) {
this.allUserPresentList = allUserPresentList;
}
private String presentId ;
public String getPresentId() {
return presentId;
}
public void setPresentId(String presentId) {
this.presentId = presentId;
}
public void setPresentObj(ActionEvent ev){
Object presentOb = ev.getComponent().getAttributes().get("present");
if(presentOb != null){
this.presentId = (String) presentOb;
}else{
presentId = null ;
}
}
}
You need to use a setPropertyActionListener instead of <f:attribute name="present" value="#{present.presentId}"/> as the f:attribute tag is only evaluated when the component is created (only once) not when the component generates html based on the iterated rows.
So you'll need to instead use:
<f:setPropertyActionListener target="#{presentBean.presentId}" value="#{present.presentId}" />
That will set the value of the presentId in your managed bean, so in your action method you can just access the presentId itself already without having to work it out.
Alternatively if you're using a later version of JSF (using Servlet 3.0 or above), then you could create a method in the managed bean which takes the presentId or even the present object as a parameter
e.g. in your managed bean:
public void myAction(Present p){
//do whatever you want with the Present object
}
and in your .xhtml:
<h:commandLink value="Show present #{present.name} #{present.presentId}" actionListener="#{presentBean.myAction(present)}">
</h:commandLink>

Update the page with command bouton primefaces

I want to get the value of the input Textarea and show it in the same page by clicking on the command button "compiler "
however i don't get any result ! and the contnet is only shown when I update with the browser updater
Sh How do I upate the page and the managed beans to show the content of a primefaces textarea in the same page
this is the code:
<p:layoutUnit position="west" size="520" header="Code à executer" resizable="true" >
<h:form id="moncode">
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="guest.xhtml" styleClass="myButtonClass" />
</h:form>
</p:layoutUnit>
<p:layoutUnit position="east" size="550" header="Resultat d'execution" resizable="true" >
<h:outputText value="#{fichier.code}" />
</p:layoutUnit>
<p:layoutUnit position="south" >
my application is about compiling a given code: I write a code and then I executed with the button "compiler" so a file will be created however the file is always created with "null" and I think because the var "code" is not yet set in the managed bean that why I want to update the page so the managed bean ill be set here is compile:
`
private String code;
private String error;
public String getCode() {
return code;
}
public String getError() {
return error;
}
public void setCode(String code) {
this.code = code;
}
public void compile() throws IOException {
File file = new File("C:\\Users\\Rad1\\test.c");
PrintWriter ecrivain;
ecrivain = new PrintWriter(new BufferedWriter (new FileWriter(file)));
ecrivain.println(code);
ecrivain.close();
`
There are two ways to achieve what you want: either by using a synchronous submit of a form with a subsequesnt postback, or by sending an AJAX request to partially update necessary parts of the page.
Synchronous submit
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="#{fichier.action}" styleClass="myButtonClass" ajax="false" />
<h:outputText id="upd" value="#{fichier.code}" />
with action method
public String action() {
//do business job
return null;
}
This way a fields will be refreshed by making a postback. Don't forget that the bean Fichier must be view scoped. Note the ajax="false" attribute of <p:commandButton>.
AJAX call
<p:inputTextarea id="mycode" value="#{fichier.code}" rows="17" cols="50" />
<p:commandButton value="compiler" id="btn3" action="#{fichier.action}" styleClass="myButtonClass" update="upd" />
<h:outputText id="upd" value="#{fichier.code}" />
with the same action method
public String action() {
//do business job
return null;
}
This way only the contents of <h:outputText> will be updated after AJAX call is finished. Don't forget that the bean Fichier should also be view scoped. Note that id attribute of <h:outputText> must be specified.
Actually, you don't call the action itself. Your action forwards to a certain page. There is no race condition or syncronization problems in a JSF action betwwen setting the properties and the action itself. I recommend you to read JSF life cycles tutorial by BalusC Aplly request values phase run before the action.
Try to call action on command Button.
<p:commandButton value="compiler" id="btn3" action="#{fichier.compile}" update="outputCode" styleClass="myButtonClass" />
Add an id attribute to your output panel and specify it in the action button.
<p:layoutUnit id="outputCode" position="east" size="550" header="Resultat d'execution" resizable="true" >
<h:outputText value="#{fichier.code}" />
</p:layoutUnit>
P.S. It is also good to read this BalusC answer for better understanding of actions, Ajax/non Ajax request etc.