f:ajax not re rendering target DOM element (JBoss error?) - jsf-2

I am running JBoss 7.1.0.Final with the default JSF 2.1 .
I have been having problems getting the render attribute of a f:ajax to work
Here is my code
<h:form>
<h:panelGrid>
<h:inputText value="#{bean.text}" >
<f:ajax event="keyup" render="text"/>
</h:inputText>
<h:outputText id="text" value="#{bean.text}" />
</h:panelGrid>
</h:form>
With a bean:
#ManagedBean(name = "bean")
public class Bean
{
private String text;
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
}
The page renders but the value entered in the inputtext does not render as outputtext.
There does seem to be some interaction with the server as I get
JBAS010152: APPLICATION ERROR: transaction still active in request with status 0
happening on each keyup event?
Note that I am running this within Seam 2.3

Related

why action in <h:commandLink> doesn't work inside a composite component

I have a very simple JSF 2/Facelets page that looks like this:
<ui:repeat value="#{myBean.names}" var="_name">
<h:commandLink value="#{_name}" action="#{myBean.sayHello(_name)}">
<f:ajax execute="#this"/>
</h:commandLink>
<br/>
</ui:repeat>
The backing bean provides a java.util.List<String> with names and the action-method just prints a "hello <name>" message to standard output.
This works fine. I get a list of names in the browser and a click fires the action-method that says hello to the specified name.
The Problem arises, when I want to put this code in a composite component that does the iteration and renders the actual link via a facet:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:cc="http://xmlns.jcp.org/jsf/composite">
<cc:interface>
<cc:attribute name="value" type="java.util.List" required="true" />
<cc:facet name="content" />
</cc:interface>
<cc:implementation>
<ui:repeat value="#{cc.attrs.value}" var="_name">
<cc:renderFacet name="content"/>
</ui:repeat>
</cc:implementation>
</ui:component>
I use the composite component like this:
<my:myComp value="#{bean.names}">
<f:facet name="content">
<h:commandLink value="#{_name}" action="#{bean.sayHello(_name)}">
<f:ajax execute="#this"/>
</h:commandLink>
<br/>
</f:facet>
</my:myComp>
In the browser I get a list of names that looks exactly like before. But clicking a link now renders a "hello null" message. So _name is resolved correctly in the value attribute of <h:commandLink> but not in the action attribute.
I also tried using actionListener instead of action or the listener attribute from the <f:ajax> tag with no difference.
Could anybody shade some light on this issue?
My environment:
WildFly 8.1 with
JSF 2.2.6 (Mojarra)
The issue has to do with the scope of the variable in this case _name which is evaluated once when the <ui:repeat/> is being processed. In my case, I ran your code and it produced Hello John even though their were other names in my list. To get around this, I introduced a <f:param/> that would contain the value of the _name, and modified your code as follows:
<h:form>
<my:myComp value="#{bean.names}">
<f:facet name="content">
<h:commandLink value="#{_name}" action="#{bean.sayHello()}">
<f:param name="name_" value="#{_name}"/>
<f:ajax execute="#this"/>
</h:commandLink>
<br/>
</f:facet>
</my:myComp>
</h:form>
I also modified the sayHello() method as follows for a #RequestScoped bean:
#ManagedProperty(value = "#{facesContext}")
private FacesContext facesContext;
public void setFacesContext(FacesContext facesContext) {
this.facesContext = facesContext;
}
public void sayHello() {
Map<String, String> params = facesContext.getExternalContext()
.getRequestParameterMap();
String name = params.get("name_");
System.out.println("Hello " + name);
}
You could change this to something shorter in a #ViewScoped bean to:
public void sayHello() {
Map<String, String> params = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap();
String name = params.get("name_");
System.out.println("Hello " + name);
}
The final result is that it prints out the names correctly.

outPutText not being updated when a commndButton is pressed

