h:commandbutton not working in <o:form> - jsf

<html xmlns:h="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui">
<o:form includeViewParams="true">
<h:commandButton value="Home" action="/index?faces-redirect=true"/>
<p:dataTable>
</p:dataTable>
</o:form>
The h:commandButton is not working under the o:form. When I click on it, it remains on the same page. But when I change to h:form, it works. Nevertheless I need to use o:form for the includeViewParams. Is there any way I could resolve this?

This construct works for me, as in, it actually navigates to /index. Only the view params disappear from the URL because you're forcing a redirect. But there is more, the <h:commandButton> is here essentially the wrong tool for the purpose. You want pure page-to-page navigation. You should then not be using a command link/button at all, but a plain link/button. You need <h:button>.
<h:button value="Home" outcome="/index" includeViewParams="true" />
Note: this doesn't require any form.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)

Related

ViewAction action not executing when the page has been submitted via commandbutton in a data table [duplicate]

I have a problem with the JSF 2.2 Feature <f:viewAction action="#{...}/>.
I placed this tag in my XHTML-Page, it's called viewActionStart.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<f:view>
<f:metadata>
<f:viewAction action="#{redirect.getView()}" onPostback="true"
immediate="true" />
</f:metadata>
</f:view>
<h:outputText value="If you see that text, the viewAction was not performed." />
</h:body>
</html>
If I visit this XHTML-Page directly, everything works fine: The method redirect.getView() is called and a redirect to another page is performed.
Now I have my landing page, that is shown before that viewActionStart-Page. There is a button, that basically should navigate to my viewActionStart-Page to show the <f:viewAction> effect. The following code is from this landing page index.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<f:view>
<h:form>
<h:commandButton action="viewActionStart.xhtml"
value="To f:viewAction Page" />
</h:form>
</f:view>
</h:body>
</html>
If I hit that command button, the content of the viewActionStart.xhtml is shown. Why does JSF ignore the <f:viewAction>? I do not understand why the viewAction does not work on every page load. I tried around with those onPostback and "immediate" attributes, but nothing changes.
Another weird result is, that after I hit the command button and see the content of viewActionStart.xhtml the URL still remains on localhost:8080/UIIncludeTest/index.xhtml. But shouldn't look this URL like localhost:8080/UIIncludeTest/viewActionStart.xhtml after the command button does navigation?
Am I doing something wrong? Or do I simply misunderstood <f:viewAction>? The weird thing, is, that it works if I browse directly to viewActionStart.xhtml.
I'm trying to get this working on:
JSF-2.2.6
Tomcat-7.0.47
PrimeFaces 5.0
I have read the numerous posts related to <f:viewAction> but nothing helped.
The <f:viewAction onPostback="true"> applies only on postbacks on the very same view. I.e. it runs only when a <h:form> in the very same view has been submitted. The <f:viewAction> is never intented to be executed upon POST navigation triggered by a submit of a <h:form> of another view. Moreover, the term "postback" in the attribute name also confirms this. This term means in web development world "a POST request on the URL of the page itself".
You need to open it by a GET request instead of a POST request. Replace the <h:commandButton> by <h:button>:
<h:button outcome="viewActionStart.xhtml" value="To f:viewAction Page" />
(note: the <h:form> is not necessary anymore)
Or, if you really intend to perform a POST request first for some unclear reason (it would have been a bit more understandable if you were invoking a bean action method, but you're here merely navigating, so the whole POST request doesn't make any sense), then let it send a redirect:
<h:commandButton action="viewActionStart.xhtml?faces-redirect-true" value="To f:viewAction Page" />
Either way, the URL should now be properly reflected in address bar. This was at its own indeed a strong hint that you was donig things the wrong way ;)
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
Difference between h:button and h:commandButton

CommandButton execution while rendering

