JSF with gettable only - java

I'm trying to achieve a chat system through JSF. All text typed inside h:inputText will be stored after h:commandButton is pressed. After this, I have a table to print all data typed so far. This way, I have the following code for JSF:
<h:form>
<h:inputText id="id1" value="#{unicoBean.text}" />
<h:commandButton id="botao" value="Entrar" action="#{unicoBean.test}"
onclick="test()"
/>
</h:form>
<h:dataTable value="#{unicoBean.all}" var="msg">
<h:column>
#{msg.text}
</h:column>
</h:dataTable>
<script>
function test() {
alert("alert");
}
</script>
And this for backbean:
#ManagedBean
public class UnicoBean {
Facade f = new Facade();
public void setText(String s) throws Exception {
f.setText(s);
}
public List<Message> getAll() throws Exception {
return f.getAll();
}
public void test() {
System.out.println("bean called on jsf");
}
}
Inside h:inputText I want only to set values, not get them and throw back to html. Unfortunately, JSF says "Expression is not gettable", even when I don't want to get anything, only set, as exposed on my Bean. How I solve this?

It's not possible to achieve this using getter/setter strategy because is not part of JSF but Expression Language (EL). JSF only uses it to bind the data of the HTML components to the fields of a bean through proper getters and setters
However, you can use binding attribute via UIInput to pass the input field value as an argument to your action button:
<h:form>
<h:inputText id="id1" binding="#{input1}" />
<h:commandButton id="botao" value="Entrar" action="#{unicoBean.test(input1.value)}"
onclick="test()" />
</h:form>
And then receive the new value from your action method:
public void test(String value) {
System.out.println("bean called on jsf: " + value);
}

Related

How to set a f:selectItem in a specific option after a p:commandButton action?

I have a javascript code that clears all the p:inputText (after a p:commandButton action) of the form. The problem is that the p:selectOneMenu still has the f:selectItem selected in the option it was selected. I need to put the values in the first f:selectItem of each p:selectOneMenu.
How to I do that? How can I clear the selected values?
The java script code:
<script type="text/javascript">
function limpiarForm()
{
document.getElementById("formularioAltas").reset();
}
</script>
formularioAltas is the form id.
The code of the p:commandButton:
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion()}" oncomplete="limpiarForm()" />
And that code does not reset(I dont want to clear the values, I just want to put the first option selected) the values of the p:selectOneMenu
Here it is:
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
The bean:
private RefaccionBean refaccion = null;
/**
* Get the value of refaccion
*
* #return the value of refaccion
*/
public RefaccionBean getRefaccion() {
return refaccion;
}
/**
* Set the value of refaccion
*
* #param refaccion new value of refaccion
*/
public void setRefaccion(RefaccionBean refaccion) {
this.refaccion = refaccion;
}
public void agregarRefaccion() {
I did a lot of things here...
And after those things i clear the p:inputText with the javascript code
-> After that i want to set the values of the p:selectOneMenu in the fist f:selectItem
}
Josef's answer does lead you in the right direction, but since you shared some code, I will just use it in my answer.
First, make sure that your button calls your bean method and updates the selectOneMenu component after it's done. Although there's some ajax going on here, primefaces abstracts that for you.
<p:commandButton value="Guardar" action="#{altasBean.agregarRefaccion}" update="selectOneMenu" />
The update attribute is important as it will look for the component whose id matches whatever is specified there. So you need to give your selectOneMenu an id. If you need to update more than one component, you can add their ids to the update attribute separated by either space or comma.
<h:outputText value="Estado de la refacción" />
<p:selectOneMenu value="#{altasBean.refaccion.estado}" id="selectOneMenu">
<f:selectItem itemLabel="..." itemValue="0" />
<f:selectItem itemLabel="Ok" itemValue="Ok" />
<f:selectItem itemLabel="Reparar" itemValue="Reparar" />
<f:selectItem itemLabel="Sospechoso" itemValue="Sospechoso" />
</p:selectOneMenu>
Now it's just a matter of cleaning up your values inside your action method:
public void agregarRefaccion() {
//If you have other values to clean, clean them here
this.refaccion.estado="0"; //Matches the value for your first item
}
Now I'm not entirely sure if I follow you, but let me know if this helps you out at all. It's entirely JSF and I threw in some ajax. You can play around with your javascript still.
Front-end:
<p:inputText id="input" value="#{bean.value}" />
<p:commandButton value="button" action="#{bean.action}">
<f:ajax execute="input" render="output" />
</p:commandButton>
<p:selectOneMenu id="output" value="#{bean.placeValue}">
<f:selectItems value="#{bean.values}" />
</p:selectOneMenu>
Bean:
#ManagedBean
#RequestScoped
public class Bean {
private String value;
private List<String> values;
#EJB
private ValueService valueService;
#PostConstruct
public void init() {
values = valueService.list();
}
public void action() {
// ... Action taken
}
public String placeValue() {
// ... Validation and clear desired values
return value;
}
// ... (getters, setters, etc)
}