im working on a JSF 2.0 project on TomEE server. i have a problem on a JSF view, im trying to update an outPutText when a button is clicked, but it is not working.
here's the form of the xhtml view:
<h:form>
<h:outputText style="width: 600px;" styleClass="infoVista" value="# {mensajes.BloqueoMaestra}" />
<p:commandButton actionListener="#{procesar.procesarPeticion()}" update="mensaje" value="Buscar Bloqueos">
<f:param name="proceso" value="bloqueo" />
</p:commandButton>
<h:outputText rendered="true" value="#{procesar.respuesta}" id="mensaje" />
</h:form>
And here is the Bean proccesing the view:
#Named("procesar")
#ViewScoped
public class procesarOpcion {
String respuesta = "";
public procesarOpcion(){
}
public String getRespuesta() {
return respuesta;
}
public String procesarPeticion(){
String proceso = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("proceso");
if (proceso.equals("bloqueo")){
respuesta = "Update this ";
}
}
Evething is working, the method procesarPeticion() is being called and the variable respuesta is filled but the view is not updating when i press the Commandbutton.
Thanks for your help.

JSF component no longer rendered, but FacesMessage remains

Here is the situation:
I have a component, whose value is a property of my ViewScoped bean, which gets a FacesMessage generated for it do to some error when the form is first submitted
On a subsequent user action, a h:commandlink is clicked, which uses f:ajax, and its actionlistener sets the component to no longer be rendered
Upon receiving the reponse, the component is no longer rendered (as expected), but the FacesMessage for it still remains and is displayed
I am using Mojarra JSF 2.1, and IceFaces 3.0 - although this example and the problematic behavior are seen using only standard JSF components. Here is a small example that demonstrates the behavior:
test.xhtml
<h:form id="testform">
<h:message for="tv"/>
<h:inputText id="tv" value="#{testBean.testVal}" rendered="#{testBean.testValRendered}" required="true" />
<h:commandButton value="Submit"/>
<h:commandLink actionListener="#{testBean.toggleTestVal}" value="Toggle input">
<f:ajax execute="#this" render="#form"/>
</h:commandLink>
</h:form>
Bean code
#ViewScoped
#ManagedBean(name = "testBean")
public class TestBean {
private String testVal;
private boolean testValRendered;
public TestBean() {
testValRendered = true;
}
public String getTestVal() {
return testVal;
}
public void setTestVal(String testVal) {
this.testVal = testVal;
}
public boolean isTestValRendered() {
return testValRendered;
}
public void setTestValRendered(boolean testValRendered) {
this.testValRendered = testValRendered;
}
public void toggleTestVal(ActionEvent ae) {
testValRendered = !testValRendered;
}
}
If I change the h:commandLink so that it does not use f:ajax, and set immediate='true' on it instead, then the message is removed properly. While this may work in some cases, I would like to understand why using f:ajax to render things as I have in my example does not work. Thanks.
The input component is submitted, processed and validated before its rendering condition has been toggled. The <h:message> isn't aware that the associated input component is not rendered. You'd like to check the very same rendering condition on the <h:message> as well:
<h:message for="tv" rendered="#{testBean.testValRendered}" />
<h:inputText id="tv" ... rendered="#{testBean.testValRendered}" />

dynamic adding radio and InputText in jsf

i am getting problem in editing in textBox which are generated dynamically.
see my code.
<h:form>
<h:panelGroup>
<h:panelGrid columns="2">
<h:panelGrid columns="1">
<h:selectOneRadio id="radio1" value="#{dynamicBean.radiovalue}" layout="pageDirection" >
<f:selectItems value="#{dynamicBean.objectList}" var="k1" itemValue="#{k1.value}" itemLabel="" />
</h:selectOneRadio>
</h:panelGrid>
<h:panelGrid columns="1" rowClasses="raw1">
<c:forEach items="#{dynamicBean.objectList}" var="k3">
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" >
</p:inputText>
</c:forEach>
</h:panelGrid>
<h:commandButton value="add new" action="#{dynamicBean.addNew}"/>
</h:panelGrid>
</h:panelGroup>
</h:form>
and this is my bean.
#ManagedBean
#ViewScoped
public class DynamicBean implements Serializable{
private String radiovalue;
private List<Pojo> objectList=new ArrayList<Pojo>();
int i=0;
private Pojo single=new Pojo();
public DynamicBean() {
System.out.println("In Cons");
if(objectList.isEmpty())
{
Pojo p1=new Pojo();
p1.setName("Name-"+i);
p1.setValue("Value-"+i);
p1.setTextvalue("Text-"+i);
objectList.add(p1);
i++;
setRadiovalue(p1.getValue());
}
}
public void addNew()
{
Pojo p1=new Pojo();
p1.setName("Name-"+i);
p1.setValue("Value-"+i);
p1.setTextvalue("Text-"+i);
objectList.add(p1);
i++;
setRadiovalue(p1.getValue());
}
public void ajaxEvent(ValueChangeEvent e)
{
System.out.println("New:"+e.getNewValue());
System.out.print("Old:"+e.getOldValue());
}
following are three variable in Pojo with getter and setter
private String name;
private String value;
private String textvalue;
biggest confusion is i can change first object value on in text box but i cant change the value of new generated objects.
Thanks.
Your concrete problem is caused because you're using JSTL <c:forEach> tag which runs during view build time while you're using a view scoped bean. View scoped beans are stored in the view state. When you submit the form to the server, the view state will be restored, but the original view scoped bean isn't available yet at that moment and thus a new one will be created (thus, with all properties set to default!). After restoring the view, the original view scoped bean will be put back in scope, overriding the temporary one.
You need a fullworthy JSF UI component instead of a JSTL tag. For this particular purpose, you need the <h:dataTable>.
Replace
<h:panelGrid columns="1" rowClasses="raw1">
<c:forEach items="#{dynamicBean.objectList}" var="k3">
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" >
</p:inputText>
</c:forEach>
</h:panelGrid>
by
<h:dataTable value="#{dynamicBean.objectList}" var="k3" rowClasses="raw1">
<h:column>
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" />
</h:column>
</h:dataTable>
See also:
JSTL in JSF2 Facelets... makes sense?
Unrelated to the concrete problem, you've some code duplication there in the constructor. Just call addNew() method in there. I'd also remove the instance variable i as that makes no sense. Just use a local one instead which get initialized with List#size().
public DynamicBean() {
addNew();
}
public void addNew() {
Pojo p1 = new Pojo();
int i = objectList.size();
p1.setName("Name-" + i);
p1.setValue("Value-" + i);
p1.setTextvalue("Text-" + i);
objectList.add(p1);
setRadiovalue(p1.getValue());
}

Checkbox inside ui:repeat not refreshed by Ajax

I work with Mojarra 2.1.3.
When the user click on button "refresh don't work", it refresh the content of the ui:repeat.I expect the checkbox to be checked, just as at the initialization.
What I've found: If I remove h:head in the facelet "refresh don't work" works... Any idea ?
The facelet:
<h:head></h:head>
<h:body>
<h:form id="myForm" >
<h:panelGroup id="panelToRefreshOutsideRepeat">
<ui:repeat value="#{sandbox.columns}" var="column">
<h:panelGroup id="panelToRefreshInsideRepeat">
<h2>composite onlyCheckbox:</h2>
<trc:onlyCheckbox value="#{column.value}" />
<br />
<h2>composite onlyInputText:</h2>
<trc:onlyInputText value="#{column.value}" />
<br />
<br/>
<h:commandButton value="Refresh don't work" >
<f:ajax render="panelToRefreshInsideRepeat" />
</h:commandButton>
<h:commandButton value="Refresh work" >
<f:ajax render=":myForm:panelToRefreshOutsideRepeat" />
</h:commandButton>
</h:panelGroup>
<br/>
</ui:repeat>
</h:panelGroup>
The composite for onlyCheckbox and onlyInputText:
<composite:interface>
<composite:attribute name="value"
type="boolean"/>
</composite:interface>
<composite:implementation>
boolean: <h:selectBooleanCheckbox value="#{cc.attrs.value}" />
<!-- for onlyInputText h:inputText instead of h:selectBooleanCheckbox -->
boolean value: #{cc.attrs.value}
</composite:implementation>
and the backing bean:
#ManagedBean
#RequestScoped
public class Sandbox {
public List<Column> columns = Arrays.asList(new Column(true));
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
public class Column {
private boolean value;
public Column(boolean value) {
this.value = value;
}
public void setValue(boolean value) {
this.value = value;
}
public boolean getValue() {
return this.value;
}
}
}
I can reproduce your problem even on latest Mojarra 2.1.4. It works fine if the checkbox is not inside a composite. This is a bug in Mojarra's <ui:repeat>. It is totally broken in Mojarra. It works perfectly fine on MyFaces 2.1.3.
You have 2 options:
Replace Mojarra by MyFaces.
Use an UIData component instead of <ui:repeat>, e.g. <h:dataTable>, <t:dataList>, <p:dataList>, etc.

Resources