alsha
alsha

Reputation: 11

<h:dataTable> re-render single cell with ajax on <h:column id> is not possible

in the followinng example, I have a single-column table with input fields placed in its cells.

Background color of an input field is changed per ajax to green (when filled), or to red (when empty).

XHTML:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<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:c="http://java.sun.com/jsp/jstl/core"
  xmlns:f="http://java.sun.com/jsf/core" xml:lang="en" lang="en">
<h:head>
</h:head>
<h:body>
  <h:form>
    <h:dataTable value="#{testBean.getData()}" var="row" id="table">
      <h:column id="cell">
        <h:inputText value="#{row[0]}" id="input" style="background-color:#{empty row[0] ? 'red' : 'green'}">
          <f:ajax event="change" render="cell" />
        </h:inputText>
      </h:column>
    </h:dataTable>
  </h:form>
</h:body>
</html>

Java:

@ManagedBean(name="testBean")
@SessionScoped
public class TestBean {
    public TestBean() {
        super();
    }

    private static String [][] initdata = {{"test"},{null},{null},{null},{null}};   

    private List<String[]> data = Arrays.asList(initdata);   

    public List<String[]> getData() {  
        return data;  
    }
}

The problem is, that

<f:ajax event="change" render="cell" />

does not work. To make it work render="input" must be used. Or <h:panelGroup> must be added as direct child of <h:column> (then it can be re-rendered using its id) But my use case is more complicated, than this simplified example. I want to avoid additional markup and html-nesting if possible. And, of course, re-render the whole table is not an option.

So, why re-render of <h:column> is not possible ?

Thanks in advance,

Alexey

PS: Tested with MyFaces 2.1.12 & Mojarra 2.1.24

Upvotes: 1

Views: 3396

Answers (1)

rdcrng
rdcrng

Reputation: 3443

This is because a datatable is a repeating construct, which uses the column components to render all the rows in the datatable. More specifically, even though in the output (HTML) you end up with many rows, in the JSF component tree there is only one component that takes care or rendering all the rows and in the update attribute you can only specify a component id but not a client side id of a specific HTML tag. See this answer for a possibly better explanation.

Upvotes: 2

Related Questions