1

I'm using a captcha in my JSF page (not recaptcha or randomly generated image value, etc). Initially it gets its value from CaptchaServlet. I want to add "refresh image" button without refreshing the whole page, but the code below doesn't work.

<h:panelGrid id="grid" columns="1" style="margin-bottom:10px">
    <h:graphicImage id="capimg" value="#{facesContext.externalContext.requestContextPath}/../Captcha.jpg"/>
</h:panelGrid>

The refresh button with PrimeFaces <p:commandButton>

<p:commandButton value="This" process="@this" update="grid" onclick="#{facesContext.externalContext.requestContextPath}/../Captcha.jpg"/>

refreshes the whole page.

Do you have any suggestions? Can I use a managed bean and forward to a servlet?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
asyard
  • 1,743
  • 5
  • 21
  • 43

1 Answers1

2

The <p:commandButton> uses Ajax to asynchronously update parts of the page. However, it requires that all necessary JavaScript libraries are included to do all the Ajax works. This should automatically happen when you have a <h:head> instead of a <head> in the master template. The JSF 2.0 resource management will then include the necessary <script> elements in there. If you have read the server logs, you should have noticed warnings that this has failed because the <h:head> is missing.

Here's how a minimum JSF 2.0 Facelet master template should look like, with PrimeFaces taglib declared:

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.som/jsf/core"
    xmlns:h="http://java.sun.som/jsf/html"
    xmlns:ui="http://java.sun.som/jsf/facelets"
    xmlns:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <title>Page title</title>
    </h:head>
    <h:body>
        <h1>Put your content here</h1>
    </h:body>
</html>

Please note the <h:head> and <h:body> instead of <head> and <body>. Rightclick the generated HTML page in the webbrowser an choose View Source. You should see the included <script> elements in there.


Update: get rid of the onclick attribute. It's not valid JavaScript code. Further you also need to ensure that the servlet response with the image is not cached by the webbrowser. You can do that by adding the following headers before you write any bit to the response:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • hi balusC, thats me again. my master page is as you said. p is included and i use h:head h:body tags. when i use another ajax tool like validation, it works. my problem is with refreshing image. am i wrong with calling a servlet in onclick action? – asyard May 11 '11 at 19:56
  • Remove the `onclick` attribute. It makes no sense. Is the captcha servlet mapped on `/Captcha.jpg`? Do you have disabled the browser cache by setting the appropriate response headers? http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers/2068407#2068407 – BalusC May 11 '11 at 19:58
  • yes, ` CaptchaServlet /Captcha.jpg `. when i remove action tag, nothing happens then. i will try disabling browser cahce now. – asyard May 11 '11 at 20:07
  • No, the `onclick` attribute, not the `action` attribute. If the browser cache is enabled then the captcha won't be reloaded from the server, but just redisplayed from the browser cache. – BalusC May 11 '11 at 20:14
  • hi BalusC, i added ` ` to template xhtml page but didn't work. the whole page is refreshed again.then i made it simple,i use; `` as img src, and a button; `` also JS: `document.getElementById('capimg').src='Captcha.jpg?'+myDate.getTime();` refreshes all page agn:( – asyard May 12 '11 at 17:27
  • Those headers only affects the XHTML page itself, not the captcha. You need to set those headers in the servlet which serves the captcha. And when you're using `` instead of `` you must add a `return false` to the onclick, e.g. `onclick="reloadimage();return false;"`. – BalusC May 12 '11 at 17:29
  • you are a great man. return false solved my problem and captcha is refreshed in same page. i didnt put headers in captchaservlet but it worked. i will put them anyway. – asyard May 12 '11 at 17:34
  • You're welcome. The JavaScript timestamp hack is also good to use instead of the headers, but it's just ugly. In the future, please be careful with how you ask the question. First it was `p:commandButton` and now it is `h:commandButton`. You've wasted a lot of time now because your question was careless formulated and did apparently not represent the real code. Red herrings are dangerous. – BalusC May 12 '11 at 17:35
  • you mean `src='Captcha.jpg?'+myDate.getTime()` ? if it put headres to my servlet, no need to add gettime()? – asyard May 12 '11 at 17:37
  • I'm very sorry about that. New to this site and JSF so I make many mistakes for beginning. I know I changed my question in comments many times, but h:button solved it now i will try p:button.. – asyard May 12 '11 at 17:42
  • Oh, nothing personal. You didn't waste *my* time, but you did waste your own time :) You can also just keep it as you now have. "It works" anyway ;) – BalusC May 12 '11 at 17:45
  • i waste my time a lot yes.. and a bit yours. p:button also worked now. i will use p :) Can you recommend me a book about JSF 2.0, or blog etc? (i follow your blog also.) I have to put Spring Framework and JSF together, i should work and read a lot.. – asyard May 12 '11 at 17:51