Salam,
I'm trying to show a notification in a dialog dynamically from a poll component but it doesn't seem to work !!
<p:poll interval="15" listener="#{notificationBean.showNotification}" />
the action works well when i use it with a commandButton.
<p:commandButton value="View" icon="ui-icon-extlink" actionListener="#{notificationBean.showNotification}" />
This is my actionListener's code:
public void showNotification() {
System.out.println("showNotification");
Map<String,Object> options = new HashMap<String, Object>();
options.put("resizable", false);
RequestContext.getCurrentInstance()
.openDialog("notifications/notify", options, null);
}
I'm working with PF 6.0
Can't figure out what happens :(
Try to add following to your p:poll oncomplete="PF('DIALOG_WIDGETVAR').show()"/> or oncomplete="PF('DIALOG_WIDGETVAR').loadContents()"/>
Maybe you also have to add update within <p:poll> so content of dialog is updated.
Related
I have the following command button in the view with ID "save":
<p:panel style="border:none;text-align:left;margin:0;">
<p:commandButton value="Save Document" id="save" icon="fa fa-save"
disabled="#{dIGRCController.digrc.qconce == '020'}">
<f:param name="validate" value="true" />
</p:commandButton>
<p:commandButton value="Clear" icon="fa fa-undo"></p:commandButton>
</p:panel>
I am trying to dynamically assign a different actionListener. If the user wants to INSERT some new record, I want it to call the insert method. If the user wants to update an existing record, it should call the update method.
Right now I am trying to do this:
#PostConstruct
public void init() {
// setting the action listener of the Save Document button
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
// UIComponent button = viewRoot.findComponent("save");
CommandButton button = (CommandButton) viewRoot.findComponent("save");
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context
.getApplication()
.getExpressionFactory()
.createMethodExpression(context.getELContext(),
"#{dIGRCController.updateDocument}", null,
new Class[] { DIGRCController.class });
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
}
I am getting a null pointer exception on the line:
button.addActionListener(new MethodExpressionActionListener(
methodExpression));
What am I doing wrong? Is there another way to accomplish what I am trying to do? I am using JSF 2.2, PrimeFaces 5.3 and OmniFaces 1.11.
The findComponent() takes a client ID as argument not a component ID. The client ID is exactly the value of the generated HTML id attribute associated with the component in question. In case of a command button, usually the component ID of the parent <h:form> is prepended, separated by the naming container separator character which defaults to :.
Given this,
<h:form id="form">
<p:commandButton id="save" ... />
</h:form>
the client ID would be form:save.
CommandButton button = (CommandButton) viewRoot.findComponent("form:save");
See also this related question as to identifying and using client ID: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Unrelated to the concrete problem, manipulating the component tree in Java side is a poor practice. You'd better keep using XHTML+XML for this which is so much more self-documenting as to declaring/defining tree structures. You can use JSTL tags to dynamically build the view (note: this is different from dynamically rendering the view using rendered attribute!).
E.g.
<p:commandButton ... action="#{bean.save}">
<c:if test="#{bean.existing}">
<f:actionListener binding="#{bean.needsUpdate()}" />
</c:if>
</p:commandButton>
See also JSTL in JSF2 Facelets... makes sense?
Even more, you could just pass #{bean.existing} as method argument.
<p:commandButton ... action="#{bean.save(bean.existing)}" />
Both approaches are in turn admittedly kind of weird if #{bean.existing} refers the same bean as #{bean.save}. You could just check for that inside #{bean.save} itself.
public void save() {
if (existing) {
// UPDATE
} else {
// INSERT
}
}
Going further on that, this is IMO not the responsibility of frontend layer, but of the service layer. You pass the whole entity to the service layer which in turn checks based on PK if it's existing or not.
if (entity.getId() == null) {
// INSERT
} else {
// UPDATE
}
I've a Primefaces (version 5) dialog binding with an attribute of my bean:
<p:dialog
id="dialog"
widgetVar="myDialog"
modal="true"
resizable="false"
appendTo="#(body)"
binding="#{bean.dialog}"
>
...
<p:commandButton
id="cmdButton"
action="#{bean.test()}"
value="Save"
disabled="false" />
My back bean method is:
#ViewScoped
private Dialog dialog;
public Dialog getDialog() {
return dialog;
}
public void setDialog(Dialog dialog) {
this.dialog = dialog;
}
public void test( )
{
RequestContext rc = RequestContext.getCurrentInstance();
rc.execute("PF('myDialog').hide();");
rc.closeDialog(dialog);
}
When it runs, I get exception on closeDialog calling in back bean:
Warning: java.lang.NullPointerException: Argument Error: Parameter key is null
Despite this, my dialog closing correctly.
Why this exception?
Thanks in advance.
PrimeFaces has two type of dialog implements:
p.dialog (as yours): dialog visibility is managed by using show() and hide() methods of the client side api.
Dialog Framework: dialog displayed in an external page which dynamically generated on runtime.
To answer your question:
1. Exception raised by "rc.closeDialog(dialog);" which should used in dialog framework. e.g.
public void selectResultFromDialog(Object result) {
RequestContext.getCurrentInstance().closeDialog(result);
}
This will close the dialog and return the selected object to parent page.
Why my dialog closing correctly?
rc.execute("PF('myDialog').hide();") closed the dialog which actually hide it.
For your solution, I suggest you use the dialog framework.
Prerequisites:
Glasfish 3.1
JSF 2.1
Primefaces 5.2
User Story:
I want to implement a delete row function on my Primefaces DataTable, the Delete Function has to be displayed within the table.
Implementation:
datatable header
<p:dataTable value="#{a.list}" var="var">
delete
<p:column headerText="Delete">
<p:commandLink value="-" action="#{a.delete(var)}" />
</p:column>
delete method in bean
public void delete(Something sth) {
model.getList().remove(sth);
}
Outcome:
When hovering over the commandLink its showing me this Uniform Resource Locator localhost/applicationname/#
Eclipse is giving me the Facelet Validator Warning Marker Syntax Error on this ExpressionLanguage Code #{a.delete(var)}
Question:
What am i missing in order to delete the row?
Solution:
I have changed to commandlink from JSF (not primefaces) and got the Error, that my method shouldnt be void, but String after changing that and returning null it works...
public String delete(Something sth) {
model.getList().remove(sth); return null;
}
I use JSF + Primefaces 3.2.1.
There is an p:datatable on the page, in each row I have button "Edit". When I click that button, in the footer of the page renders a form for editing that row. Then I need to scroll down there to change values..
But I need the browser to scroll there automatically after clicking on "Edit" button like Anchors in basic HTML work.
I found this decision:
FacesContext.getCurrentInstance().getExternalContext().redirect("pProvidersPriceAppointment.xhtml#anchor1");
It works, but with that my update="#form" not working.. So the form in the bottom not renders. It renders after refreshing page.
How can I do it with p:commandButton or h:commandButton ?)
My button:
<p:commandButton id="providerEdit" actionListener="#{providersPriceAppointment.setEditProvider(provider.id)}" icon="iconEdit" update="#form"/>
Bean method:
public void setEditProvider(int id) throws IOException {
for (int i = 0; i < providersList.size(); i++) {
ProvidersExt p = providersList.get(i);
if (p.getId() == id) {
providerForEdit = p;
break;
}
}
enableEdit = true;
FacesContext.getCurrentInstance().getExternalContext().redirect("pProvidersPriceAppointment.xhtml#anchor1");
}
Form in the footer:
<a name="anchor1"/>
<p:fieldset id="editFieldset" legend="blablabla" rendered="#{providersPriceAppointment.enableEdit}"/>
...
</p:fieldset>
There isn't something like this implemented in JSF or Primefaces yet. But since you have the jQuery Framework running in your application (Primefaces), you could use the jQuery Animate features.
To get a Hint on how to realize something like this, you could check out this answer:
jQuery scroll to Element
For your application that would be somehow like that:
Add this to your <head> element:
function scrollToAnchor() {
jQuery('html, body').animate({
scrollTop: jQuery("#editFieldset").offset().top
}, 2000);
}
And this would be the Button Part:
<p:commandButton id="providerEdit"
actionListener="# {providersPriceAppointment.setEditProvider(provider.id)}"
icon="iconEdit" onComplete="scrollToAnchor();" update="#form"/>
Use PrimeFaces RequestContext with scrollTo to target a component id:
https://www.primefaces.org/showcase/ui/misc/requestContext.xhtml
public void save() {
RequestContext context = RequestContext.getCurrentInstance();
...
//scroll to panel
context.scrollTo("form:panel");
Simple decision that I found on PrimeFaces ShowCase:
<p:fieldset id="edit" legend="Here you can edit.." rendered="#{providersPriceAppointment.enableEdit}">
<p:focus context="panel"/>
</p:fieldset>
When this fieldset is rendered, browser simply jump to this place)
https://www.primefaces.org/showcase/ui/misc/focus.xhtml
Hope, somebody will find this helpful (",)
Versions:
NetBeans: 7.2.1
PrimeFaces: 3.5.3
GlassFish: 3.1.2
JDK 1.6
I've been trying to find related issues and have found topics that are close, but not quite what I'm looking for. I'm trying to do something similar to the p:schedule demo from PrimeFaces ShowCase where I want a dialog to appear showing the details of the event clicked.
I think the issue is coming from calling the listener method from the backing bean. When I go to type in the listener method in the p:ajax tag, NetBeans forces me to pass in a parameter like:
listener="#{cmodel.onEventSelect(e)}"
which I don't think is necessary as I don't have a value to pass in anyways.
I'm thinking either:
Something is up with NetBeans that doesn't recognize the method as a listener. (Since i keep seeing multiple examples of people calling the method without needing to pass a parameter.)
or
I'm not registering the method as a listener properly in the Model.
Also, I have directly copied and pasted the demo from the ShowCase into a project and it didn't work which is making me lean more towards an issue with NetBeans. (that is, the dialog appears but with no information on the event that was selected)
So to summarize; events are showing up as they should on the schedule itself, I just cant get the dialog to show the event details of the event that was selected.
Any help would be greatly appreciated!
View Layer:
<h:form>
<p:schedule id="nelsonsSchedule" value="#{cmodel.scheduleModel}" showHeader="true"
leftHeaderTemplate="none" rightHeaderTemplate="prev, next today"
draggable="false" timeZone="UTC" styleClass="schedule">
<p:ajax event="eventSelect" listener="#{cmodel.onEventSelect}"
update="eventDialog eventDetails" oncomplete="eventDialog.show()"/>
</p:schedule>
<p:dialog id="eventDialog" widgetVar="eventDialog" header="EventDetails">
<p:panel id="eventDetails">
<h:outputLabel value="#{cmodel.selectedEvent.title}" />
</p:panel>
</p:dialog>
</h:form>
Backing Bean:
#ManagedBean(name = "cmodel")
#SessionScoped
public class CalendarModel implements Serializable {
private ScheduleModel scheduleModel;
private List<ScheduleEvent> allScheduledGames;
private DefaultScheduleEvent gameEvent;
public ScheduleEvent selectedEvent;
List<Game> allGames;
#PersistenceContext
private EntityManager em;
public CalendarModel() {
}
#PostConstruct
public void init() {
allScheduledGames = new ArrayList<ScheduleEvent>();
allGames = new ArrayList<Game>();
allGames = em.createNamedQuery("Game.findAll").getResultList();
/*create list of games to put into the ScheduleModel*/
for (int i = 0; i < allGames.size(); i++) {
gameEvent = new DefaultScheduleEvent(allGames.get(i).getOpponent() +
"\n\n\n" + allGames.get(i).getTimeOfGame(),
allGames.get(i).getDateOfGame(),
allGames.get(i).getDateOfGame());
if(allGames.get(i).getHomeAway().equals("away")){
gameEvent.setStyleClass("away");
} else{
gameEvent.setStyleClass("home");
}
gameEvent.setData(allGames.get(i));
allScheduledGames.add(gameEvent);
}/*end for*/
scheduleModel = new DefaultScheduleModel(allScheduledGames);
}/*end init()*/
public void onEventSelect (SelectEvent e) {
selectedEvent = new DefaultScheduleEvent();
selectedEvent = (ScheduleEvent) e.getObject();
}
In case anyone runs into the same issue - It was NetBeans. I upgraded to 7.3 and don't have the problem anymore. Although another has come up where itellisense doesn't recognize a hashmap from the backing bean, but that's for another question.