Question: How can I prevent the execution of a while the website is rendering?
Thats where my Button sits:
<p:dialog widgetVar="newComment" height="200" width="500">
<h:form>
<h:panelGrid>
<h:outputText value="#{commentDialog.username}" />
<h:inputTextarea id="in_text" value="#{commentDialog.text}" />
<p:message for="in_text" />
</h:panelGrid>
<p:commandButton validateClient="true" value="Abschicken" ajax="true"
actionListener="#{popupRequestView.update}" action="PF('newComment').hide();update_popup();" />
</h:form>
</p:dialog>
The action attribute is intented to execute a backing bean action method on click, not to print some JavaScript code (which of course get executed immediately
You perhaps meant to use onclick or oncomplete instead. Like as in basic HTML, those on* attributes are intented to execute some JavaScript code during the specified HTML event ("click", "complete", etc).
oncomplete="PF('newComment').hide();update_popup();"
Another cause not visible in the information provided so far is that you forgot to register the p: XML namespace. Any <p:xxx> tags would then be printed as if it's plain text. Verify if a parent element somewhere in the markup has this:
xmlns:p="http://primefaces.org/ui"
Regardless, taking a JSF pause and learning some basic HTML/JavaScript wouldn't be a bad idea. After all, JSF is "just" a HTML/CSS/JS code generator.
you must use primefaces ajaxStatus to prevent click on button while rendering and execute ajax
ajaxStatus in primefaces showcase

f:viewAction ignored, when commandButton navigates to page

I have a problem with the JSF 2.2 Feature <f:viewAction action="#{...}/>.
I placed this tag in my XHTML-Page, it's called viewActionStart.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<f:view>
<f:metadata>
<f:viewAction action="#{redirect.getView()}" onPostback="true"
immediate="true" />
</f:metadata>
</f:view>
<h:outputText value="If you see that text, the viewAction was not performed." />
</h:body>
</html>
If I visit this XHTML-Page directly, everything works fine: The method redirect.getView() is called and a redirect to another page is performed.
Now I have my landing page, that is shown before that viewActionStart-Page. There is a button, that basically should navigate to my viewActionStart-Page to show the <f:viewAction> effect. The following code is from this landing page index.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<f:view>
<h:form>
<h:commandButton action="viewActionStart.xhtml"
value="To f:viewAction Page" />
</h:form>
</f:view>
</h:body>
</html>
If I hit that command button, the content of the viewActionStart.xhtml is shown. Why does JSF ignore the <f:viewAction>? I do not understand why the viewAction does not work on every page load. I tried around with those onPostback and "immediate" attributes, but nothing changes.
Another weird result is, that after I hit the command button and see the content of viewActionStart.xhtml the URL still remains on localhost:8080/UIIncludeTest/index.xhtml. But shouldn't look this URL like localhost:8080/UIIncludeTest/viewActionStart.xhtml after the command button does navigation?
Am I doing something wrong? Or do I simply misunderstood <f:viewAction>? The weird thing, is, that it works if I browse directly to viewActionStart.xhtml.
I'm trying to get this working on:
JSF-2.2.6
Tomcat-7.0.47
PrimeFaces 5.0
I have read the numerous posts related to <f:viewAction> but nothing helped.
The <f:viewAction onPostback="true"> applies only on postbacks on the very same view. I.e. it runs only when a <h:form> in the very same view has been submitted. The <f:viewAction> is never intented to be executed upon POST navigation triggered by a submit of a <h:form> of another view. Moreover, the term "postback" in the attribute name also confirms this. This term means in web development world "a POST request on the URL of the page itself".
You need to open it by a GET request instead of a POST request. Replace the <h:commandButton> by <h:button>:
<h:button outcome="viewActionStart.xhtml" value="To f:viewAction Page" />
(note: the <h:form> is not necessary anymore)
Or, if you really intend to perform a POST request first for some unclear reason (it would have been a bit more understandable if you were invoking a bean action method, but you're here merely navigating, so the whole POST request doesn't make any sense), then let it send a redirect:
<h:commandButton action="viewActionStart.xhtml?faces-redirect-true" value="To f:viewAction Page" />
Either way, the URL should now be properly reflected in address bar. This was at its own indeed a strong hint that you was donig things the wrong way ;)
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
Difference between h:button and h:commandButton

JSF redirect via commandButton

I cannot redirect to another page if the code is like this:
<h:commandButton type="button" value="Enter" action="index?faces-redirect=true" >
But the redirect works if the code is:
<h:commandButton type="button" value="Enter" action="index?faces-redirect=true" >
<f:ajax />
</h:commandButton>
Could anyone explain this? Thanks!
-----------------------EDIT------------------------
The entire xhtml code for your reference:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="form">
<h:commandButton id="enterModelButton" type="button" value="Enter" action="index?faces-redirect=true" >
<f:ajax />
</h:commandButton>
</h:form>
</h:body>
</html>
The <h:commandButton type="button"> doesn't generate a submit button. It just generates a "dead" button without any effects, purely intented to be used for custom onclick="..." scripts and like. This is somewhat a leftover of the dark JSF 1.0/1.1 era, when it wasn't nicely possible to just use plain vanilla HTML in JSF for this kind of things.
The <f:ajax> performs the submit by ajax powers through JSF-generated onclick. It doesn't care about the button's type.
Essentially, removing type="button" and relying on its default type="submit" should fix your problem.
<h:commandButton value="Enter" action="index?faces-redirect=true" />
However, all with all, if this is the real code and you don't actually intend to invoke a bean action, then you're going in completely the wrong direction as to implementing the functional requirement of navigating to a different page by a button. You should be using <h:button> instead.
<h:button value="Enter" outcome="index" />
See also:
Difference between h:button and h:commandButton
How to navigate in JSF? How to make URL reflect current page (and not previous one)

Unable to understand <h:head> behaviour

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?
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:
Use ajax="false".
<p:commandLink ... ajax="false" />
Just use <h:commandLink> instead.
<h:commandLink ... />
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>

Resources