I am working for a French organization and I am supposed to develop a rather complex form which is composed of six sequential screens. I have already finished five screens and in the final screen I have faced a specific problem for which there are different solutions. In order to make the markups in my .xhtml page more readable I prefer the solution in which we could add a new column to one specific row of a dataTable. The row will be chosen by a click on a commandButton which will at the same time chose the row and add a new column. Until now I can add a new row to the datatable, but the problem is that the new added column will be added to all rows of my dataTable. My question is simple. Is it at all possible to add a new column to one specific row chosen by the user, or not? If it is possible I will search to find the answer, if not I will follow one of other already considered solutions. Of course I highly appreciate any further help like mentioning any reference book or website.
2 Answers
we don't have any informations about your data model but i'll try to help you.
Possibility :
using a and loop over the #{data.optionalValues} using a nested loop with or perhaps even another
<p:column>
<p:dataTable value=""><!-- Empty string as value forces 1 row. -->
<p:columns value="#{data.optionalValues}" var="opt" headerText="#{opt.id}">
#{opt.value}
</p:columns>
</p:dataTable>
With this structure, you could have row with differents amont of columns. If it's work, you just have to update you array content after.
But if you need more informations, you can see the following link : Primefaces static and dynamic columns in datatable
it's not exaclty what you want to do but i hope it can help you.

- 1
- 1

