I'm currently working with Primefaces datatable with simple CRUD operations. This Datatable shows tasks of a work list that's selected previously in another datatable that show worklists of projects. To get the selected worklist, i inject the WorkListManagedBean into the TaskManagedBean. When i create or delete a task from the selected work list, it was done successfully in the database but the datatable is not updation :(. Here is my Task Managed Bean:
@ManagedBean(name = "taskMBean")
@ViewScoped
public class TaksMBean implements Serializable {
@ManagedProperty("#{workListMBean}")
private WorkListMBean workListMBean;
@Inject
private TaskBusinessLocal taskBusinessLocal;
@Inject
private ResourceBusinessLocal resourceBusinessLocal;
private String description, code;
private Date startDate, endDate;
private Status status;
private List<Resource> resources, resourceslist;
private List<Task> filteredTasks, tasks;
private Task selectedTask;
private WorkList selectedWorkList;
@PostConstruct
public void init() {
selectedTask = new Task();
selectedWorkList = workListMBean.getSelectedWorkList();
}
public List<Task> getTasks() {
return tasks=workListMBean.getTasksList();
}
public void setTasks(List<Task> tasks) {
this.workListMBean.setTasks(tasks) ;
}
public List<Resource> getAllResources() {
return resourceBusinessLocal.allResources();
}
public Status[] getAllStatus() {
return Status.values();
}
public String addTask() {
taskBusinessLocal.addTask(description, code, startDate,
endDate,status,
selectedWorkList, resources);
return "index";
}
public String upDateTask() {
taskBusinessLocal.updateTask(selectedTask);
return "index";
}
public String deleteTask() {
taskBusinessLocal.deleteTask(selectedTask);
return "index";
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resources) {
this.resources = resources;
}
public List<Resource> getResourceslist() {
return resourceslist;
}
public void setResourceslist(List<Resource> resourceslist) {
this.resourceslist = resourceslist;
}
public List<Task> getFilteredTasks() {
return filteredTasks;
}
public void setFilteredTasks(List<Task> filteredTasks) {
this.filteredTasks = filteredTasks;
}
public Task getSelectedTask() {
return selectedTask;
}
public void setSelectedTask(Task selectedTask) {
this.selectedTask = selectedTask;
}
public WorkListMBean getWorkListMBean() {
return workListMBean;
}
public void setWorkListMBean(WorkListMBean workListMBean) {
this.workListMBean = workListMBean;
}
public WorkList getSelectedWorkList() {
return workListMBean.getSelectedWorkList();
}
}
and here is my JSF page:
<ui:composition template="/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="content">
<h:form id="form">
<p:contextMenu for="tasks">
<p:menuitem value="View" update="taskView"
icon="ui-icon-search" oncomplete="taskDialogView.show()"/>
<p:menuitem value="Update" update="taskUpdate"
icon="ui-icon-arrowrefresh-1-w"
oncomplete="taskDialogUpdate.show()"/>
<p:menuitem value="Delete" update="tasks"
icon="ui-icon-close" onclick="confirmation.show();"/>
</p:contextMenu>
<p:dataTable id="tasks" value="#{taskMBean.tasks}"
var="item" rowsPerPageTemplate="5,10,15,20,25,30"
paginator="true" rows="10"
filteredValue="#{taskMBean.filteredTasks}"
selection="#{taskMBean.selectedTask}"
rowKey="#{item.id}" selectionMode="single">
<p:ajax event="rowSelect" update=":form:tasks, :form:taskView ,
:form:taskUpdate , :form:confirmDelete"/>
<f:facet name="header" >
<p:outputLabel value="List of WorkList (#
{taskMBean.selectedWorkList.code}) tasks"/>
</f:facet>
<p:column sortBy="#{item.description}" filterBy="#{item.description}">
<f:facet name="header">
<p:outputLabel value="Description"/>
</f:facet>
<p:outputLabel value="#{item.description}">
</p:outputLabel>
</p:column>
<p:column sortBy="#{item.code}" filterBy="#{item.code}">
<f:facet name="header">
<p:outputLabel value="Code"/>
</f:facet>
<p:outputLabel value="#{item.code}">
</p:outputLabel>
</p:column>
<p:column sortBy="#{item.startDate}" filterBy="#{item.startDate}">
<f:facet name="header">
<p:outputLabel value="Start Date"/>
</f:facet>
<h:outputText value="#{item.startDate}">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
</p:column>
<p:column sortBy="#{item.endDate}" filterBy="#{item.endDate}">
<f:facet name="header">
<p:outputLabel value="End Date"/>
</f:facet>
<h:outputText value="#{item.endDate}">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
</p:column>
<f:facet name="footer">
<p:commandButton value="New Task" oncomplete="TaskDialogNew.show()"
icon="ui-icon-star" title="New Task"/>
<p:commandButton value="Delete Task" actionListener="#
{taskMBean.deleteTask()}" update="tasks" icon="ui-icon-trash"
style="margin-left: 5px"/>
<p:button value="Back" outcome="WorkLists.xhtml" icon="ui-icon-
arrowthick-1-w" style="margin-left: 900px"/>
</f:facet>
</p:dataTable>
<p:dialog header="Task Detail" widgetVar="taskDialogView" resizable="false"
showEffect="clip" hideEffect="fold" style="position: absolute ;"
id="dialogView">
<p:panelGrid id="taskView" columns="2" >
<f:facet name="header">
<p:graphicImage value="/images/task.png"/>
</f:facet>
<p:outputLabel value="Code:" />
<p:outputLabel value="#{taskMBean.selectedTask.code}" title="Code" />
<p:outputLabel value="Description:" />
<p:outputLabel value="#{taskMBean.selectedTask.description}" />
<p:outputLabel value="Resources"/>
<p:dataList value="#{taskMBean.selectedTask.resources}" var="item"
itemType="square">
#{item.name} (#{item.code})
</p:dataList>
<p:outputLabel value="Start Date"/>
<p:outputLabel value="#{taskMBean.selectedTask.startDate}" >
<f:convertDateTime pattern="MM/dd/yyyy" />
</p:outputLabel>
<p:outputLabel value="End Date"/>
<h:outputText value="#{taskMBean.selectedTask.endDate}" title="EndDate">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
<p:outputLabel value="Status"/>
<p:outputLabel value="#{taskMBean.selectedTask.status}"/>
</p:panelGrid>
</p:dialog>
<p:dialog header="task Update" widgetVar="taskDialogUpdate" resizable="false"
showEffect="clip" hideEffect="fold" style="position: absolute ;"
id="dialogUpdate">
<p:panelGrid id="taskUpdate" columns="2" >
<f:facet name="header">
<p:graphicImage value="/images/task.png"/>
</f:facet>
<p:outputLabel value="Code:" for="code" style="width: 242px"/>
<p:inputText id="code" value="#{taskMBean.selectedTask.code}"
style="width: 236px" required="true" requiredMessage="The Code field
is required."/>
<p:outputLabel value="Description:" for="description" />
<p:inputTextarea id="description"
value="# {taskMBean.selectedTask.description}" required="true"
requiredMessage="The Description
field is required."/>
<p:outputLabel value="Resources" for="resources"/>
<p:selectCheckboxMenu id="resources" value="#
{taskMBean.selectedTask.resources}" style="width: 241px"
label="Select Resources" required="true" requiredMessage="The List of
Resources field is required.">
<f:selectItems value="#{taskMBean.allResources}" var="item"
itemLabel="#{item.name}" itemValue="#{selectedTask.resources}" />
<f:converter
converterId="com.gis.plannerplus.converters.ObjectConverterResource
" />
</p:selectCheckboxMenu>
<p:outputLabel value="Status" for="status"/>
<p:selectOneMenu id="status" value="#{taskMBean.selectedTask.status}"
style="width: 241px" required="true" requiredMessage="The customer
field is required.">
<f:selectItems value="#{taskMBean.allStatus}" var="s" itemLabel="#
{s.status}"/>
</p:selectOneMenu>
<p:outputLabel for="startdate" value="Start " />
<p:calendar id="startdate" required="true" label="StartDate"
style="width: 240px" binding="#{startdate}"
effect="fold" value="#
{taskMBean.selectedTask.startDate}" pattern="dd/MM/yy" >
<p:ajax process="startdate finishDate" update="toDateMsg" />
</p:calendar>
<p:outputLabel for="finishDate" value="End " />
<p:calendar id="finishDate" label="FinishDate" style="width: 240px"
pattern="dd/MM/yy"
effect="fold" value="#{taskMBean.selectedTask.endDate}" >
<f:attribute name="startDate" value="#{startdate.value}" />
<f:validator validatorId="validator.dateRangeValidator" />
<p:ajax process="startdate finishDate" update="toDateMsg" />
<p:message for="finishDate" id="toDateMsg" >
</p:message>
</p:calendar>
</p:panelGrid>
<p:commandButton value="Clear" type="reset" icon="ui-icon-arrowrefresh-1-n"
styleClass="ui-priority-primary"/>
<p:commandButton value="Save" ajax="false" icon="ui-icon-circle-check"
styleClass="ui-priority-primary" action="#{taskMBean.upDateTask()}" />
</p:dialog>
<p:confirmDialog id="confirmDelete" message="Are you sure ?" appendTo="@(body)"
header="Delete Task?" severity="alert"
widgetVar="confirmation" style="width: auto">
<p:commandButton id="confirm" value="Yes" ajax="false" />
<p:commandButton id="decline" value="No" onclick="confirmation.hide();"
type="button" />
</p:confirmDialog>
</h:form>
<h:form id="newTaskForm">
<p:dialog header="New Task" widgetVar="TaskDialogNew" resizable="false"
showEffect="clip" hideEffect="fold" style="position: absolute ;"
id="dialogNewTask">
<p:panel id="panel">
<p:messages id="messages" />
<p:panelGrid id="newTask" columns="2" style="margin-bottom:10px" >
<f:facet name="header">
<p:graphicImage value="/images/task.png"/>
</f:facet>
<p:outputLabel value="Code:" for="code" />
<p:inputText id="code" value="#{taskMBean.code}" style="width:
236px" required="true" requiredMessage="The Code field is required."/>
<p:outputLabel value="Description:" for="description" />
<p:inputTextarea id="description" value="#{taskMBean.description}"
style="width: 236px" required="true" requiredMessage="The Description field is
required."/>
<p:outputLabel value="Resources" for="resources"/>
<p:selectCheckboxMenu id="resources" value="#{taskMBean.resources}"
style="width: 241px" label="Select Resources" >
<f:selectItems value="#{taskMBean.allResources}" var="item"
itemLabel="#{item.name}" itemValue="#{resources}" />
<f:converter
converterId="com.gis.plannerplus.converters.ObjectConverterResource" />
</p:selectCheckboxMenu>
<p:outputLabel value="Status" for="status"/>
<p:selectOneMenu id="status" value="#{taskMBean.status}"
style="width: 241px" required="true" requiredMessage="The customer field is
required.">
<f:selectItems value="#{taskMBean.allStatus}" var="s"
itemLabel="#{s.status}"/>
</p:selectOneMenu>
<p:outputLabel for="startDate" value="Start " />
<p:calendar id="startDate" required="true" label="StartDate"
style="width: 260px" binding="#{startDate}"
effect="fold" value="#{taskMBean.startDate}"
pattern="dd/MM/yy" >
<p:ajax process="startDate finishDate" update="toDateMsg" />
</p:calendar>
<p:outputLabel for="finishDate" value="End " />
<p:calendar id="finishDate" label="FinishDate" style="width:
240px"
effect="fold" required="true" value="#
{taskMBean.endDate}" >
<f:attribute name="startDate" value="#{startDate.value}" />
<f:validator validatorId="validator.dateRangeValidator" />
<p:ajax process="startDate finishDate" update="toDateMsg" />
<p:message for="finishDate" id="toDateMsg" >
</p:message>
</p:calendar>
</p:panelGrid>
<p:commandButton type="reset" value="Clear" icon="ui-icon-
arrowrefresh-1-n" styleClass="ui-priority-primary"/>
<p:commandButton value="Submit" ajax="false" process="@form"
update=":form:tasks, :growl" oncomplete=" handleSubmitRequest(xhr, status,
args, 'TaskDialogNew','newTaskForm');" actionListener="#{taskMBean.addTask
()}"/>
</p:panel>
</p:dialog>
</h:form>
<p:growl id="growl" showDetail="true" life="5000" />
<script>
function handleSubmitRequest(xhr, status, args, dialogName, formName) {
dialog = jQuery('#' + dialogName);
if (args.validationFailed) {
dialog.effect("shake", {times: 3}, 100);
} else {
clearForm(formName);
TaskDialogNew.hide();
taskDialogUpdate.hide();
}
}
function clearForm(formName) {
jQuery('#' + formName).each(function() {
this.reset();
});
}
</script>
</ui:define>
</ui:composition>
I used a JPQL query to retreive all tasks of the selected workList in the database. So, I defined a named query in the Task entity class:
@NamedQuery(name = "task.findByWorklist", query = "select t from Task t where
t.worklist=:worklist"),
Then, I added this method in the Task manager class:
@Override
public List<Task> findByWorklist(WorkList worklist) {
Query query =
em.createNamedQuery("task.findByWorklist").setParameter("worklist", worklist);
return (List<Task>) query.getResultList();
}
Finally, I placed getter and setter methods in the TaskManagedBean class:
public List<Task> getTasks() {
return tasks=workListMBean.getTasksList();
}
public void setTasks(List<Task> tasks) {
this.workListMBean.setTasks(tasks) ;
}
by this method:
public List<Task> getTasks() {
return tasks=taskManagerLocal.findByWorkList(selectedWorkList);
}
By this way, I could get tasks of the selected worklist from the database and the datatable is perfectly updating from the database after CRUD operation.