Passing value from data table to bean JSF with Confirm Dialog - java

I'm having trouble with passing a single value from the data table to the backing bean. I always get the value of 0 when I try to print it in the method in the confirm dialog but when I try to print it in the method in the command button, it shows the value that I need. I think it resets the value or whatever.
<p:dataTable id="labLists" var="lab" value="#{coltsysHome.laboratory}" >
.....
<p:column headerText=" ">
<p:commandButton value="DELETE" onclick="confDlg.show()" icon="ui-icon-closethick" action="#{coltsysHome.action}">
<f:setPropertyActionListener value="#{lab.lab_id}" target="#{coltsysHome.lab_id_del}" />
</p:commandButton>
</p:column>
For the confirm dialog:
<p:confirmDialog widgetVar="confDlg" header="DELETE LABORATORY" message="Are you sure you want to delete this lab?">
<h:form id="delDlgForm">
<p:commandButton id="confirm" value="Yes Sure" oncomplete="confDlg.hide()" actionListener="#{coltsysHome.deleteLab(event)}"/>
<p:commandButton id="decline" value="Not Yet" onclick="confDlg.hide()" type="button" />
</h:form>
Bean (RequestScoped):
...getter and setter (lab_id_del)
public void deleteLab(ActionEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
String cpath = context.getExternalContext().getRequestContextPath();
try (Connection conn = dataSource.getConnection()) {
ColtsysDAO coltsysDAO = new ColtsysDAO(conn);
coltsysDAO.deleteLab(lab_id_del, coltsysDAO.getUserID(getUser_name()));
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
public void action() {
System.out.println("lab_id_del: " + lab_id_del);
}

The first and foremost change you need to do is: RequestScoped->ViewScoped as Luiggi Mendoza has suggested. you might need to add process attribute to the p:commandButton with the id of the p:dataTable. Also you can pass the lab object directly into action method without using f:setPropertyActionListener as: action="#{coltsysHome.action(lab)}" and take it as: public String action(Lab lab). Why not actionListener!

Related

how to specified id update in server side (bean) primefaces

my example:
<p:growl id="growlId"/>
<h:form id="form">
<h:inputText id="input" value="#{messageManagedBean.message}"
required="true"
requiredMessage="input is not null!"/>
<p:message for="input"/>
<p:commandButton value="Execute JSF Lifecycle - Invoke Action One"
validateClient="true"
action="#{messageManagedBean.doSomeAction}"
update="form growlId"></p:commandButton>
</h:form>
public String doSomeAction() {
if (!this.message.equals("")) {
FacesContext.getCurrentInstance().addMessage("growlId", new FacesMessage("Header", "Success!"));
}
return "";
}
in this case, i check if input null, will show requiredMessage="input is not null!" when click commandbutton, but growl show this message too.
i want to specified id of growl in server side (bean), i'm to try specified only update="form" :
<p:commandButton ...
action="#{messageManagedBean.doSomeAction}"
update="form"></p:commandButton>
but, if input not null, when submit,i dont receive message of growl,
thanks all!
I found a solution, i'm using RequestContext.getCurrentInstance().update("growlId");

create dynamic Confirm dialog in jsf

I need create dynamic confirmDialog. I have a dynamicallly created CommandButton. So when it press, confirmDialog will show. I do not know how to show it on CommandButton pressed.
Your button should be like this:
<p:commandLink oncomplete="confirmation.show()"
action="#{campagneComtroller.messageDeleteCam1(c)}"
update=":frmDlgDel:confirmDialog">
<p:graphicImage value="/image/delete.png" height="20" width="20"/>
</p:commandLink>
Your confirmDialog should be like this:
<h:form id="frmDlgDel">
<p:confirmDialog id="confirmDialog"
message="#{campagneComtroller.messageDeleteCam1}"
header="#{bundles.messages['message.SupprimerGeneral']}" severity="alert" widgetVar="confirmation">
<p:commandButton id="confirm" value="#{bundles.messages['message.OuiSure']}" oncomplete="confirmation.hide()" update=":formCam :frmDlgDel"
actionListener="#{campagneComtroller.deleteCam1()}" />
<p:commandButton id="decline" value="NonPasEncore" onclick="confirmation.hide()" type="button" />
</p:confirmDialog>
</h:form>
Your java code should be like this:
public void messageDeleteCam1(Cam cam) {
conditionVerified = true; // ... you can put here your treatments
if (conditionVerified) {
messageDeleteCam1 = "this cam is bla bla bla ";
} else {
messageDeleteCam1 = "are you sure to delete this cam ?";
}
}
NB: we have used here oncomplete + update, that's why we could see the difference in the confirmDialog after java treatments.

JSF: data not showing when editing twice

I have a dataTable with a list of items and a checkbox for selecting an item to edit. Ticking an item and clicking the edit button pops up a component which has fields and update and cancel buttons. Here's what happens.
Dialog appears
I empty all fields and click UPDATE, required messages appear since all fields are empty, data is not saved
Click CANCEL, dialog disappears
Click and edit the same item again
Some fields are not showing. I checked the datatable and database, data for the item still exists. Just not showing on the edit dialog the 2nd time around.
I noticed that the fields not showing are only those that have NULL attributes. NOT NULL fields are fine. I wonder if this has something to do with sessions. (Using Primefaces for all components)
Code for the edit dialog
<p:dialog header="#{bundle.Edit}" modal="true" widgetVar="editDialog" resizable="false">
<h:form id="edit-form">
<p:messages id="edit-error" autoUpdate="true" closable="true"/>
<h:outputLabel value="#{bundle.Name}" for="name" /><span class="required">*</span>
<p:inputText id="name" value="#{controller.selected.name}" required="true" requiredMessage="#{bundle.Name} #{bundle.FieldIsRequired}" maxlength="45"/>
<h:outputLabel value="#{bundle.Input}" for="input" /><span class="required">*</span>
<h:selectOneRadio id="input" value="#{controller.selected.input}" required="true" requiredMessage="#{bundle.Input} #{bundle.FieldIsRequired}">
<f:selectItem itemLabel="◯ " itemValue="0" />
<f:selectItem itemLabel="☓ " itemValue="1" />
</h:selectOneRadio>
<h:outputLabel value="#{bundle.IsOption}" for="isOption" /><span class="required">*</span>
<h:selectOneRadio id="isOption" value="#{controller.selected.isOption}" required="true" requiredMessage="#{bundle.IsOption} #{bundle.FieldIsRequired}">
<f:selectItem itemLabel="◯ " itemValue="0" />
<f:selectItem itemLabel="☓ " itemValue="1" />
</h:selectOneRadio>
<h:outputLabel value="#{bundle.Remark}" for="remark" />
<p:inputTextarea id="remark" value="#{controller.selected.remark}"/>
<p:commandButton action="#{controller.update()}"
value="#{bundle.Save}"
actionListener="#{controller.prepareList()}"
oncomplete="handleEditDialog(xhr, status, args)"
update=":form:datatable :edit-form:edit-error"
/>
<p:commandButton value="#{bundle.Cancel}"
onclick="editDialog.hide(); reset();"
type="button"/>
</h:form>
</p:dialog>
Code for the update function
public String update() {
RequestContext context = RequestContext.getCurrentInstance();
try {
current.setUpdateDate(new Date());
Map<String, Object> param = JsfUtil.getExternal().getSessionMap();
int createUser = (Integer) param.get("LOGIN_ID");
Account account = accountFacade.find(createUser);
current.setUpdateUser(account);
getFacade().edit(current);
search();
prepareList();
JsfUtil.addSuccessMessage(ResourceBundle.getBundle(JsfUtil.getSessionBundle()).getString("Updated"));
updateOk = true;
current = null;
context.addCallbackParam("updated", true);
return "";
} catch (Exception e) {
if (e.getCause().getCause().getMessage().contains("uk_")) {
JsfUtil.addErrorMessage("edit-form:edit-error",JsfUtil.getResourceString("Duplicate"));
context.addCallbackParam("updated", false);
} else {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle(JsfUtil.getSessionBundle()).getString("PersistenceErrorOccured"));
context.addCallbackParam("updated", false);
}
return null;
}
}
Based on what you are describing I think the following scenario is happening. When you see the form and you delete all fields and you hit save, the components that have no validators are actually overwriting some of the previous property values of your bean. That's why when you reload it for a second edit, you'll notice that all the components that have a validator attached (e.g required = true) are appearing but those with no validators are blank. In reality, you are actually doing a partial update. What you actually need to do is mark all fields as required to avoid that problem.
My teammate just found out a fix for this one. There is a function on the controller generated by NetBeans called prepareList().
public String prepareList() {
recreateModel();
return "";
}
private void recreateModel() {
items = null;
}
Basically we added this on catch block of the update() function. It is called after every unsuccessful update and recreates the model. The bug existed because the field retained its state of not having a value after an unsuccessful update.

Primefaces component does not update

I have a p:dataGrid that used to update itself in 3.0.1. Now I upgraded to PF 3.1 and the ajax update event of the "availableIcons" component does not fire anymore. I don't get an error that the component is not found in the view.
The XHMTL
<h:form id="Application">
......
<p:confirmDialog id="iconDialog" message="Select one icon"
showEffect="bounce" hideEffect="explode" header="Icon Selection"
severity="alert" widgetVar="iconSelect" modal="false">
<p:dataGrid id="availableIcons" var="icon"
value="#{appEditController.availableIcons}" columns="4">
<p:column>
<p:panel id="pnl" header="" style="text-align:center">
<h:panelGrid columns="1" style="width:100%" id="iconPanelGrid">
<p:graphicImage value="/resources/icons/#{icon.icon}"
id="iconImage" />
<p:selectBooleanCheckbox id="iconSelector"
value="#{icon.selected}"
disabled="#{appEditController.isIconSelected(icon)}">
<p:ajax update="availableIcons" event="change"
process="availableIcons"
listener="#{appEditController.iconSelectedChanged(icon)}" />
</p:selectBooleanCheckbox>
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
<p:commandButton value="Done" update="currentIcon"
action="#{appEditController.updateCurrentIcon}" ajax="false"
oncomplete="iconSelect.hide()" />
</p:confirmDialog>
.......
</h:form>
I don't see what's missing or what's incorrect.
This is the backing bean code
public void updateCurrentIcon() {
for (IconVO iconVO : availableIcons) {
if (iconVO.isSelected()) {
log.debug("CURRENT ICON IS NOW " + iconVO.getIcon());
currentIcon = iconVO;
break;
}
}
}
public void iconSelectedChanged(IconVO iconVO) {
if (iconVO == currentIcon) {
log.debug("NULLING ICON");
currentIcon = null;
} else {
log.debug("SETTING NEW ICON");
currentIcon = iconVO;
}
}
public boolean isIconSelected(IconVO iconVO) {
log.debug("IS ICON SELECTED " + iconVO.getIcon());
if (currentIcon == null
|| iconVO.getIcon().equals(currentIcon.getIcon())) {
return false;
}
return currentIcon != null;
}
I tried to do update="#form", then the update fires but it closes the modal panel completely.
Thanks,
Coen
Indeed, the way how PrimeFaces locates components by relative client ID has been changed in PrimeFaces 3.1 to adhere the UIComponent#findComponent() javadoc.
In your particular case, you need to specify the absolute client ID of the <p:dataGrid> instead. Easiest way to figure it is to check the ID of the <p:dataGrid> in the generated HTML source. With the code given so far, that would be Application:availableIcons. You need to prefix it with : to make it absolute and then reference it in update as follows:
<p:ajax update=":Application:availableIcons" ... />
Update as per the comments it turns out to not work at all. You could try wrapping the table in some invisible containing component like <h:panelGroup> and update it instead. Alternatively, you could consider moving the <h:form> into the dialog and use update="#form" instead. Having the <h:form> outside the dialog is kind of odd anyway. You surely won't submit all the other inputs which are outside the dialog inside the same form.

How to place markers on google map

I use the google map tool from primefaces.
I want my user to be able to place just one marker on a map.
The values of the coordinates should be stored in a managed bean variables.
How can I do that?
See what I did so far:
I created the map:
<f:view contentType="text/html">
<p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID"
style="width:600px;height:400px"
model="#{mapBean.emptyModel}"
onPointClick="handlePointClick(event);"
widgetVar="map" /> </f:view>
<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">
<h:form prependId="false">
<h:panelGrid columns="2">
<h:outputLabel for="title" value="Title:" />
<p:inputText id="title" value="#{mapBean.title}" />
<f:facet name="footer">
<p:commandButton value="Add"
actionListener="#{mapBean.addMarker}"
update="messages"
oncomplete="markerAddComplete()"/>
<p:commandButton value="Cancel" onclick="return cancel()"/>
</f:facet>
</h:panelGrid>
<h:inputHidden id="lat" value="#{newOfferSupportController.mapLocationX}" />
<h:inputHidden id="lng" value="#{newOfferSupportController.mapLocationY}" />
</h:form>
</p:dialog>
<script type="text/javascript">
var currentMarker = null;
function handlePointClick(event) {
if(currentMarker == null) {
document.getElementById('lat').value = event.latLng.lat();
document.getElementById('lng').value = event.latLng.lng();
currentMarker = new google.maps.Marker({
position:new google.maps.LatLng(event.latLng.lat(), event.latLng.lng())
});
map.addOverlay(currentMarker);
dlg.show();
}
}
function markerAddComplete() {
var title = document.getElementById('title');
currentMarker.setTitle(title.value);
title.value = "";
currentMarker = null;
dlg.hide();
}
function cancel() {
dlg.hide();
currentMarker.setMap(null);
currentMarker = null;
return false;
}
</script>
I also greated the variables that will hold the coordinates:
#ManagedBean
#RequestScoped
public class NewOfferSupportController {
private float mapLocationX;
private float mapLocationY;
//Get & set methods
It all works as in the primefaces page but I have 2 problems:
Problem 1: Once the marker is placed, it cannot be placed again.
Problem 2: In the same form where the map is there are some other elements such as text fields. I noticed that validation does not occur when I click on the submit button located in the form where the map is, Actually the form does not get submitted at all(This didn't occur before i added the map), why is the map disrupting the validation?
Problem 1: Once the marker is placed, it cannot be placed again.
This problem is caused by the following things:
You've bound latitude and longitude to a different bean (NewOfferSupportController) than the bean which holds the map model (MapBean). You should be using MapBean example in the PrimeFaces showcase as design starting point for NewOfferSupportController bean. It namely stores the markers set. The hidden inputs must point to that bean because in the addMarker() method those values will be added. From the showcase example you just have to rename the MapBean class name and rename #{mapBean} references in the view by #{newOfferSupportController}.
Your NewOfferSupportController bean is request scoped while it should be view scoped.
#ManagedBean
#ViewScoped
public class NewOfferSupportController implements Serializable {}
View scoped beans live as long as you're interacting with the same form by Ajax. But request scoped beans get recreated on every request (and thus also on every Ajax request!), hereby trashing the markers which are placed before in the map and inputs which are entered before adding markers.
Problem 2: In the same form where the map is there are some other elements such as text fields. Actually the form does not get submitted at all(This didn't occur before i added the map), why is the map disrupting the validation?
This works for me. This is likely caused because your NewOfferSupportController is been placed in the request scope instead of the view scope.
To recap, here is the code which I used in my test:
view:
<p:growl id="messages" showDetail="true" />
<h:form>
<p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID" style="width:600px;height:400px"
model="#{mapBean.mapModel}" onPointClick="handlePointClick(event);" widgetVar="map" />
<h:inputText value="#{mapBean.input}" required="true" />
<p:commandButton value="submit" action="#{mapBean.submit}" update="messages" />
</h:form>
<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">
<h:form prependId="false">
<h:panelGrid columns="2">
<h:outputLabel for="title" value="Title:" />
<p:inputText id="title" value="#{mapBean.title}" />
<f:facet name="footer">
<p:commandButton value="Add" actionListener="#{mapBean.addMarker}"
update="messages" oncomplete="markerAddComplete()"/>
<p:commandButton value="Cancel" onclick="return cancel()"/>
</f:facet>
</h:panelGrid>
<h:inputHidden id="lat" value="#{mapBean.lat}" />
<h:inputHidden id="lng" value="#{mapBean.lng}" />
</h:form>
</p:dialog>
(I didn't change the <script> code in the showcase example, just add it unchanged)
Bean:
#ManagedBean
#ViewScoped
public class MapBean implements Serializable {
private MapModel mapModel;
private String title;
private double lat;
private double lng;
private String input;
public MapBean() {
mapModel = new DefaultMapModel();
}
public void addMarker(ActionEvent actionEvent) {
mapModel.addOverlay(new Marker(new LatLng(lat, lng), title));
addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added", "Lat:" + lat + ", Lng:" + lng));
}
public void submit() {
addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Form submitted", "Amount markers: " + mapModel.getMarkers().size() + ", Input: " + input));
}
public void addMessage(FacesMessage message) {
FacesContext.getCurrentInstance().addMessage(null, message);
}
// Getters+setters.
}

Categories