continuation of pressing button twice - ajax

Yesterday I posted a question about having to press a button twice to get it to work. I received good help, which is the hallmark of stackoverflow, but the problem still exists. I cut down my code to the bare minimum and the problem still exists. I read closely a BalusC suggestion, hoping that I would find a form inside a form. There is certainly nothing I can see so I will post my code in the hopes that additional pairs of eyes will see something.
I have a template which I call from welcome (the login part). This goes to userInfo which has a command button. This is the command button which I mysteriously have to press twice. On the second push the command button will take me to userPhoto. Everything is trimmed down to the minimum so that I can post it.
master.xthml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Master template</title>
</h:head>
<h:body>
<p:layout fullPage="true" >
<p:layoutUnit position="north" size="254">
Top
</p:layoutUnit>
<p:layoutUnit position="east" size="50" resizable="true">
Hello
</p:layoutUnit>
<p:layoutUnit position="south" size="30">
south
</p:layoutUnit>
<p:layoutUnit position="center">
<ui:insert name="AreaOne">Default text</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
</html>
welcome1.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<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:p="http://primefaces.org/ui">
<ui:composition template="master.xhtml">
<ui:define name="AreaOne">
<h:form id="form1">
<p:commandButton type="submit" value="Login" action="userInfo" />
</h:form>
<p:messages />
</ui:define>
</ui:composition>
</html>
And last but not least userInfo.xhtml with the button which needs to be pressed twice:
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<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:p="http://primefaces.org/ui">
<ui:composition template="master.xhtml">
<ui:define name="AreaOne">
<h:form id="formP">
<p:commandButton type="submit" value="photos" action="userPhoto" />
</h:form>
<p:messages />
</ui:define>
</ui:composition>
</html>
I don't see any form nested inside any other form, but SOMETHING is wrong and I can't figure out what. Maybe BalusC is correct that it has something to do with ajax, but I don't see that either.
Thanks for all the help.
Ilan
I added a button on the userPhoto page which goes back to the userInfo page. The Login button is the only one which works one the first press. When I use the command buttons to switch back and forth between userInfo and userPhoto, it always takes 2 pushes. I will show the center of userPhoto
<ui:composition template="master.xhtml">
<ui:define name="AreaOne">
<h:form id="form3">
<p:commandButton type="submit" value="home page" action="userInfo" />
</h:form>
<p:messages />
</ui:define>
</ui:composition>

You've there a very specific problem. You're fully navigating by ajax instead of by a normal synchronous request and the whole view is replaced with the new view. The forms in the new view does not have the view state anymore which is indeed related to JSF issue 790. It's also not possible to reference the forms in the update of the <p:commandButton> as the forms does not exist in the same view.
After all, it's not recommendable to fully navigate by ajax. It makes your page non-bookmarkable and non-searchbotindexable. I suggest to replace all forms of
<p:commandButton ... action="otherViewId" />
by
<p:button ... outcome="otherViewId" />
This will navigate by normal synchronous requests and will create new views wherein all forms will have their view state. Note that the <p:button> doesn't require a <h:form>, you can omit it if necessary.
Unrelated to the concrete problem, I also suggest to put master.xhtml in the /WEB-INF folder so that the endusers can never request it by entering/guessing its URL in browser address bar. See also Which XHTML files do I need to put in /WEB-INF and which not?

Related

Oracle ADF popup not showing when button clicked

I am new to JDeveloper and ADF. I am trying to make a popup appear on my webpage when I am using JDeveloper to make an ADF application. Here is my code:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:document title="untitled1.jsf" id="d1">
<af:popup childCreation="deferred" autoCancel="disabled" id="somePopup">
<af:outputText value="Hello there" id="ot1"/>
</af:popup>
<af:commandButton id="button" text="Click me">
<af:showPopupBehavior popupId="somePopup" triggerType="action" />
</af:commandButton>
</af:document>
</f:view>
I believe I have done everything correctly in order for this popup to show, but when I click the button, nothing appears. I was thinking I might need a panel in order to show the text, but I don't think that is necessary. Do you guys have an idea of what's going on or how I should make a popup? My JDeveloper Version is: 11.1.2.2.0. I know this is a simple task, but I am stuck on getting it to show and would appreciate some help. Thanks guys.
It is a browser issue. The code is correct, I just can't find a way to get my browser to actually show it.
Add partialSubmit="true" attribute to your commandButton.
I think you are missing the af:form tag in your page.
This works for me in 12.1.3:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:document title="untitled3.jsf" id="d1">
<af:form id="f1">
<af:popup childCreation="deferred" autoCancel="disabled" id="somePopup">
<af:outputText value="Hello there" id="ot1"/>
</af:popup>
<af:commandButton id="button" text="Click me">
<af:showPopupBehavior popupId="somePopup" triggerType="action" />
</af:commandButton>
</af:form>
</af:document>
</f:view>
First create the binding for the popup.In Command Button add Action Listener.Then in th action event method Write the below code..
RichPopup.popuphints hints = new RichPopup.popuphints();//hints is the object name
popupbind.show(hints); //popupbind is the property of popup