- 91
- 8
-
Thank you. I have found my answer int the link you have sent: It isn't possible to define columns based on row data. Imagine that row 1 has 2 columns, row 2 has 6 columns, row 3 has 1 column, etc how would you ever produce a technically valid table in HTML? – Arash Daklan Jul 05 '16 at 12:34
I have solved my problem. Maybe the problem I am faced with does not raise very often, I post the solution and hope that it can help others facing with a problem like mine.
At first what I want is a from in which the columns are specific form fields. But this will be user
who decides that (s)he wants to add a new form field or not. As you see in the figure this is what I wanted:
In order to do that I have used primefaces <p:columns>
possibility. But since this tag with the help of specific backing bean adds a column to all lines of the dataTable, I have used <ui:repeat>
exhaustively so that the resting dataTable has just one line, as you see in the xhtml code:
Liste des Types de recherche
<ui:repeat var="thisQuadripole" value="#{saParametrageJbCoordinateurPrincipal.dataTableList.quadripoles}">
<h3>
<h:outputText value="#{thisQuadripole.quadripoleName}"></h:outputText>
</h3>
<ui:repeat var="thisMonoDatatable" value="#{thisQuadripole.monoDataTables}">
<h4>
<h:outputText value="#{thisMonoDatatable.directive}"></h:outputText>
</h4>
<p:dataTable value="" styleClass="normal" style="able-layout: fixed; width: 20px;" id="datatable">
<p:columns var="thisColumn" value="#{thisMonoDatatable.dataTableColumns}">
<f:facet name="header">
<h:outputText value="#{thisColumn.header}"></h:outputText>
</f:facet>
<h:selectOneMenu value="#{recherchesEcranBean.colonneTypeRechercheJb.sousColonne}">
<f:selectItems value="#{saParametrageJbCoordinateurPrincipal.toutTypeColonne}"></f:selectItems>
</h:selectOneMenu>
<p></p>
<p:outputLabel for="largeur2" value="(largeur)% "></p:outputLabel>
<p:inputText id="largeur2" value="#{recherchesEcranBean.colonneTypeRechercheJb.largeurAffichage}"
style="width: 40%;"></p:inputText>
</p:columns>
<p:column>
<f:facet name="header" style="width:10px;">
<h:outputText value=""></h:outputText>
</f:facet>
<h:commandButton id="thisButton"
action="#{saParametrageJbCoordinateurPrincipal.addNewColumnToMonoDataTable(thisMonoDatatable)}"
value=" + " style="background-color: #db70b8; cursor:pointer">
<f:ajax execute="@this" render="datatable"></f:ajax>
</h:commandButton>
</p:column>
</p:dataTable>
</ui:repeat>
</ui:repeat>
</h:form>
For doing this I have used four backing bean, One of them, as I will explain, is imposed on my by the project I am working on, but three others are what you need to use. The first one, which I have named DataTableList contains only a list of another bean called Quadripole (the naming is coming from my background in physics):
@ManagedBean
@SessionScoped
public class DataTableList
{
@ManagedProperty(value="#{quadripoles}")
private List<Quadripole> quadripoles;
public List<Quadripole> getQuadripoles() {
if (quadripoles == null) {
quadripoles = new ArrayList<Quadripole>();
}
return quadripoles;
}
}
Quardripole is in fact a bean which contains in fact four datatables, which I have called a MonoDataTable:*
@ManagedBean
@SessionScoped
public class Quadripole
{
@ManagedProperty(value="#{quadripoleName}")
private String quadripoleName;
@ManagedProperty(value="#{monoDataTables}")
private List<MonoDataTable> monoDataTables;
public Quadripole() {
//Emty contructor for managedBean
}
public Quadripole(String quadripoleName) {
this.quadripoleName = quadripoleName;
}
/**
* Accesseur de quadripoleName
*
* @return quadripoleName
*/
public String getQuadripoleName()
{
return quadripoleName;
}
/**
* Mutateur de quadripoleName
*
* @param quadripoleName quadripoleName
*/
public void setQuadripoleName(String quadripoleName)
{
this.quadripoleName = quadripoleName;
}
MonodataTable contains among other things a list of dataTableColumns:
@ManagedBean
@ViewScoped public class MonoDataTable implements Serializable {
/**
* serialVersionUID - long, DOCUMENTEZ_MOI
*/
private static final long serialVersionUID = 1L;
@ManagedProperty(value="#{directive}")
private String directive;
@ManagedProperty(value="#{}")
private int columnCounter = 1;
@ManagedProperty(value="#{dataTableColumns}")
private List<DataTableColumn> dataTableColumns = new ArrayList<DataTableColumn>();
public MonoDataTable() {
//Empty constructor for managedBean
}
public MonoDataTable(String directive)
{
// DOCUMENTEZ_MOI Raccord de constructeur auto-généré
this.directive = directive;
}
/**
* Accesseur de directive
*
* @return directive
*/
public String getDirective()
{
return directive;
}
/**
* Mutateur de directive
*
* @param directive directive
*/
public void setDirective(String directive)
{
this.directive = directive;
}
/**
* Accesseur de columnCounter
*
* @return columnCounter
*/
public int getColumnCounter()
{
return columnCounter;
}
/**
* Mutateur de columnCounter
*
* @param columnCounter columnCounter
*/
public void setColumnCounter(int columnCounter)
{
this.columnCounter = columnCounter;
}
public List<DataTableColumn> getDataTableColumns() {
return dataTableColumns;
}
}
/**
* Accesseur de monoDataTables
*
* @return monoDataTables
*/
public List<MonoDataTable> getMonoDataTables()
{
if (monoDataTables == null ) {
monoDataTables = new ArrayList<MonoDataTable>();
}
return monoDataTables;
}
}
in this way with the help of the specif functions:
public static void addMonoDataTablesToQuadripole(Quadripole quadripole) {
String directive = null;
directive = "Autre Structure ou National 0";
MonoDataTable newmonoDataTable = new MonoDataTable(directive);
addFixedColumnsToMonoDataTable(newmonoDataTable);
quadripole.getMonoDataTables().add(newmonoDataTable);
directive = "Direction 3";
MonoDataTable newmonoDataTable2 = new MonoDataTable(directive);
addFixedColumnsToMonoDataTable(newmonoDataTable2);
quadripole.getMonoDataTables().add(newmonoDataTable2);
directive = "Direction 7";
MonoDataTable newmonoDataTable3 = new MonoDataTable(directive);
addFixedColumnsToMonoDataTable(newmonoDataTable3);
quadripole.getMonoDataTables().add(newmonoDataTable3);
directive = "Direction 10";
MonoDataTable newmonoDataTable4 = new MonoDataTable(directive);
addFixedColumnsToMonoDataTable(newmonoDataTable4);
quadripole.getMonoDataTables().add(newmonoDataTable4);
}
/**
*
* DOCUMENTEZ_MOI
*
* @param monoDataTable
*/
public static void addFixedColumnsToMonoDataTable(MonoDataTable monoDataTable) {
int columnCounter = monoDataTable.getColumnCounter();
String header = columnHeader + columnCounter;
DataTableColumn newDataTableColumn = new DataTableColumn(header);
monoDataTable.getDataTableColumns().add(newDataTableColumn);
monoDataTable.setColumnCounter(++columnCounter);
columnCounter = monoDataTable.getColumnCounter();
header = columnHeader + columnCounter ;
DataTableColumn newDataTableColumn2 = new DataTableColumn(header);
monoDataTable.getDataTableColumns().add(newDataTableColumn2);
monoDataTable.setColumnCounter(++columnCounter);
}
/**
*
* DOCUMENTEZ_MOI
*
* @param monoDataTable
*/
public static void addNewColumnToMonoDataTable(MonoDataTable monoDataTable) {
int columnCounter = monoDataTable.getColumnCounter();
String header = columnHeader + columnCounter;
DataTableColumn newDataTableColumn = new DataTableColumn(header);
monoDataTable.getDataTableColumns().add(newDataTableColumn);
monoDataTable.setColumnCounter(++columnCounter);
}
each time the user clicks on the “+” the result is adding one column to the exactly line on which the click is received. Maybe this solution is not too elegant, but it worked for me. I hope, at least, that it is not too stupid.

- 23
- 8