I got trouble in JSF when I try to delete the row content from database through commandLink inside dataTable element. So I got the bean with viewScopped and managedScoped like this :
@ViewScoped
@ManagedBean
public class DivisiController implements Serializable{
private static final long serialVersionUID = 1L;
private String konten;
private String deskripsi;
private Long id;
private Divisi selectedDivisi;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Divisi getSelectedDivisi() {
if(selectedDivisi == null){
selectedDivisi = new Divisi();
}
return selectedDivisi;
}
public void setSelectedDivisi(Divisi selectedDivisi) {
this.selectedDivisi = selectedDivisi;
}
public String getKonten() {
return konten;
}
public void setKonten(String konten) {
this.konten = konten;
}
public String getDeskripsi() {
return deskripsi;
}
public void setDeskripsi(String deskripsi) {
this.deskripsi = deskripsi;
}
public void halo(){
System.out.println("Hi, I'm halo");
}
public void delete(){
DivisiDAO dao = new DivisiDAO();
dao.beginTransaction();
try{
Divisi persistedDivisi = dao.findReferenceOnly(selectedDivisi.getId());
dao.delete(persistedDivisi);
}
catch(Exception e){
dao.rollback();
addMessage("System Error", "Please try again later.");
e.printStackTrace();
}
dao.commitAndCloseTransaction();
}
public void addMessage(String summary, String detail) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail);
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
Then, I try to set selectedDivisi value when delete button clicked from the jsf page. And hope that my delete method would be delete the selected value.
I attempt to send item, as a division value, through f:setPropertyActionListener
But unfortunately, I always stuck with null value at my backing bean (DivisiController). I try to debug, set breakpoint at my selectedDivisi setter, and the result is, the selectedDivisi value null. It seems like, my selectedDivisi never set with #{item} from my button. Here is the snippet of, how I manage to draw html from jsf, and call my backing bean to perform an action.
<div class="col-md-12">
<!-- Custom Tabs -->
<h:form id="form">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active" >
<a id="lampiran" data-toggle="tab" href="#tab_2" aria-expanded="false">
<i class="fa fa-list">
</i> Daftar Divisi</a></li>
<li class="">
<a data-toggle="tab" href="#tab_1" aria-expanded="false">
<i class="fa fa-pencil"></i> Buat Divisi</a>
</li>
</ul>
<div class="tab-content">
<div id="tab_2" class="tab-pane active">
<h:panelGroup layout="block" id="berkas" class="row">
<div class="col-md-12">
<div class="box-footer text-right top-buffer">
<ui:include src="list.xhtml"/>
</div>
</div>
</h:panelGroup>
</div><!-- /.tab-pane -->
<div id="tab_1" class="tab-pane">
<h:panelGroup layout="block" id="tembusan" class="row">
<div class="col-md-12">
<ui:include src="create-form.xhtml"/>
</div>
</h:panelGroup>
<div class="box-footer text-right top-buffer">
<h:commandLink action="#{divisiController.create}" class="btn btn-primary">
Buat Baru <i class="fa fa-arrow-circle-right"></i>
</h:commandLink>
</div>
</div><!-- /.tab-pane -->
</div><!-- /.tab-content -->
</div><!-- nav-tabs-custom -->
</h:form>
<p:confirmDialog header="Confirmation"
message="#{divisiController.selectedDivisi.id}"
global="true"
showEffect="fade"
hideEffect="fade"
widgetVar="confirmDialogWidget">
<h:form>
<h:outputText value="#{divisiController.selectedDivisi.id}"/>
<p:commandButton value="Yes" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" action="#{divisiController.delete()}" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</h:form>
</p:confirmDialog>
</div>
That was the index.html, which included the list.xhtml (as you can see), and here is list.xhtml snippet :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:dv="http://xmlns.jcp.org/jsf/composite/mycomp">
<div class="row">
<div class="col-md-12 complex">
<dv:data-table value="#{divisiController.view()}"
id="surat"
scrollable="true"
scrollableHeight="500">
<p:column headerText="Konten" width="40%" styleClass="text-left" style="width: 44%">
<h:outputText value="#{item.konten}"/>
</p:column>
<p:column headerText="Deskripsi" width="40%" styleClass="text-left" style="width: 44%">
<h:outputText value="#{item.deskripsi}"/>
</p:column>
<p:column headerText="Aksi" styleClass="text-left">
<h:outputLink styleClass="btn btn-primary text-white" value="edit.xhtml">
<i class="fa fa-edit"></i>
<f:param name="id" value="#{item.id}" />
</h:outputLink>
<p:commandLink styleClass="btn btn-primary text-white" update=":form">
<h:panelGroup styleClass="fa fa-trash" />
<f:setPropertyActionListener value="#{item}" target="#{divisiController.selectedDivisi}" />
<p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
</p:commandLink>
</p:column>
</dv:data-table>
</div>
</div>
</ui:composition>
As you can see at the last snippet, I try to set the selectedDivisi through this snippet :
<f:setPropertyActionListener value="#{item}" target="#{divisiController.selectedDivisi}" />
But it always error. And if I try to direct pass the {item}
to my delete method from bean (if I set the delete method with input parameter), then it will goes same with the previous technique(from <f:setPropertyActionListener>
).
So, how this can happened, and what the thing that makes it mess?
Thanks in advance with your help.