Trigger <a4j:ajax> request on page load

I have a page which has to trigger an AJAX request when it is loaded. I've managed to perform the request when clicking a button on the page. But I haven't managed to trigger this automatically on page load. The parameter to use comes from the other page via f:viewParam.
I've tried to use a load event which seems to be usable with f:ajax and HTMLGraphicImage or HTMLBody as per this thread but it doesn't work with a4j:ajax (or I may be missing something).
Tag Exception
<a4j:ajax> loadevent is not supported for the HtmlGraphicImage
I haven't posted the bean for simplicity as this part now works as I want to. My problem is about triggering the a4j:ajax tag. If you think the bean would be also needed just let me know.
I think there is a way to do it via PrimeFaces. I am not sure I'll be allowed to add this library to the project so please post other solutions if there are any.
Here is the JSF page. This one tries to use an image load event to trigger AJAX. There is also an attempt to use HTMLBody but it's tagged with ui:remove:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j">
<ui:composition template="layouts/template.jsf">
<ui:define name="body">
<f:metadata>
<f:viewParam name="recordCode"
value="#{recordDetailBean.record.recordCode}" />
</f:metadata>
<h:graphicImage value="/images/transparent.gif">
<a4j:ajax event="load"
action="#{recordDetailBean.createDummyDelay}"
status="loadingRecordDetail" render="recordDetail" />
</h:graphicImage>
<ui:remove>
<a4j:ajax event="load"
action="#{recordDetailBean.createDummyDelay}"
status="loadingRecordDetail" render="recordDetail" />
</ui:remove>
<rich:popupPanel id="loadRecord" style="text-align:center"
autosized="true" modal="true" width="200">
<h:graphicImage value="/images/ajax-loader.gif" />
<br />
<h:outputText value="#{msg.loadingRecord}" />
</rich:popupPanel>
<a4j:status name="loadingRecordDetail">
<f:facet name="start">
<rich:componentControl event="start" operation="show"
target="loadRecord" />
</f:facet>
<f:facet name="stop">
<rich:componentControl event="stop" operation="hide"
target="loadRecord" />
</f:facet>
</a4j:status>
<h:form>
<a4j:commandButton value="Do something"
action="#{recordDetailBean.createDummyDelay}"
status="loadingRecordDetail" render="recordDetail" />
<a4j:outputPanel id="recordDetail">
<h:outputText value="#{recordDetailBean.dummyDelay}" />
</a4j:outputPanel>
</h:form>
</ui:define>
</ui:composition>
</html>
Thanks in advance.
Watching again my question I guess I should have asked that I wanted to link two pages passing a parameter and invoking a method of the managed bean being invoked prior to page render.
This is the approach I finally used. It is probably shown in other threads so this may be closed as duplicate. I also followed guidelines shown in this answer by BalusC regarding f:metadata. Unfortunately I couldn't make a "loading" h:popupPanel appear prior to change to the other page. If somebody could provide an approach to do this I would open another question:
Link on the first page:
<h:link value="#{rSearch.recordCode}" outcome="recordDetail">
<f:param name="recordCode" value="#{rSearch.recordCode}" />
</h:link>
Metadata on the page being called:
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="recordCode" value="#{RecordDetailBean.theRecord.recordCode}" />
<f:event type="preRenderView" listener="#{RecordDetailBean.populateRecord}" />
</f:metadata>
</ui:define>
In the populateRecord method I use a DAO and the parameter stored in RecordDetailBean.theRecord.recordCode to retrieve all the info I need before the page is rendered.

Richfaces 4 select only gets rendered correctly after a site refresh

