Primefaces dataTable columns sequence by displayPriority parameter - primefaces

I try to change Primefaces dataTable columns sequence using displayPriority parameter. But it does not work.If I try to change isVisible parameter or Width parameter of column everything works fine, but displayPriority does not work, why?
My xhtml:
<p:dataTable id="dataTableIncomingDoc"
var="item"
scrollable="true"
scrollHeight="100%"
scrollWidth="100%"
showGridlines="true"
selectionMode="single"
draggableColumns="true"
resizableColumns="true"
size="small"
styleClass="fixed-size"
selection="#{docsBean.docEntitySelected}"
rowKey="#{item.id}"
value="#{docsBean.loadDocsList()}">
<p:column id="registrationDate"
headerText="Reg. date"
width="100"
filterBy="#{item.registrationDate}"
sortBy="#{item.registrationDate}"
filterMatchMode="contains">
<h:outputText value="#{item.registrationDate}"/>
</p:column>
<p:column id="regNr"
headerText="Reg. Nr."
width="100"
filterMatchMode="contains"
sortBy="#{item.regNr}"
filterBy="#{item.regNr}">
<h:outputText value="#{item.regNr}"/>
</p:column>
<p:column id="documentNr"
headerText="Doc. Nr."
width="100"
filterMatchMode="contains"
sortBy="#{item.docNr}"
filterBy="#{item.docNr}">
<h:outputText value="#{item.docNr}"/>
</p:column>
</p:dataTable>
My bean:
public List<DocEntity> loadDocsList() {
var dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:dataTableIncomingDoc");
var a = dataTable.getColumns().get(1);
var b = dataTable.getColumns().get(2);
((Column) a).setDisplayPriority(2);
((Column) b).setDisplayPriority(1);
PrimeFaces.current().ajax().update(dataTable);
return docsList;
}

Related

In Cell editing does not update value on focus change

Cell value is not captured when mouse focus changes
I have a simple datatable that shows the name and income. The cell values are editable. When I update the cell value with a different value and hit "Update" (basically change mouse focus) the new value is not captured. The update method
prints the old value. However, when I press the "tab" key I can see the updated values printed. I am not sure what I am missing
Here is my backing bean:
#PostConstruct
public void init() {
NVPair nvp = new NVPair("xx", 10000);
dataList.add(nvp);
nvp = new NVPair("yy", 20000);
dataList.add(nvp);
}
public void update() {
for (NVPair item : dataList) {
System.out.println("Name: " + item.getName() + " Value: " +
item.getValue());
}
}
Here is the view:
<h:form>
<p:dataTable id="testTable" value="#{testBean.dataList}" var="item"
editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{testBean.onCellEdit}"
immediate="true" update="testTable" />
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.name}" />
</f:facet>
<f:facet name="input">
<h:outputText value="#{item.name}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Income">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.value}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.value}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton action="#{testBean.update}" value="Update" />
</h:form>
When the focus changes, I am expecting that the edited value is captured just like when the tab key is pressed.

How to disable sorting on Primefaces lazy datatable?

