JSF DocumentViewer fails to display PDF in #ViewScope - jsf

I am relatively new to JSF thus need some help.
Problem: I have webpage that displays a PDF. Thus I created a xhtml as follow
<p:panel rendered="#{mainAppView.getMessages().isEmpty()}" styleClass="preview-panel">
<div class="document-viewer-wrapper">
<pe:documentViewer
url="#{previewView.previewUrl}"
download="Document.pdf"
id="pdfPreview"/>
</div>
</p:panel>
URL is provided by a BackingBean previewView. Thus when the jsf tries to display the document, it makes a call to WebServlet. The WebServlet downloads the document and displays it and if it fails to download, an error message is shown on the DocumentViewer.
Is there a way to I can notify the ViewScope Bean about the failure? I want to disable a tab on the screen if the document download fails. I read that servlet can't make call to viewScope Bean.

Do not use ViewScoped with PDFViewer use RequestScoped/SessionScoped/ApplicationScoped instead.
See: https://github.com/primefaces-extensions/primefaces-extensions.github.com/issues/796
BalusC explains why ViewScoped can't be used as well: https://stackoverflow.com/a/18994746/502366

I ended up writing a JS to achieve the desire result. JS monitored the pdfviewer and if it fails to load the document, I updated the message on the pdfviewer.

Related

Updating an UI value from javascript is not getting reflected in javabean

I am trying to update an UI text field in primefaces 6.2 using java script method. Though I am able to update the value from UI side, it is not reflecting in backing managed bean
Xhtml:
<h:inputHidden id="test" value="#{mybean.fieldname}" valueChangeListener="#
{mybean.method}">
<f:ajax/>
</h:inputHidden>
Javascript:
function update(){
document.getElementByID('form:test').value="change";
alert(document.getElementByID('form:test').value);
}
I expect my value changehandler to get called since I updated my value but nothing occurs.can some one pls tell where I am getting wrong
Edit :Actually I am trying to submit the value changed from UI side alone using Js to the actual bean value, basically dom alone is changed and kind of trying to submit the same using any ajax calls. but still it is not working. Refered this link:When to use valueChangeListener or f:ajax listener? Can some one pls give some insights on how this can be achieved?
You have to trigger explicitly a change event by JavaScript if you set a value by JavaScript.

ManagedBean processing when browser is closed

Is there any way to capture closing of browser or being redirected to other pages at managedBean to do some processes? I know that #PreDestroy is called when the container decides to kill the managedBean. However, that is not quite what I need. I want to do an immediate processing right after the view is changed.
Use javascript events and Ajax4JSF from Richfaces. This code calls Bean#callBean method if the page unloads. More information on a4j jsfunction you can find here.
<h:body onunload="unload()">
<a4j:jsFunction name="unload" action="#{bean.callBean}">
</a4j:jsFunction>
</h:body>

Render a jsf element on mouseover

I have a <h:panelGrid> and a h:commandLink(link is basically a image).Now I want that on mouseover event , Then link should be render(render='true') and on mouseout event, it gets removed render='false'.But I am unable to create the logic that How can I do this with these events as the approach I am using is To set the values of bean true and false on this event.
Here is my code
<h:form>
<h:panelGrid mouseover='** we cannot call a bean method here which changes the bean value **'>
This is the Div On which I want to apply mouseover event
</h:panelGrid>
<h:commandLink id="btn" render={renderBean.renderLink}>
<h:graphicImage url="image.jpg"/>
</h:commandLink>
</h:form>
The default value of renderLink attribute of renderBean is false. Now I want to know the way that How can I change its value to true on mouseover event? Is it possible? OR Anyother solution in JSF w.r.t this requirement
You have to remember in JSF that the page will first be processed server-side by the JSF engine in the web server. At that time all JSF tags will be converted into their HTML equivalent. The render attribute tells the server-side engine whether or not to output an HTML a (anchor) link in the place of the <h:commandLink> element.
The behavior you're looking for, namely responding to mouse events, is client-side functionality. It happens in the browser, not at the web server, so no JSF is involved. The solution is to handle the mouse events in JavaScript, not JSF. You will typically set (or remove) the CSS attribute display:none on the id called btn (unfortunately it's slightly more complex as JSF will mangle the element id a bit). There are lots of posts here on StackOverflow that deal with how to handle client-side events in JavaScript. Using jQuery for example is a really common approach.
I recommend to get started you take a look at the blog of one of our best JSF resources and long-time StackOverflow user BalusC: http://balusc.blogspot.com.
There's a lot to learn and you'll get a good start by going there first (and searching for his posts on SO).
Good luck.

How to retain form data in a multi form page

I am working on JSF. I have an xhtml page with multiple forms. when i am submitting one form, and if i had made some changes on other form i am loosing it, as on submit the page is getting refreshed. I cannot use a single form. is there any way to do.
any solution will be highly appreciated.
thanks !
If you're already using JSF 2.x (your statement that you're using XHTML (Facelets) confirms this less or more), just submit the form by ajax.
It's a matter of adding the following tag to the command links/buttons of the form:
<f:ajax execute="#form" render="#form" />
This way the current <h:form> will be submitted by ajax and the current <h:form> only will be rendered (updated/refreshed). You can if necessary specify other to-be-updated components in the render attribute by adding other client ID(s).
If you're still on the old JSF 1.x, you may want to look at Ajax4jsf sublibrary of RichFaces which supports basically the same.

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