I don't know if I'm doing something wrong or if it might be a bug or something.
My setup contains IntelliJ IDEA 12, JBoss AS 7.2.0.Final, Richfaces 4.3.4 within a war-File within an ear-Project (no Maven).
I have this index-page:
<ui:composition 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:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<rich:notifyMessage stayTime="3500" showShadow="true" showCloseButton="true" />
<f:view>
<h:head> <title> title </title> </h:head>
<h:body>
<!-- some more divs for page-design, but commented out at the moment -->
<div id="page">
<div id="index_workspace" style="width:1000px;margin:auto;">
<h:panelGrid columns="2" id="index_workspace_table">
<rich:panel id="index_workspace_navi_left" style="width:180px;min-height:600px;max-height:600px;">
<ui:include src="general/navi_left.xhtml"/>
</rich:panel>
<rich:panel id="index_workspace_content" style="width:550px; min-height:600px; max-height:600px;" rendered="#{not empty naviBean.content}">
<a4j:outputPanel id="index_workspace_content_ajax" ajaxRendered="true">
<ui:include src="#{naviBean.content}" id="current_site" />
</a4j:outputPanel>
</rich:panel>
</h:panelGrid>
</div>
<!-- some more divs for page-design, but commented out at the moment -->
</div>
</h:body>
</f:view>
</ui:composition>
Within the section I load the pages with forms and all the other cool stuff RF brings. But I have a rendering problem with this part of a loaded page:
<rich:select id="someID_1" rendered="true" immediate="true" required="true" enableManualInput="true" defaultLabel="someLabel">
<a4j:ajax render="true">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</a4j:ajax>
</rich:select>
And here my problem is located:
This drop-down list only gets rendered on a page reload, e.g. F5 or CTRL-R action.
Also I could observe that if I set this element on some Kind of a "start page" (initially loaded on the index.xhtml) it gets rendered very well. In this case every other page containing this kind of element renders it correctly also.
I tried
updating JSF from 2.1 to 2.2.1 - that only brought up more problems - so I rolled it back.
The "standard" h:selectOneMenu behaves the same.
additional options within rich:select (e.g.: rendered, immediate, required, ...)
different ajax commands within the navigation (server, client, ajax, on different levels)
googling around since days - found no useable hint
I would appreciate every hint that guides me into the right direction as I feel confident, that I make some mistake I can't figure out...
Additionally my navigation looks like this (in another div on the index.xhtml):
<ui:composition 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:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<h:form id="navi_left">
<rich:panel>
<rich:panelMenu itemMode="ajax" groupMode="ajax" itemChangeListener="#{naviBean.updateContent}" >
<rich:panelMenuGroup itemLeftIcon="disc" label="Erfassung" name="#{naviBean.content}">
<rich:panelMenuItem label="someLabel_navi" name="path/to/page-not-getting-rendered-well.xhtml"/>
</rich:panelMenuGroup>
</rich:panel>
</h:form>
</ui:component>
Hope this helps helping me.
<a4j:ajax render="true">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</a4j:ajax>
The above construct is not legal(as you've already seen yourself). The render attribute in there is not used for what you'd expect: to conditionally render the component; Rather, it's supposed to contain a list of on-page components to update via ajax.
To achieve the output I presume you're trying to get, you should use the following instead:
<a4j:region>
<rich:select id="someID_1" rendered="true" immediate="true" required="true" enableManualInput="true" defaultLabel="someLabel">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</rich:select>
<a4j:region>
I think I found the problem. As my navigation and my desired site with the not correctly rendered component lie nested in <div>s on the third participating site - my index.xhtml - it seems to be impossible to let a jsf-component be rendered without having all (i.e. the navigation and the desired) sites processed on the server. So the following code-snippets work for my situation:
index.xhtml snippet:
<rich:panel id="index_workspace_content" style="width:550px; min-height:600px; max-height:600px;" rendered="#{not empty naviBean.content}">
<ui:include src="#{naviBean.content}" id="current_site" />
</rich:panel>
navi_left.xhtml snippet:
<h:form id="navi_left">
<rich:panel>
<rich:panelMenu itemMode="server" groupMode="client" itemChangeListener="#{naviBean.updateContent}">
<rich:panelMenuGroup label="someLabel" name="#{naviBean.content}">
<rich:panelMenuItem label="anotherLabel" name="path/to/page-being-rendered-correctly.xhtml"/>
</rich:panelMenuGroup>
...
</h:form>
component snippet in the desired.xhtml:
<rich:select id="someId" rendered="true" immediate="true" required="true" enableManualInput="true">
<f:selectItems var="#{backingBean.selectableItemList}" id="selectlist" value="#{backingBean.predefinedItem}"/>
</rich:select>
So what I have changed is the itemMode to "server", both of the others (ajax and client) will not work!
Setting the groupMode to "client" does not affect the renderprocess of desired.xhtml as it only describes the way the rich:panelMenu behaves.
What makes me feel a bit confused is, that the URL now gets extended with a "/index.xhtml". Before the change it was always just the url:port/context (e.g. localhost:8080/app ).
So it works now, but maybe it's not really what I wanted. I'll observe and report future facts concerning this itemMode-option here.

JSF Form with AJAX validation - Focus issues

Hi JSF experts out there ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui">
<h:head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
</h:head>
<h:body>
<h:form>
<o:validateOneOrMore components="one two three" id="validate"/>
<p:message for="validate"/>
<p:inputText id="one" value="#{testBean.valueOne}">
<p:ajax event="change" process="#this" update="#form"/>
</p:inputText>
<p:inputText id="two" value="#{testBean.valueTwo}">
<p:ajax event="change" process="#this" update="two"/>
</p:inputText>
<p:inputText id="three" value="#{testBean.valueThree}">
<p:ajax event="change" process="#this" update="one two validate"/>
</p:inputText>
<p:commandButton process="#form"
update="#form"
value="Submit"
partialSubmit="true"
action="#{testBean.submit}"/>
</h:form>
</h:body>
</html>
a simple form with requirement of at least one form filled, immediate error reset and tab-able.
But i didn't get it work, tried different things as you can see in sample code.
What happens
hit submit -> error message shown: fine
enter entry in field one and leave with tab: fine (all fields are not in error state anymore and message is gone) BUT focus lost after complete AJAX update. Ok expected behavior of JSF and browsers as i read here, but how to solve?
delete all entries, hit enter -> input in field three and leave the field ... nothing changes ... even message is not gone sth. i also do not understand, since i updated all fields
Is there any solution out, for having a form like that ... where after each input validation of form will happen (meaning remove such global errors) and still have it quickly usable by using the tab-key?
thx.
This is a very annoying issue, which has to do with the way JSF preforms partial renders, there is an in depth post regarding JSF 2 AJAX focus issues.
Which offers a potential solution in the form of using the JSF JavaScript API to listen for triggered AJAX request and refocusing, have a look at the post for further details.

Why did ajax break when sub forms are loaded in a c:forEach block?

I found a strange behavior using JSF 2.0 and Ajax functionality. Ajax seems to no longer work if a subpage is loaded in c:forEach block.
I am using a main form which includes a set of subpages dynamically (based on a backend configuration):
<c:forEach items="#{workflowController.editorSections}" var="section">
<div class="imixs-portlet" >
<ui:include src="/pages/workitems/parts/#{section.url}.xhtml"/>
</div>
</c:forEach>
In this case it is not possible to use simple f:ajax render"..." tags.
For example the following code snippet will only work for the first subpage be included in the c:forEach tag :
<h:commandButton value="Welcome Me">
<f:ajax execute="name" render="output" />
</h:commandButton>
<h:outputText id="output" value="#{childWorkitemController.name}" />
If I try to use f:ajax in the subpage which was included after the first subpage, then in this subpage ajax will no longer work.
So for now my only working solution was to skip the c:forEach block and include all subpages manually.
Why did ajax behavior breaks when subpages are included in a c:forEach block?
The Problem was that I did not use a ui:composition tag for my subpages.
This was the structure of my subpage before
<f:subview xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions" id="mysubpage">
<h:panelGroup layout="block" styleClass="imixs-form-section"
id="minutes_body" binding="#{minutesBody}">
....
</f:subview>
After I changed into a ui:composition everything is working!
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:panelGroup layout="block" styleClass="imixs-form-section"
id="minutes_body" binding="#{minutesBody}">
....
</ui:composition>
With thie ui:composition tag my subpages can be included in any situation and ajax is working as expected.
Only in one situation it was still necessary to surround a part of a subpage with a f:subview element.
Otherwise I got a alert box with the message:
malformedXML: During update: workitem_form:form_panel:j_idt179 not found
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<!-- subview tag necessary here -->
<f:subview>
<!-- minutes body -->
<h:panelGroup layout="block" styleClass="imixs-form-section"
id="minutes_body" binding="#{minutesBody}">
.....
</f:subview>
</ui:composition>

Resources