I have a datatable with lazy data model and pagination. I want to disable default sorting when I click on "search" button and enable it again when I click on "display" button. So didn't put "sortBy" in my xhtml file and instead, I set it dynamically in my backing bean.
Everything works properly until I click on the header to flip sort order between descending and ascending. It means the "search" button disables the sorting and "display" button enables it correctly if I don't click on the header. But when I click on the header and then click the "search" button, in load funciton of LazyDataModel, value of the argument sortField is "date" and the datatable will be sorted by date though the "date" column is not colored apparently!!
This is my datatable:
<h:form id="contents-form">
...
<p:dataTable id="tbl" widgetVar="tbl" var="msg" value="#{homeController.messagesModel}" lazy="true"
currentPageReportTemplate="سطر {startRecord}-{endRecord} از {totalRecords}"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
paginator="true" rows="10" rowsPerPageTemplate="5,10,15"
emptyMessage="هیچ پیامکی وجود ندارد."
selection="#{homeController.selectedMessages}" rowSelectMode="checkbox"
rowKey="#{msg.id}" filteredValue="#{homeController.filteredMessage}"
editable="true" editMode="cell"
style="width:100%" dir="rtl">
<f:facet name="header">
<p:commandButton value="خروجی" action="#{homeController.prepareExport}" icon="fa fa-save"
update="export-dlg-box" oncomplete="PF('exportDlgBox').show()"/>
<p:commandButton value="واژگان" action="#{homeController.showListTermsChart}"
icon="fa fa-bar-chart" update="contents-form chart-form msgs"
oncomplete="PF('chartDlgBox').show()"/>
</f:facet>
<p:ajax event="cellEdit" listener="#{homeController.onCellEdit}" oncomplete="updateDescFilter()"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="فرستنده" style="width:100px" filterBy="#{msg.sender.number}"
sortBy="#{msg.sender.number}">
<p:commandLink action="#{homeController.setPhoneNumToShow(msg.sender)}" update="phone-form"
oncomplete="PF('phoneDlgBox').show()" styleClass="simple-command-link">
<h:outputText value="#{msg.sender.number}"/>
</p:commandLink>
</p:column>
<p:column headerText="گیرنده" style="width:100px" filterBy="#{msg.receiver.number}"
sortBy="#{msg.receiver.number}">
<p:commandLink action="#{homeController.setPhoneNumToShow(msg.receiver)}" update="phone-form"
oncomplete="PF('phoneDlgBox').show()" styleClass="simple-command-link">
<h:outputText value="#{msg.receiver.number}"/>
</p:commandLink>
</p:column>
<p:column headerText="متن" sortBy="#{msg.text}">
<h:outputText value="#{msg.getTrimmedText()}"/>
</p:column>
<p:column headerText="زمان" style="width:100px" filterBy="#{msg.date}" sortBy="#{msg.date}">
<f:facet name="filter">
<p:calendar pattern="yyyy-MM-dd">
<p:ajax event="dateSelect" oncomplete="PF('tbl').filter()" update="tbl"/>
</p:calendar>
</f:facet>
<h:outputText value="#{msg.getJalaliDate()}"/>
</p:column>
<p:column headerText="منبع" style="width:70px" filterBy="#{msg.source}" sortBy="#{msg.source}">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('tbl').filter()" style="width:30px; direction:ltr">
<f:selectItem itemLabel="همه" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{homeController.sources}" var="source"
itemValue="#{source}" itemLabel="#{source}"/>
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{msg.source}"/>
</p:column>
<p:column headerText="توضیح" style="width:70px" filterBy="#{msg.description}"
sortBy="#{msg.description}">
<f:facet name="filter">
<p:selectOneMenu id="desc-filter-select" onchange="PF('tbl').filter()"
style="width:30px; direction:ltr">
<f:selectItem itemLabel="همه" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{homeController.descriptions}" var="desc"
itemValue="#{desc}" itemLabel="#{desc}"/>
</p:selectOneMenu>
</f:facet>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{msg.description}"/></f:facet>
<f:facet name="input"> <p:inputText id="desc-input" value="#{msg.description}"
style="width:85%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="جزئیات" style="width:40px">
<p:commandLink action="#{homeController.setMessageToShow(msg)}" ajax="true"
update="img-dlg-box" oncomplete="PF('imgDlgBox').show()">
<i class="fa fa-blue fa-desktop"/>
</p:commandLink>
</p:column>
<p:column headerText="مشاهده گفتگو" style="width:40px">
<p:commandLink action="#{homeController.showConversation(msg.sender, msg.receiver)}"
ajax="true" update="conv-dlg-box" oncomplete="PF('convDlgBox').show()">
<i class="fa fa-blue fa-wechat"/>
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
My "search" button:
<p:commandButton value="جست‌وجو" action="#{homeController.search}" update=":contents-form:tbl msgs"
icon="fa fa-search"/>
My "display" button:
<p:commandButton value="نمایش" icon="fa fa-desktop" action="#{homeController.loadArchive}"
update="contents-form msgs"/>
search method in the backing bean:
public void search() {
if (this.selectedArchive == null) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "لطفا یک مجموعه را انتخاب کنید"));
return;
}
if ((this.textQuery != null && !this.textQuery.equals(""))
|| (this.selectedNodes != null && this.selectedNodes.length > 0)) {
logger.info(String.format("searching '%s' in archive %d ...", this.textQuery, this.selectedArchive.getId()));
List<String> selectedWords = this.getSelectedWords(this.selectedNodes);
searchText(this.textQuery, selectedWords);
} else {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "برای جست‌وجو هیچ متنی وارد نشده و هیچ واژه‌ای انتخاب نشده است."));
return;
}
extractChoices();
// Disable default sorting:
DataTable table = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":contents-form:tbl");
table.setValueExpression("sortBy", null);
table.setValueExpression("sortOrder", null);
}
And loadArchive method in the backing bean:
public void loadArchive() {
if (this.selectedArchive == null) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "خطا!", "لطفا یک مجموعه را انتخاب کنید"));
return;
}
this.messagesModel = new LazyMessageModel(this.selectedArchive, true, this.messageService);
extractChoices();
// Enable default sorting:
FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory ef = context.getApplication().getExpressionFactory();
DataTable table = (DataTable) context.getViewRoot().findComponent(":contents-form:tbl");
ValueExpression sortVe = ef.createValueExpression(context.getELContext(), "#{msg.date}", Message.class);
table.setValueExpression("sortBy", sortVe);
table.setSortOrder("descending");
logger.info(String.format("archive %d loaded", (this.selectedArchive.getId())));
}
Spec:
Primefaces 6.2
JSF 2.2.14
Java 1.8
I finally found a clean solution! Just I must reset the table in addition to setting sortBy null after clicking "search" button:
public void search() {
// Do something ...
DataTable table = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":contents-form:tbl");
table.reset();
table.setValueExpression("sortBy", null);
}

