1

I have a template composition Button.xhtml which contains a <p:commandLink>:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
    <p:commandLink value="View" action="#{printClass.printPdf}"/>
</ui:composition>

The link's purpose is to generate PDF.

I have a template client defaultPage.xhtml where the Button.xhtml is been included.

<ui:composition template="../../WebPages/MasterPage/Template.xhtml">
    <ui:define name="MainContent">
        <ui:include src="../../WebPages/Facelets/Button.xhtml"/>
    </ui:define>
</ui:composition>

The last one is Template.xhtml which inserts the MainContent template definition inside a <h:form>.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <h:form>
            <ui:insert name="MainContent" />
        </h:form>
    </h:body>
</html>

When I place <h:head></h:head> in Template.xhtml, then the <p:commandLink> in Button.xhtml stops working, but CSS of page works perfect. When I remove the <h:head></h:head> or replace it by <head></head> then the <p:commandLink> starts working, but CSS stops working.

How is this caused and how can I solve it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Freak
  • 6,786
  • 5
  • 36
  • 54
  • Are you using ICEfaces? Or did you carelessly oversimplify the code snippets without actually having testing them (i.e. you originally used e.g. PrimeFaces `` but you overgeneralized it as `` for some unclear reason)? Otherwise the answer of aamir makes no utter sense. There's **by default no** ajax bahvaiour on the `` at all. – BalusC Nov 21 '12 at 11:51
  • Yes I used thats why it started to work.I mistakenly forgot to mention that – Freak Nov 21 '12 at 12:47
  • 2
    -1 for being careless in asking the question which results in a question which does not show **any** problem at all. I remove the downvote once you fix that. The answer of aamir may have hinted the solution, but it is technically also wrong considering that you're actually using PrimeFaces. In future questions, test the code snippets yourself into a blank playground environment; it's easiest to do as if you're the answerer yourself and are trying to reproduce the problem based on the information provided so far in the question. – BalusC Nov 21 '12 at 12:51

2 Answers2

4

The <h:head> will auto-include all necessary JavaScript files for ajax behavior and CSS files for layout. When you remove it, then CSS will not be auto-included and ajax behavior will not be enabled. The <p:commandLink> would then act like as a plain vanilla link.

The <h:head> is absolutely necessary for proper functioning of JSF and PrimeFaces components and applying of the PrimeFaces look'n'feel. So you should not remove or replace it.

Let's concentrate on the problem of the failing <p:commandLink>. There are relatively a lot of possible causes, which are all mentioned in this answer: commandButton/commandLink/ajax action/listener method not invoked or input value not updated

You didn't show a fullworthy SSCCE, so it's impossible to copy'n'paste'n'run your code to see the problem ourselves (work on that as well in your future questions). So, I'll just mention the most probable cause for this problem based on the symptoms: you're nesting <h:form> components in each other. Placing the <h:form> in the master template is also a design smell. You should rather place it in the template client. Als note that the <p:dialog> should have its own form but that the <p:dialog> should by itself not be nested in another form.


Update: based on the comments, you're trying to return a whole PDF file as a response to an ajax request. This will indeed not work. The ajax engine expects a XML response with information about changes in the HTML DOM tree. A PDF file isn't valid information. Also, JavaScript has for obvious security reasons no facilities to programmatically trigger a Save As dialogue whereby possibly arbitrary content is provided.

You can't download files by ajax. You have to turn off ajax. In case of <p:commandLink> there are basically 2 solutions:

  1. Use ajax="false".

    <p:commandLink ... ajax="false" />
    
  2. Just use <h:commandLink> instead.

    <h:commandLink ... />
    
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thx for such useful answer but I want to know that Why my code started working when i placed `` in ``. I'm still unable to understand this – Freak Nov 22 '12 at 03:53
  • First this: how exactly have you definied "working"? Is this in enduser's perspective as in "something visually happened", or is this in developer's perspective as in "the method is invoked". In other words, if you were describing this in enduser's perspective (in spite of you being a developer), then "not working" would thus mean that "visually nothing happens", but that does not necessarily mean that the HTTP request is never sent and/or that the method is never invoked. So, can you please explicitly confirm, as being a self-respected developer, if the method is invoked or not? – BalusC Nov 22 '12 at 03:56
  • After all, reconsidering the method name `printPdf()`, I believe the purpose is to provide a concrete PDF file as download to the enduser, is that correct? You're writing a whole PDF file to the HTTP response? If so, then you've here the answer: **you can't download files by ajax**. You'd have to turn off ajax. See also my answer on this question for a more elaborate explanation: http://stackoverflow.com/q/12660179 – BalusC Nov 22 '12 at 03:59
  • Exactly I'm printing pdf in browser on this method invokation..Now I got the reason :) Thanks alot man :) – Freak Nov 22 '12 at 04:01
-1

In Button.xhtml where you placed

<h:commandLink value="View" action="#{printClass.printPdf}"/> 


You need to disable the ajax.So your new code should be like

<h:commandLink value="View" action="#{printClass.printPdf}">
<f:ajax disabled="true"></f:ajax>
</h:commandLink> 


mck
  • 978
  • 3
  • 14
  • 38
  • This answer is wrong on more than one way. Starting with the fact that the Q is about `p:commandLink` and that an `h:commandLink` by default does **not** have ajax enabled, so no need to disable it in the first place – Kukeltje Jan 02 '18 at 11:15