How do I update a menu bar in a calling template - jsf

As an exercise I want to have a menu bar which is disabled until the user logs in. When he logs in I want to call something which will trigger an update. The menu bar is in the master.xhtml template file
<h:form >
<p:menubar id="masterMenuBar">
<p:menuitem disabled="#{backing.disableMenu}" value="List users" />
</p:menubar>
</h:form>
As part of the login I have code to refresh the form
public void refreshForm() {
RequestContext context = RequestContext.getCurrentInstance();
context.update("form1");
context.update("masterMenuBar");
}
I tried my luck with calling a context update to my defined label of masterMenuBar but the RequestContext apparently doesn't include my calling template form (which sounds reasonable enough).
Is there some other context I can call which will include a context update to my menu bar? Perhaps I am on the wrong path, and there is a better way to achieve the same thing?
I did notice that even resizing the browser wasn't reason enough to call again to my backing.disableMenu bean. Apparently I need something fairly strong to cause it to reach my bean a second time.

You need to pass the absolute client ID, not the relative client ID. If you rightclick and view source in browser, then you'll see that the masterMenuBar element has the (autogenerated) ID of its form prefixed.
You need to give the form where the menu is sitting in a fixed ID
<h:form id="menuForm">
<p:menubar id="masterMenuBar">
...
and pass the absolute client ID instead.
context.update("menuForm:masterMenuBar");
Update: sorry, it shouldn't start with : in contrary to the update attribute of <p:commandButton>.

Related

How to open a blank page for an external url with JSF, if target url must be initialy retained from server?

Primefaces 3.5.14, Omnifaces 1.6
Is there a component in JSF/Prime that looks like a button, but that allows to open a new blank page with an external link ? So unlike a normal link, on click the new page URL must be initialy retained from server and just then new page must be opened. Like a commanButton with an action attribute, where a string result of an action method determine the new url.
Of course I can use p:button as in Styling one JSF external link to make it look like a button but in that case I must update link generated by p:button, depending on actions made on the page every time. This is not always desirable.
You need target="_blank" on the parent form in order to submit into a new window and you need to invoke ExternalContext#redirect() (or OmniFaces' Faces#redirect()) in the action method in order to let the target window send a new GET request on the given URL. Importantly, when you use <p:commandButton> instead of <h:commandButton>, you also need to set ajax="false" because it doesn't respect target="_blank".
Thus, so:
<h:form target="_blank">
<p:commandButton value="Submit" action="#{bean.submit}" ajax="false" />
</h:form>
with
public void submit() throws IOException {
String redirectURL = determineItSomehow();
Faces.redirect(redirectURL);
}

JSF form onload reset() functionality not working

I am using the jsf along with primefaces. I want to call reset functionality when my form loads. But so far i am unable to achieve it.
<script type="text/javascript">
function reset(){
alert("dsdsd");
document.getElementById('A1938:create-ticket').reset();
}
window.onload=function(){reset();};
</script>
<h:form id="create-ticket">
<p:dialog id="dialog" header="Select different user" widgetVar="dlg" modal="true">
<ui:include src="searchpopup.xhtml" />
</p:dialog>
which definately not gona work as jsf translates the page in different way. Any idea.
The alert is getting called.So again i want the form to reset itself when it gets loaded similar to form.reset()
thanks,
Cyd
Calling reset when the page loads makes no utter sense. Perhaps you misunderstood the meaning of reset(). The form.reset() does not clear the input fields, instead it resets the input values to their initial values. I.e. when you get a form with prefilled inputs and then change them, then the reset() would reinitialize them with initial values as it was when the page was loaded. So, the form would only be cleared out on reset() when the initial values are already empty by itself.
So, to achieve your concrete functional requirement, you need to clear out the bean properties directly instead of fiddling with form.reset() which doesn't do what you think it does. Or, better, put the bean in the request or view scope and make sure that the form is opened by a fresh new GET request.

CommandButton open new tab with FlashScope parameters

