Hi all,
I am quite new to Trinidad and JSF and have the following problem: in a
page I list some entities from a
TrinidadEntityQuery. The page displays a commandlink to let the user
delete one of those entities. The
deletion shall be confirmed by the user by clicking 'Ok' in a popup
dialog. The dialog then passes back
the enity's id to the main page's backup bean which has a return
listener method. All works fine BUT the
main page is not re-rendered after the deletion of the entity, so the
entity still is displayed. In my application
there are other usages of popups to update entites in quite the same way
(main page listing enitity, popup
editing entitiy, main page shows changes after popup has closed), so I
really have no clue why in this
case nothing happens.
The table and commandling portion of the main page 'enginetypes.xhtml'
looks like this:
<!-- Table -->
<tr:form>
<tr:table var="engineType"
value="#{engineTypeHome.entityQuery.dataModel}"
rows="#{engineTypeHome.entityQuery.maxResults}" rowBandingInterval="1"
width="100%">
<f:facet name="header">
<tr:outputText value="Engine Types"/>
</f:facet>
<!-- the edit button, redirects to this page
with the currently selected engineTypeId -->
<tr:column inlineStyle="width:4em">
<f:facet name="header">
<tr:outputText value="Edit"
styleClass="columnUnsortableHeaderText"/>
</f:facet>
<s:link view="/enginetypes.xhtml">
<f:param name="engineTypeId"
value="#{engineType.id}"/>
<img src="images/edit.gif"
alt="#{engineType.id}" style="border:0"/>
</s:link>
</tr:column>
<!-- the delete button, calls the
engineTypeHome's remove method -->
<tr:column inlineStyle="width:4em">
<f:facet name="header">
<tr:outputText value="Delete"
styleClass="columnUnsortableHeaderText"/>
</f:facet>
<tr:commandLink
action="dialog:deleteEntity"
immediate="true"
partialSubmit="true"
useWindow="true"
windowWidth="650"
windowHeight="300"
launchListener="#{engineType.addConfirmDeletionParams}"
returnListener="#{engineTypeHome.handleConfirmDeletionDialogReturn}">
<img src="images/delete.gif"
alt="#{engineType.name}" style="border:0"/>
</tr:commandLink>
</tr:column>
<!-- the first (and only) column displays the
engineType's name -->
<tr:column sortable="true"
sortProperty="upper(engineType.name)">
<f:facet name="header">
<tr:outputText value="Name"
styleClass="columnSortableHeaderText"/>
</f:facet>
<tr:outputText value="#{engineType.name}"/>
</tr:column>
</tr:table>
</tr:form>
This is the code of the backing bean 'EngineTypeHome.java':
@Name("engineTypeHome")
@Scope(ScopeType.CONVERSATION)
public class EngineTypeHome extends HomeBase<EngineType> {
private TrinidadEntityQuery engineTypesQuery;
@In
private EntityManager entityManager;
public EngineTypeHome() {
super("engineTypeId");
}
@Factory("selectedEngineType")
public EngineType init() {
return getInstance();
}
@Override
public boolean checkRemovable() {
EngineType engineType = getInstance();
return checkRemovable(engineType);
}
public boolean checkRemovable(EngineType engineType) {
long usageCount = (Long) entityManager.createQuery("select
count(event) from Event event where event.engineType = :engineType")
.setParameter("engineType", engineType)
.getSingleResult();
if(usageCount > 0) {
FacesUtil.error("Cannot delete engine type '" +
engineType.getName() + "'. There are events for this engine type.");
return false;
}
return true;
}
@Override
public EntityQuery getEntityQuery() {
if (engineTypesQuery == null) {
engineTypesQuery = new TrinidadEntityQuery();
String ejbql = "select engineType from EngineType engineType";
engineTypesQuery.setEjbql(ejbql);
engineTypesQuery.setMaxResults(15);
engineTypesQuery.setOrder("engineType.name");
}
return engineTypesQuery;
}
@Transactional
public String handleConfirmDeletionDialogReturn(ReturnEvent
returnEvent){
Long engineTypeId = (Long) returnEvent.getReturnValue();
if (engineTypeId != null){
// load the entity from the database
EngineType engineType = entityManager.find(EngineType.class,
engineTypeId);
// make sure it has been loaded (no locking currently
activated!)
if (engineType == null){
FacesUtil.error("Cannot delete engine type. It may have
been deleted in the meantime.");
return null;
}
// actually remove it
if (checkRemovable(engineType)){
entityManager.joinTransaction();
entityManager.remove(engineType);
entityManager.flush();
}
getEntityQuery().refresh();
FacesContext.getCurrentInstance().renderResponse();
}
return "removed";
}
/**
* Calls the super save method and refreshes the entity query.
* @return The navigation outcome of HomeBase.save().
*/
@Override
public String save(){
String outcome = super.save();
if (engineTypesQuery != null){
engineTypesQuery.refresh();
}
return outcome;
}
}
The confirmation dialog page 'delete-entity_dlg.xhtml' looks like this:
<?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">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:tr="http://myfaces.apache.org/trinidad"
xmlns:trh="http://myfaces.apache.org/trinidad/html">
<head/>
<body>
<ui:composition template="popup_template.xhtml">
<ui:define name="main-content">
<script type="text/javascript" xml:space="preserve">
// <![CDATA[
_pprUnsupported = false;
// ]]>
</script>
<tr:form defaultCommand="okButton" styleClass="noprint">
<tr:panelFormLayout>
<tr:outputText inlineStyle="font-size:0.8em"
value="Please confirm the
deletion of the #{deleteEntityBackingBean.userPrompt}"/>
<tr:messages globalOnly="true"/>
<tr:panelButtonBar>
<tr:commandButton id="okButton"
styleClass="okButton"
action="#{deleteEntityBackingBean.ok}"
rendered="#{deleteEntityBackingBean.initOk}"/>
<tr:commandButton id="cancelButton"
styleClass="cancelButton"
action="#{deleteEntityBackingBean.cancel}"
immediate="true"/>
</tr:panelButtonBar>
</tr:panelFormLayout>
</tr:form>
</ui:define>
</ui:composition>
</body>
</html>
And here is it's backing bean 'DeleteEntityBackingBean.java':
/**
* Backing bean for the dialog page delete-entity_dlg.xhtml.
*/
@Name("deleteEntityBackingBean")
@Scope(ScopeType.CONVERSATION)
public class DeleteEntityBackingBean {
// the message displayed to the user
private String userPrompt;
// the entity to be deleted
private Long objectId;
// if false, an initialization error occurred (missing dialog parameter)
private boolean initOk = true;
@Logger("etd.edit")
private Log log;
@In(create = true)
private EntityManager entityManager;
public DeleteEntityBackingBean() {
}
@Create
@Begin
public void create() {
// get the dialog startup parameters
RequestContext requestContext = RequestContext.getCurrentInstance();
objectId = (Long) requestContext.getPageFlowScope().get("objectId");
userPrompt =
(String)requestContext.getPageFlowScope().get("userPrompt");
if (objectId == null) {
FacesUtil.error("Internal error: no object to be deleted!");
initOk = false;
}
}
@Transactional
@End
public String ok() {
// close the dialog returning the id
RequestContext.getCurrentInstance().returnFromDialog(objectId,
null);
}
@Transactional
@End
public String cancel() {
// close the dialog returning null
RequestContext.getCurrentInstance().returnFromDialog(null, null);
}
public String getUserPrompt() {
return userPrompt;
}
public boolean isInitOk() {
return initOk;
}
}
There is a navigation rule for the dialog in the faces-config.xml:
...
<navigation-case>
<from-outcome>dialog:deleteEntity</from-outcome>
<to-view-id>/delete-entity_dlg.xhtml</to-view-id>
</navigation-case>
...
Any help appreciated,
Alexander Pohl
--
------------------------
Alexander Pohl
------------------------
Think Applications GbR
Zionskirchstrasse 73
D-10119 Berlin
------------------------
Phone +49 30 4171 4624
Fax +49 30 4171 4625
Mobile +49 173 211 2864
------------------------
mailto:[EMAIL PROTECTED]
------------------------