I'm having a PrimeFaces (3.5) DataTable which contains some columns with <p:cellEditor> as usual in which selection of multiple rows is enabled by selectionMode="multiple".
When I click on a cell in a row containing <p:cellEditor>, the row is selected only time to time. The selection of the row is possible only when the padding area close to the cell borders is clicked. The selection is not made, when the actual text of that cell in the middle is clicked which is actually enclosed by <p:cellEditor>.
This doesn't happen, when <p:cellEditor> is dismissed.
Selection of a row in this manner is essential in my case , since a single row is deleted with a context menu by right-clicking on the row to be deleted exactly the same as this showcase example (that example works fine because it doesn't have <p:cellEditor>. I don't find a showcase example that uses both row selection and cell-editor together).
This issue was reported and its status is 'WontFix'. They said,
Cell and Row selection at same time is not supported.
But downgrading the framework from 3.5 indeed works (therefore, the above quote should simply be false and it appears to be misinterpreted) but this is not a solution. Did someone encounter this issue? Is there a way to change this behaviour?
Well, it has been 4 years and it hasn't been fixed yet. But - you can use some of JS magic in order to make it work.
First define JS function which selects datatable row by index:
<script>
function selectCurrentRow(index) {
var table = PF('myTableWidgetVar');
table.unselectAllRows();
table.selectRow(index, false);
}
</script>
Then define your datatable with rowIndexVar attribute set:
<p:dataTable id="myTable" widgetVar="myTableWidgetVar" var="parameter"
value="#{serviceMB.parameters}"
rowIndexVar="rowIndex"
rowKey="#{parameter.id}"
selectionMode="single"
editMode="cell">
And wrap cellEditor fields inside a div with onclick function defined:
<p:column>
<p:cellEditor>
<f:facet name="output">
<div onclick="selectCurrentRow(#{rowIndex});">
<p:outputLabel value="#{parameter.value}"/>
</div>
</f:facet>
<f:facet name="input">
<div onclick="selectCurrentRow(#{rowIndex});">
<p:inputText value="#{parameter.value}"/>
</div>
</f:facet>
</p:cellEditor>
</p:column>
This hack wont work properly if you are using row grouping datatable (row indexes will be shifted).
EDIT:
Use this function if you're using row grouping datatable:
function selectByRowKey(rowKey, table) {
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows.get(i);
if (row.getAttribute("data-rk") === rowKey) {
table.unselectAllRows();
table.selectRow(i, false);
break;
}
}
}
Where table = PF('myTableWidgetVar') and rowKey is a currently selected rowKey (for example '#{parameter.id}').
USE: style="display: block" in your cell:Editor, works for me.
<p:cellEditor>
<f:facet name="output"><h:outputText style="display: block;" value="#{whatever}"/></f:facet>
<f:facet name="input"><p:inputText id=......../></f:facet>
</p:cellEditor>
Related
I'm using Primefaces 5.3, and I'm filling a datatable with some records from the database if the length of records is lower than 10 I complete it with empty records so the datatable always diplays 10 rows.
My datatable looks like this :
<p:dataTable id="dataTable"
editable="true" editMode="cell"
value="#{beanPlanningl.getListPlanningSalle(entry, 1)}"
var="planning"
selectionMode="single"
selection="#{beanPlanning.selectedPlanning}"
rowKey="#{planning.id}"
sortBy="#{planning.heureDebut}"
>
So what I want is to disable selection on rows that has the empty records.
How can I do that ?
PS : planning.id equals 0 in empty records.
Edit :
I forgot to mention that I already used rendered as following :
<p:column >
<p:cellEditor rendered="#{planning.id != 0}">
<f:facet name="output"> <h:outputText value="#{planning.heureDebut}" /></f:facet>
<f:facet name="input">
<p:inputMask mask="99:99" value="#{planning.heureDebut}"
required="true" maxlength="4"
requiredMessage="Heure de début : vous devez indiquer une valeur."
validatorMessage="Heure de début non valide.">
<f:validateRegex pattern="([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]"/>
</p:inputMask>
</f:facet>
</p:cellEditor>
</p:column>
But this only prevents from editing cells, but they can be always selected.
Edit 2 :
I tried to use disabledSelection now I can't select rows but cells can always be selected, before I used disabledSelection :
as you can see I can select rows and on hovering they get colored.
and then when I used disabledSelection :
Now hovering doesnt work for empty rows and selection on rows as well, but the cells can always be selected, so no I only need to prevent that from hapenning.
I noticed that when the cell is selected two css classes are added : ui-state-highlight ui-cell-editing.
The solution I did was to prevent the default behaviour of columns which doesnt have a .ui-cell-editor in it's childs as following :
$(".ui-editable-column").click(function(event){
if(!$(this).find('.ui-cell-editor').length){
event.preventDefault();
return false;
}
});
I need to add and remove rows in DataTable and using buttons to add and remove the rows respectively by single selection.
My html/jsf code is :
<p:dataTable id="creditTable" rowIndexVar="sn"
value="#{cpeTrainingMB.cpeTrainingObj.cpeTrainigSchDetail}"
var="cpeDetail" scrollable="true" scrollHeight="100"
selectionMode="single"
rowKey="#{cpeDetail.id}">
<p:ajax event="rowSelect" update=":cpe:creditTable" listener="#{cpeTrainingMB.onRowSelect}"/>
<p:column headerText="Sn">
<h:outputText value="#{sn+1}"></h:outputText>
</p:column>
<p:column headerText="Date">
<h:outputText value="#{cpeDetail.fromDtBS}"></h:outputText>
</p:column>
<p:column headerText="Credit HR">
<h:outputText value="#{cpeDetail.creditHr}"></h:outputText>
</p:column>
</p:dataTable>
The problem is that when I add more than one data, and then select a row to delete , it selects all the rows at once which is not required.
It works well for only one row.
The backing methods/functions are listed below :
public void onRowSelect(SelectEvent event){
cpeScheSelected = null;
this.cpeScheSelected = (CPETrainingScheduleModel)event.getObject();
cpeTrainingScheObj = null;
cpeTrainingScheObj = this.cpeScheSelected;
}
All elements listed in the dataTable must have a not-null value in the rowKey property (in this case - id field). Nulls will lead to the behaviour described in the question. An alternative to specifying rowKey is implementing SelectableDataModel with custom method public Object getRowKey(RowClass rc).
I'm having a problem with the dataTable multiple selection with checkbox (like the second one: http://primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf).
When I try to execute a method in my backingBean, the selected items always comes with the right size, but, with the same object.
Example: I select in my dataTable three Messages: Message 1, Message 2 and Message 3. When I execute my method in the JSF page my selected items comes like this:
Messages[0] = Message 1
Messages[1] = Message 1
Messages[2] = Message 1
Here is my JSF Page:
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}">
<p:column selectionMode="multiple" style="width:2%"/>
<p:column headerText="Titulo:" style="width:49%">
#{msg.titulo}
</p:column>
<f:facet name="footer">
<p:commandButton id="multiViewButton" value="#{msgs.delete}" icon="ui-icon-trash" actionListener="#{mensagensBean.excluirMsgsGrupo}" update=":tabMain" ajax="true"/>
</f:facet>
</p:dataTable>
Your above code is working fine for me except that I'm using a rowKey.
Try using rowKey attribute in p:dataTable
<p:dataTable id="mensagensLidas" var="msg" value="#{mensagensBean.msgGrupoModel}"
paginator="true" rows="10" selection="#{mensagensBean.selectedMsgsGrupo}"
rowKey="#{msg.titulo}">
....
</p:dataTable>
Using rowKey is must and best practice when you have selection in Datables, it helps to map the selected <tr> to the POJOs that you're filling up with.
Usually its even better if your rowKey is unique propety, you can even put an integer variable in your #{msg} POJO as best practice.
I discovered the problem. My DataModel was with the getRowData returning always the same object. I was doing a wrong comparison. Thank you all!
I'm having a PrimeFaces (3.5) DataTable which contains some columns with <p:cellEditor> as usual in which selection of multiple rows is enabled by selectionMode="multiple".
When I click on a cell in a row containing <p:cellEditor>, the row is selected only time to time. The selection of the row is possible only when the padding area close to the cell borders is clicked. The selection is not made, when the actual text of that cell in the middle is clicked which is actually enclosed by <p:cellEditor>.
This doesn't happen, when <p:cellEditor> is dismissed.
Selection of a row in this manner is essential in my case , since a single row is deleted with a context menu by right-clicking on the row to be deleted exactly the same as this showcase example (that example works fine because it doesn't have <p:cellEditor>. I don't find a showcase example that uses both row selection and cell-editor together).
This issue was reported and its status is 'WontFix'. They said,
Cell and Row selection at same time is not supported.
But downgrading the framework from 3.5 indeed works (therefore, the above quote should simply be false and it appears to be misinterpreted) but this is not a solution. Did someone encounter this issue? Is there a way to change this behaviour?
Well, it has been 4 years and it hasn't been fixed yet. But - you can use some of JS magic in order to make it work.
First define JS function which selects datatable row by index:
<script>
function selectCurrentRow(index) {
var table = PF('myTableWidgetVar');
table.unselectAllRows();
table.selectRow(index, false);
}
</script>
Then define your datatable with rowIndexVar attribute set:
<p:dataTable id="myTable" widgetVar="myTableWidgetVar" var="parameter"
value="#{serviceMB.parameters}"
rowIndexVar="rowIndex"
rowKey="#{parameter.id}"
selectionMode="single"
editMode="cell">
And wrap cellEditor fields inside a div with onclick function defined:
<p:column>
<p:cellEditor>
<f:facet name="output">
<div onclick="selectCurrentRow(#{rowIndex});">
<p:outputLabel value="#{parameter.value}"/>
</div>
</f:facet>
<f:facet name="input">
<div onclick="selectCurrentRow(#{rowIndex});">
<p:inputText value="#{parameter.value}"/>
</div>
</f:facet>
</p:cellEditor>
</p:column>
This hack wont work properly if you are using row grouping datatable (row indexes will be shifted).
EDIT:
Use this function if you're using row grouping datatable:
function selectByRowKey(rowKey, table) {
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows.get(i);
if (row.getAttribute("data-rk") === rowKey) {
table.unselectAllRows();
table.selectRow(i, false);
break;
}
}
}
Where table = PF('myTableWidgetVar') and rowKey is a currently selected rowKey (for example '#{parameter.id}').
USE: style="display: block" in your cell:Editor, works for me.
<p:cellEditor>
<f:facet name="output"><h:outputText style="display: block;" value="#{whatever}"/></f:facet>
<f:facet name="input"><p:inputText id=......../></f:facet>
</p:cellEditor>
I have a primefaces datatable and inside the primefaces datatable, I have a column, which contains the . The issue is,I have set the default value for the as false. When I click/check the , its still retrieving the value as false. I tried it multiple times but not sure why its returning false. Please find the sample code below.
<p:dataTable id="review-table" var="item" value="#{demandBean.filterVOList}">
<p:column id="SelectallID" style="text-align: left; width:40px;" rendered="#{demandBean.screeRenderVo.selectAllRenderer}">
<f:facet name="header" >
<h:outputText id="selectId" value="#{demandBean.dmdScreenLabelVO.selectAll}" />
<div></div>
<h:selectBooleanCheckbox id="checkbox1" value="Select All" onclick="checkAll(this)"/>
</f:facet>
<h:selectBooleanCheckbox id="checkbox2" value="#{item.selected}"/>
</p:column>
Im getting the value as false, when I check the and click on the save button. I have written an Action listerner, below is the code corresponding to the actionListener
public void saveData(ActionEvent event)
{
System.out.println("Entering the Save :");
selected = isSelected();
System.out.println("value of Selected"+selected);
}
I have tried debugging the code as well, but not sure why the value for is getting displayed as false. Please Assist. Thanks in Advance
You seem to be binding the value of all checkboxes in the column to the one and same bean property. This way the value will ultimately end up to be the one of the last row in the column.
This is not how it's supposed to be used.
You basically need to bind the value of the checkbox to the property of the currently iterated row object (the one behind the var attribute of the datatable).
<p:dataTable value="#{bean.items}" var="item">
<p:column>
<p:selectBooleanCheckbox value="#{item.selected}" />
Alternatively, you could use the <p:column selectionMode="multiple" /> to use builtin multiple selection support of the PrimeFaces datatable (see also the showcase example).
<p:dataTable value="#{bean.items}" var="item" rowKey="#{item.id}" selection="#{bean.selectedItems}">
<p:column selectionMode="multiple" />