JF2 Dynamic form element doesn't remember input and page refreshes every time I add element

I am trying to make a form with options to add rows. However, after I type in some input and click the add button again, the input I enter disappears. I'm not sure what is wrong with my code. In addition, when I click the add button, the page refreshes. Is there way to stop this page refresh?
Person.java
public class Person{
private List<String> guys = new ArrayList<String>();
public List<String> getGuys() {
return guys;
}
public void setGuys(List<String> guys) {
this.guys = guys;
public void addNewItem(){
guys.add("");
}
}
form.xhtml
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men">
<h:column>
<p:inputText value="#{men}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton name="submit" type="submit" value="Submit"></h:commandButton>
</h:form>
Provided that the bean is placed in the right scope for the functional requirement, the view scope, the only major mistake left is that you're expecting that the String class has some magic setter method.
It hasn't. The String class is immutable. The following will never work on a String:
<p:inputText value="#{men}" />
You have 2 options:
Create a real model class. You can find complete examples in the following answers:
How to dynamically add JSF components
Recommended JSF 2.0 CRUD frameworks
Set the value by row index instead:
<h:dataTable binding="#{table}" value="#{person.guys}">
<h:column>
<p:inputText value="#{person.guys[table.rowIndex]}" />
</h:column>
</h:dataTable>
(note: no additional bean property necessary for the table! the code is as-is)
This does basically a person.getGuys().add(table.getRowIndex(), submittedValue). I.e. the setter is invoked on the List itself, which works perfectly fine. See also the following related answers concerning ui:repeat:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
How map multiple inputText to an array property?
You never update your list, you are just adding empty items. You should do something like this:
Person.java (viewscoped)
public class Person implements Serializable {
private List<String> guys = new ArrayList<String>();
private HtmlDataTable dtGuys;
public void addNewItem() {
guys.add("");
}
public void addToList(ValueChangeEvent e) {
guys.set(dtGuys.getRowIndex(), e.getNewValue().toString());
}
public String save() {
System.out.println("saving...");
for (String item : guys) {
System.out.println("item= " + item);
}
return null;
}
//gettes and setters
}
form.xhtml
<h:form id="frmPrincipal">
<h:panelGrid columns="2">
<h:outputText value="Guys: " />
<h:dataTable value="#{person.guys}" var="men" binding="#{person.dtGuys}" >
<h:column>
<p:inputText value="#{men}" valueChangeListener="#{person.addToList}" />
</h:column>
</h:dataTable>
<h:commandButton name="add" value="Add" action="#{person.addNewItem}" />
</h:panelGrid>
<br />
<h:commandButton id="submit" name="submit" value="Submit" action="#{person.save}"/>
</h:form>
Using jsf 2.0.10 and primefaces 3.5
Its because you don't have an scope for that bean, so its request scoped, so when you call the action the bean is created again, you can fix this using a sessionScope or conversationScope

How to send/recieve data to/from bean function using JSF Richfaces AJAX?

I'm trying to get some code working in an XHTML/JSF/Spring application through which I send an ID to a bean function and expect a string in return. I haven't found an understandable tutorial on this nor any answered question here on SO.
XHTML:
<h:form>
<h:inputText id="inputId" value="#{npBean.idString}"/>
<a4j:commandButton value="get def" render="out">
<f:param value="#{npBean.idString}" name="id" />
<f:setPropertyActionListener target="#{npBean.definition}"/>
</a4j:commandButton>
<a4j:outputPanel id="out">
<h:outputText id="outputId" value="#{npBean.def}"
rendered="#{not empty npBean.def}"/>
</a4j:outputPanel>
</h:form>
Java:
public String getDefinition(int id)
{
def = this.getXService().getXData(id).getDefinition();
return def;
}
All values shown have their getters and setters in the bean.
What we basically do:
Map the value of the <h:inputText> component to a property (with getter/setter) in the managed-bean (which is called myBean)
By using the reRender attribute of the <a4j:commandButton> component, we point which component on the page to be re-rendered (refreshed) when the button is clicked.
When clicking on the button, the invokeService() method from the managedBean is executed and it updates the other property of the managedBean.
In the <h:panelGroup> below, we have several <h:outputText> components and with the rendered attribute we specify when a component has to be displayed on the page.
Exploring the managed-bean, the only thing that is required, are the accessors for the property, which holds the result from the service invoke.
Here's the *.xhtml sample:
<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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:form>
<h:panelGrid columns="3">
<h:outputText value="String value:" />
<h:inputText value="#{myBean.value}" />
<a4j:commandButton value="Click" reRender="out">
<a4j:actionListener listener="#{myBean.invokeService}" />
</a4j:comandButton>
</h:panelGrid>
</a4j:form>
<rich:spacer height="7"/>
<br />
<h:panelGroup id="out">
<h:outputText value="Service returned: " rendered="#{not empty myBean.result}" />
<h:outputText value="#{myBean.result}" />
</h:panelGroup>
</ui:composition>
Managed-bean:
#ManagedBean(name = "myBean")
#SessionScoped //for example
public class MyBean {
private String value;
private String result;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getResult() {
return result;
}
public void invokeService(ActionEvent actionEvent) {
this.result = "Hello, " + value + "!";
}
}
As #Luiggi mentioned, the accessor methods MUST meet the following conventions (if we assume you have a private <some-type> property; in the managed-bean.)
public <some-type> getProperty {
return property;
}
public void setProperty(<some-type> property) {
this.property = property:
}
In order to learn how the RichFaces components work, combined with good code examples, I suggest you open this address and play around with the components.

How to access the bean linked in an attribute of UIComponent?

I need to access the bean object used in a EL expression of an UIComponent.
For example, in this sample code:
xhtml:
<h:form>
<f:view>
<p:selectBooleanButton value="#{baseBean.selected}" onLabel="Instalar" offLabel="Ignorar" onIcon="ui-icon-check" offIcon="ui-icon-close">
<f:validator validatorId="baseValidator.items" />
</p:selectBooleanButton>
<p:commandButton type="submit" value="Submit"
actionListener="#{baseBean.process}"
ajax="false" />
</f:view>
</h:form>
java:
#FacesValidator("baseValidator.items")
public static class BaseValidator implements Validator
{
#Override
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
ValueReference reference = component.getValueExpression("value").getValueReference(context.getELContext());
Object o1 = reference.getBase();
Object o2 = reference.getProperty();
return; //break point here
}
}
When the command button is pressed the BaseValidator.validate is executed, I need to get the baseBean object used in <p:selectBooleanButton value="#{baseBean.selected}">
My code is currently throwing NullPointerException because getValueReference is returning null. How do I get that object inside the validate method?
value="#{baseBean.selected}" should be changed as "#{baseBean.value}"