Primefaces Drag&Drop drags and drops only one element from dataTable

So, I've used example from showcase of PrimeFaces https://www.primefaces.org/showcase/ui/dnd/dataTable.xhtml. That's my code:
<div class="page_content">
<div class="header">Очередь рассылок</div>
<script type="text/javascript">
function handleDrop(event, ui) {
var droppedEmail = ui.draggable;
droppedEmail.fadeOut('fast');
}
</script>
<h:form>
<p:fieldset id="availableEmailsField" legend="Доступные рассылки">
<p:dataTable id="availableEmails" var="email" value="#{emailingQueueUI.customEmails}">
<p:column style="width: 20px;">
<h:outputText id="dragIcon" styleClass="ui-icon ui-icon-arrow-4"/>
<p:draggable for="dragIcon" revert="true" helper="clone"/>
</p:column>
<p:column headerText="ID">
<h:outputText value="#{email.id}"/>
</p:column>
<p:column headerText="Название">
<h:outputText value="#{email.name}"/>
</p:column>
<p:column headerText="Заголовок">
<h:outputText value="#{email.header}"/>
</p:column>
<p:column headerText="Количество порции">
<h:outputText value="#{email.chunkSize}"/>
</p:column>
</p:dataTable>
</p:fieldset>
<p:outputPanel id="selectedEmailsField">
<p:outputPanel id="dropArea">
<h:outputText value="Переместите сюда c доступных рассылок" rendered="#{empty emailingQueueUI.customEmailQueue}" style="font-size:16px;" />
<p:dataTable id="selectedEmails" var="email" value="#{emailingQueueUI.customEmailQueue}" rendered="#{not empty emailingQueueUI.customEmailQueue}"
rowIndexVar="index">
<!--<p:ajax event="rowReorder" listener="#{emailingQueueUI.onQueueReorder}" update=":form" />-->
<p:column headerText="Номер в очереди">
<h:outputText value="#{index}"/>
</p:column>
<p:column headerText="Рассылка">
<h:outputText value="#{email.id}"/>
</p:column>
<p:column headerText="Название">
<h:outputText value="#{email.name}"/>
</p:column>
<p:column headerText="Заголовок">
<h:outputText value="#{email.header}"/>
</p:column>
<p:column headerText="Количество порции">
<h:outputText value="#{email.chunkSize}"/>
</p:column>
</p:dataTable>
</p:outputPanel>
</p:outputPanel>
<p:droppable for="selectedEmailsField" tolerance="touch" activeStyleClass="ui-state-highlight" datasource="availableEmails" onDrop="handleDrop">
<p:ajax listener="#{emailingQueueUI.onEmailDrop}" update="dropArea availableEmails" />
</p:droppable>
</h:form>
</div>
There is a problem with d&d, I can drag and drop only one element from "availableEmailsField". When I try to drop another element it removes previous element and adds the dropped one.
I think the problem is in your bean.
Make sure that you initialize customEmailQueue inside #PostConstruct method and use the proper bean scope. In this case #ViewScoped.
It seems that an update function must be setted correctly in order to work properly. I faced the same issue and discovered that the ajax inside dropable has to update all drag-drop area elements, it seems that this action solves the issue.
The solution that worked is to put inside your form an:
<h:panelGroup id="elementsPanel">
....
...
...
...
....
</h:panelGroup>
, surrounding all drag-drop elements (if you dont want a panelgroup the idea is to update all the components)
and on the dropable update this panel:
<p:droppable id="dropHandler" for="selectedTable" tolerance="touch" activeStyleClass="ui-state-highlight" datasource="myDataSource" onDrop="handleDrop">
<p:ajax listener="#{dimensionsClass.onDimensionDrop2}" update="elementsPanel" />
</p:droppable>
I hope that helps!

