Hi,
JDeveloper version - 11.1.1.4.0
I have been trying to create an editable table (wherein the user can enter text into the input text boxes contained in the columns added at runtime). The values thus entered are to be captured in the backing bean for further processing.
Below are my attempts to achieve this in various ways but without success.
Attempt 1 : Created a Read-Only Dynamic table by dropping the view object instance from the Data Control. Here, the default being output text components, I used input text components and programatically make it updatable in the backing bean, which however, shows as an output text component.
1) UI - .jspx file
<af:table rows="#{bindings.TestViewObject1.rangeSize}"
fetchSize="#{bindings.TestViewObject1.rangeSize}"
emptyText="#{bindings.TestViewObject1.viewable ? 'No data to display.' : 'Access Denied.'}"
var="row" rowBandingInterval="0"
value="#{bindings.TestViewObject1.collectionModel}"
selectedRowKeys="#{bindings.TestViewObject1.collectionModel.selectedRow}"
selectionListener="#{bindings.TestViewObject1.collectionModel.makeCurrent}"
rowSelection="single"
id="t1"
partialTriggers="::cb1 ::cb2"
binding="#{TestDynamicTable.t1}">
<af:forEach items="#{TestDynamicTable.attributeDefns}"
var="def">
<af:column headerText="#{def.name}"
sortable="true" sortProperty="#{def.name}" id="c1">
<af:inputText value="#{row[def.name]}" id="it1"
label="Label 1"
autoSubmit="true" />
</af:column>
</af:forEach>
</af:table>
2) Backing bean -
public void listenMeForAction(ActionEvent ae) {
//adding attribute dynamically
ViewAttributeDefImpl def = (ViewAttributeDefImpl)vo.addDynamicAttribute("testDynamicAttr"+columnCount);
def.setUpdateableFlag(def.UPDATEABLE);
byte b = def.UPDATEABLE;
def.setEditable(true);
//def.setProperty(def.ATTRIBUTE_CTL_TYPE,);
//def.getUIHelper().HINT_NAME_UPDATEABLE
def.setProperty(def.ATTRIBUTE_DISPLAY_HINT_DISPLAY, def.HINT_NAME_UPDATEABLE);
columnCount ++ ;
AdfFacesContext.getCurrentInstance().addPartialTarget(this.t1);
}
Attempt 2 : Created a ADF table by dropping the view object instance from the Data Control. Here, the columns and its cells are added programatically in the backing bean. However
1) UI - .jspx file
<af:table value="#{bindings.Test5ViewObj1.collectionModel}" var="row"
rows="#{bindings.Test5ViewObj1.rangeSize}"
emptyText="#{bindings.Test5ViewObj1.viewable ? 'No data to display.' : 'Access Denied.'}"
fetchSize="#{bindings.Test5ViewObj1.rangeSize}"
rowBandingInterval="0"
id="richDynamicTable"
binding="#{TestDynamicTable.richDynamicTable}">
</af:table>
2) Backing bean - When the buildRichTable method is invoked from the constructor, the table shows the input text boxes as required, but the entered values is not getting retrieved (). Tried adding a valuchangelistener to the added cell, but this does not fire as well.
Below code however, creates a new instance of RichTable. Also, if an overloaded method is invoked on an ActionEvent, the columns added are not displayed.
//called from costructor
public void buildRichTable() {
dynamicVO.clearCache();
//create this table
richDynamicTable = new RichTable();
int noOfCols = 2;
for(int i=0; i<noOfCols; i++) {
//create new column for the table
richDynamicCol = new RichColumn();
richDynamicCol.setHeaderText("ColTest"+i);
// richDynamicCol.isVisible()
// richDynamicCol.setVisible(arg0);
richDynamicCol.setParent(richDynamicTable);
richDynamicTable.getChildren().add(richDynamicCol);
richDynamicTable.getChildCount();
richDynamicTable.getRowCount();
richDynamicCell = new RichInputText();
richDynamicCell.setLabel("aCell"+i);
// richDynamicCell.isVisible()
MethodExpression methodExpression = FacesContext.getCurrentInstance().getApplication().
getExpressionFactory().createMethodExpression(
FacesContext.getCurrentInstance().getELContext(),
"#{TestDynamicTable.inputBoxValueChangeListener}",
null,
new Class[] {ValueChangeEvent.class});
//this does not work too - on adding some text and tabbing out
richDynamicCell.addValueChangeListener(new MethodExpressionValueChangeListener(methodExpression));
richDynamicCell.setParent(richDynamicCol);
richDynamicCell.setValue("#{row.ColTest"+i+"}");
richDynamicCol.getChildCount();
richDynamicCol.getChildren().add(richDynamicCell);
dynamicVO.addDynamicAttribute("ColTest"+i);
}
//dynamicVO.insertRow(dynamicVO.createRow());
dynamicVO.getRowCount();
AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicTable());
AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCol());
AdfFacesContext.getCurrentInstance().addPartialTarget(this.getRichDynamicCell());
buildTable = false;
this.setDynamicVO(dynamicVO);
}
//captures the input data
public void captureRichTableData(ActionEvent ae) {
//gives null below
this.getDynamicVO().getCurrentRow().getAttribute("ColTest0");
this.getDynamicVO().getCurrentRow().getAttribute("ColTest1");
//again null
List<UIComponent> listCols = richDynamicTable.getChildren();
for(UIComponent aColComp : listCols) {
RichColumn aCol = (RichColumn)aColComp;
List<UIComponent> listCells = aCol.getChildren();
for(UIComponent aCellComp : listCells) {
RichInputText anInputText = (RichInputText)aCellComp;
anInputText.getValue();
}
}
}
Not sure what I must be missing. May be I need to add bindings to the text boxes added but cant figure how to go about it. I found some posts on dynamically adding columns pointing to displaying contained data. Any help would be highly appreciated.
Thanks for your time.
Dinu