Primefaces p:menuitem pass an attributes to actionListener

I would like to pass some attributes to actionListener method.
My implementation is like...
<c:forEach items="${customerProductsBean.userProductList}" var="userProduct">
<p:panel toggleable="#{true}" toggleSpeed="500" header="#{userProduct.product}" >
// Some Code... Data Table and Tree Table
<f:facet name="options">
<p:menu>
<p:menuitem value="ProductSetup" actionListener="#{customerProductsBean.getProductSetupData}" >
<f:attribute name="userIdParam" value="#{data.userId}"/>
<f:attribute name="geCustomerIdParam" value="#{data.geCustomerId}"/>
<f:attribute name="acpProductParam" value="#{data.acpProduct}"/>
</p:menuitem>
<p:menuitem value="Remove Product" url="#" onclick=""/>
</p:menu>
</f:facet>
</p:panel>
</c:forEach>
And in Java Action Listener
public void getProductSetupData(ActionEvent actionEvent) {
try {
String userIdParam =
(String)actionEvent.getComponent().getAttributes().get("userIdParam");
String geCustomerIdParam =
(String)actionEvent.getComponent().getAttributes().get("geCustomerIdParam");
String acpProductParam =
(String)actionEvent.getComponent().getAttributes().get("acpProductParam");
} catch(Exception e) {
// Exception
}
}
I tried it using <f:attribute> and <f:param> but was not able to get the value in Java.
In java It shows null for each value.
This won't work if #{data} refers to the iterating variable of an iterating JSF component such as <h:dataTable var>. The <f:attribute> is set during JSF view build time, not during JSF view render time. However, the <h:dataTable var> is not available during view build time, it is only available during view render time.
If your environment supports EL 2.2, do instead
<p:menuitem ... actionListener="#{customerProductsBean.getProductSetupData(data)}" />
with
public void getProductSetupData(Data data) {
// ...
}
Or if your environment doesn't, do instead
public void getProductSetupData(ActionEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
Data data = context.getApplication().evaluateExpressionGet(context, "#{data}", Data.class);
// ...
}

Categories

Resources