rowToggle should call first rowSelect event jsf primefaces

<p:dataTable var="item" id="datatable-list" value="#{generalJournalEntryMB.generalJournalEntries}" rows="10"
paginator="true" reflow="true" paginatorPosition="top" rowExpandMode="single"
rendered="#{generalJournalEntryMB.generalJournalEntries.size() > 0}" rowIndexVar="rowIndex"
paginatorTemplate="{CurrentPageReport} {PreviousPageLink} {NextPageLink} " rowKey="#{item.id}"
selectionMode="single" selection="#{generalJournalEntryMB.generalJournalEntry}" widgetVar="datatable-list">
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{item.id}" />
</p:column>
<p:column headerText="Description">
<h:outputText value="#{item.description}" />
</p:column>
<p:column headerText="Amount">
<h:outputText value="#{item.amount}" />
</p:column>
<p:column headerText="Reference">
<h:outputText value="#{item.reference}" />
</p:column>
<p:column headerText="State">
<h:outputText value="#{item.postingState.value}" />
</p:column>
<p:rowExpansion id="expand" rendered="true">
<p:panelGrid columns="2" columnClasses="label,value" style="width:300px">
<h:outputText value="Id:" />
<h:outputText value="1" />
<h:outputText value="Year" />
<h:outputText value="1983" />
<h:outputText value="Color:" />
<h:outputText value="White" />
<h:outputText value="Price" />
<h:outputText value="#{generalJournalEntryMB.price}" />
</p:panelGrid>
</p:rowExpansion>
<p:ajax event="rowSelect" listener="#{generalJournalEntryMB.rowSelectListener}" update="main:top-menu-bar" />
<p:ajax event="rowToggle" listener="#{generalJournalEntryMB.rowToggleListener}" update="main:top-menu-bar" />
</p:dataTable>
When I expand the row without selecting the row, it show nothing. Currently what am I doing is to first select row and expand it to get desire result.
How we can trigger rowSelect even / ajax call automatically when rowToggle event fire?
You can override primefaces toggleExpansion function so it executes selectRow before
PrimeFaces.widget.DataTable.prototype.toggleExpansion = (function() {
var cached_function = PrimeFaces.widget.DataTable.prototype.toggleExpansion;
return function() {
var row = arguments[0].closest('tr');
if(this.cfg.selectionMode === 'single') {
this.unselectAllRows();
}
if(this.cfg.selectionMode){
this.selectRow(row, false);
}
var result = cached_function.apply(this, arguments);
return result;
};
})();

Datatable emptyMessage is not shown in PF5.3

I am using PF 5.3, on (weblogic 11g/jsf2.0/java 1.6).
I thought the issue of not shown emptyMessage in Datatable is fixed in 5.3, but inspite of using the latest version, i still dont see the message. Below is my sample code.
<p:dataTable id="attaDt" var="fileRow" value="#{pendpaybean.selectedPayDetailsFiles}"
rowIndexVar="rowIndex"
emptyMessage="No Files Uploaded"
>
<p:column headerText="Uploaded Date"
width="15px;" style="text-align:center"
>
<h:outputText value="#{fileRow.columns[0]}" />
</p:column>
<p:column headerText="Uploaded By"
width="30px;" style="text-align:center"
>
<h:outputText value="#{fileRow.columns[3]}" />
</p:column>
</p:datatable>
Any help ?
Your code works well. NOTE I put attribute value to null for showing emptyMessage.
Your adapted code:
<h:body>
<h:form>
<p:dataTable id="attaDt" value="#{null}" var="fileRow" rowIndexVar="rowIndex" emptyMessage="No Files Uploaded">
<p:column headerText="Uploaded Date" width="15px;" style="text-align:center">
<h:outputText value="#{fileRow.columns[0]}" />
</p:column>
<p:column headerText="Uploaded By" width="30px;" style="text-align:center">
<h:outputText value="#{fileRow.columns[3]}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>