Reputation: 325
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.
Upvotes: 0
Views: 500
Reputation: 980
I don't have enough reputation to comment. I think it is setting nulls due to the scope.
If you see @BalusC answer on View scoped managed bean with setPropertyActionListener he advises us to use f:param and f:viewParam in @ViewScoped
Updated on comment from @user3057361: Do not call the action="#{divisiController.delete()} from the confirmDialog's yes Button if you are using the global mode of ConfirmDialog. IMHO, your p:commandLink in list.xhtml should be changed to a . Keep everything else. The yes and no button in the confirmDialog should not have action methods for global confirm dialog. Once you click yes, the action in the caller of your confirmDialog is called automatically
Upvotes: 1