How can I open new tab when user clicks p:commandButton? I also want to pass some parameters to new page using FlashScope. Here's the code:
<h:form>
<p:commandButton value="open new tab" action="#{myBean.newTab}"/>
</h:form>
public String newTab() {
Faces.setFlashAttribute("foo", bar);
return "otherView";
}
On the otherView page I use f:event type="preRenderView" to read Flash parameters.
Two notes:
I need to use FlashScope, not URL parameters.
If possible, I don't want to change newTab() and preRenderView() methods.
Thanks for help
Use target="_blank" on the form to tell the browser that the synchronous response of the form should be presented in a new (blank) tab/window. You only need to turn off ajax behaviour of the <p:commandButton> in order to make it a synchronous request.
<h:form target="_blank">
<p:commandButton value="open new tab" action="#{myBean.newTab}" ajax="false" />
</h:form>
No changes are necessary in the backing beans, it'll just work as you intented. I would only recommend to use POST-Redirect-GET pattern in the action method.
return "otherView?faces-redirect=true";
Otherwise the new tab would show the URL of the originating page and a F5 would re-invoke the POST. Also, this way the flash scope is also really used as it is been designed for (if you didn't redirect, just storing in request scope was been sufficient).
Update: as per the comments, the view scoped bean in the initial tab/window get killed this way. by returning a String navigation case outcome. That's right, if you'd like to keep the view scoped bean alive, replace the navigation case by a Faces#redirect() call (assuming that it's indeed OmniFaces which you're using there for Faces#setFlashAttribute()). You only need to set Flash#setRedirect() to true beforehand to instruct the flash scope that a redirect will occur.
public void newTab() throws IOException {
Faces.setFlashAttribute("foo", bar);
Faces.getFlash().setRedirect(true);
Faces.redirect("otherView.xhtml");
}

have to press command button twice

I'm working on building a web page and notice now that I have to press the command button twice. Any command button has the same problem, so I figured I would add and action listener on one of them to see if I could see something.
<h:form id="formP">
<p:commandButton id="temp" value="photos" actionListener="#{viewBacking.debugBreakpoint()}" action="userPhoto" />
</h:form>
The backing bean has
public void debugBreakpoint() {
int i = 0;
i++;
}
Unfortunately, this does help. It hits my breakpoint only after the second press. I suspect that some field somewhere isn't passing validation but I would like some method of detecting what exactly is going wrong - why do I need the second push? Is there some option I can turn on in Glassfish, or something else where I can look at a dump of debug information? I can ignore the dump until everything is stable and then see what exactly is happening when I press the button for the first time.
Is there any such tool which I can use?
That can happen when a parent component of the given <h:form> has been rendered/updated by another command button/link with <f:ajax>. The given form will then lose its view state which it would only get back after submitting the form for the first time. Any subsequent submits will then work the usual way. This is caused by a bug in JSF JS API as descibred in JSF issue 790 which is fixed in the upcoming JSF 2.2.
You need to fix the another command button/link with <f:ajax> to explicitly include the client ID of the given <h:form> in the render.
<f:ajax render=":somePanel :formP" />
Another way is to replace this <f:ajax> by a PrimeFaces <p:commandLink> or <p:commandButton> so that you don't need to explicitly include the client ID of all the forms. PrimeFaces's own JS API has namely already incorporated this fix.
add event="onclick" in your p:commandbutton
I guess that will sort it out.
or you can add this ajax="false" property in your commandButton
<p:commandButton ajax="false" action="#{userController.create}" value="#{bundle.CreateUserSaveLink}"></p:commandButton>
I ran into the same issue. The solution was simple, instead of having both an actionListener and an action, just convert the actionListener method to return a string to where you want to navigate to and use it as the method for the action (and don't have an actionListener).
In simple terms: only use an action (do not use an actionListener on a commandButton that is submitting a form).
Please check your binding with bean.
bean fields should be String or non primitive.

Problem With JSF 1.1 and PopUp

I am trying to popup a window when someone clicks a button on the data table.
<h:commandButton
action="#{cacheController.popupDetails}"
immediate="false"
onclick="popup()"
value="View Details"
styleClass="submit">
</h:commandButton>
The associated popup function is
function popup() {
window.open('RDDetails.jsf','popupWindow', 'dependent=yes, menubar=no, toolbar=no, height=500, width=400');
}
Now in the new 'RDDetails.jsf" file, I am trying to access the same managedBean cacheController. But the problem is, the pop-up window and JSF lifecycle is not in sync. As a result, the popup first displays blank and when I refresh, it pulls out the proper data.
Is there anyway I can click on a button which will do some processing in the managed bean and then opens a pop up which rerieves the processed data from the managed bean.
I am using JSF 1.1.
You're here basically firing two independent requests: one associated with the form submit and other which opens the RDDetails.jsf in a popup. You'll need to combine this in one request. You can achieve this in basically two ways:
Get rid of the onclick and just add target="_blank" to the <h:form> so that it get submitted into a new window/tab.
Block the default action by adding return false; to the onclick and do the business logic in the constructor of the bean associated with RDDetails.jsf. The only (major) caveat is here that the model won't be updated with the form fields. Thus, you'll need to pass the form fields as request parameters of the popup URL manually with help of JavaScript. You can then make use of managed property entries in the faces-config.xml to inject the GET request parameters into the model.
First way is obviously the easiest, but this doesn't give you a "fullworthy" popup/modal dialog. The second way is a bit harder (unless you've already a good grasp on both JavaScript and JSF). I would then consider to look for a component library which provides a ready-to-use popup component.
See my example:
<h:commandLink action="#{controller.myAction}" onmousedown="document.forms['idform'].target='_blank';">
I'm using jsf 1.1

Resources