Is it possible to disable AJAX in RichFaces? - ajax

Is it possible in a Seam/RichFaces page to disable AJAX so requests are sent via regular server-client request, where the entire page is refreshed instead of individual elements? I'm using an a4j:outputPanel and an a4j:commandButton and need to have them not use AJAX in some cases via a toggle button.
Here's a code snippet from the page. Thanks.
<a4j:outputPanel id="output" rendered="#{not empty overtime.overtimeItems}"
ajaxRendered="true">
<c:forEach items="#{overtime.overtimeItems}" var="oc">
<h:outputLabel value="#{oc.dateLabel}"
style="font-weight:#{(oc.id == 1) ? 'bold' : 'normal'}"
for="#{oc.overtimeDateId}" />
<rich:calendar value="#{oc.overtimeDate}"
requiredMessage="Date 1 is required."
id="#{oc.overtimeDateId}" datePattern="MM-dd-yyyy"
required="#{oc.id == 1 ? true : false}" firstWeekDay="0">
<a4j:support event="onchanged"
reRender="#{oc.overtimeHoursId}, #{oc.overtimeHoursOutputId}"
ajaxSingle="true"/>
</rich:calendar>
......
</c:foreach>
</a4j:outputPanel>
<a4j:commandButton action="#{utilities.sendEmail('/pages/overtime/mail.xhtml')}"
type="submit" value="Submit"
reRender="status, valid1, valid2" eventsQueue="foo" status="status"
onclick="this.disabled=false" id="btnSubmit"
oncomplete="#{facesContext.maximumSeverity == null ? 'Richfaces.hideModalPanel(\'mpErrors\');' : 'Richfaces.showModalPanel(\'mpErrors\'); this.disabled=false'}"/>

Only way to do it is to wrap these ajax components in panelgroups and use the rendered property. You'll basically need to provide conditional rendering and provide non-ajax alternatives of the ajax components.
So you would have something like :
<h:panelGroup rendered="#{someBean.ajaxEnabled}">
<a4j:commandButton ..... />
</h:panelGroup>
<h:panelGroup rendered="#{!someBean.ajaxEnabled}">
<h:commandButton ..... />
</h:panelGroup>

Related

JSF forEach loop values as method parameter

I think I have a somewhat easy question, I hope.
In my JSF page I use a forEach loop to create buttons to navigate through pages of a table. With ajax I want to render the table according to the clicked page. This looks something like this:
<h:form>
<c:forEach begin="1"
end="#{pages%1 == 0 ? pages : 1+pages-(pages%1)}" step="1"
var="page">
<ui:param name="pageParam" value="#{page}"/>
<h:commandButton value="#{page}">
<f:ajax render="testing" listener="#{properties.setPage(page)}" />
</h:commandButton>
</c:forEach>
<h:outputText id="testing" value="#{properties.getPage()}" />
</h:form>
As you can see, I try to set the page attribute in my bean. But when I click the buttons, I get an exception, that the method was not found (setPage takes int as parameter, but "page" is passed as Byte -> Exception: [...]setPage(java.lang.Byte) ).
So the question is, how can I pass the page number from the forEach as a integer? Is it even possible to pass each generated number to the correlating ajax?
Try something like that:
<c:forEach begin="1" end="#{pages%1 == 0 ? pages : 1+pages-(pages%1)}" step="1" var="page" varStatus="loop">
<ui:param name="pageParam" value="#{page}"/>
<h:commandButton value="#{page}">
<f:ajax render="testing" listener="#{properties.setPage(#{loop.index})}" />
</h:commandButton>
</c:forEach>

JSF and AJAX: hiding part of site until first ajax request

I'm trying to create a page where some content will be displayed after ajax request. Here is part of my code:
<h:panelGroup>
<h:form>
Retrive object by id: <h:inputText id="myInput" value="#{myManager.id}"/>
<h:commandButton value="ok" action="#{myManager.getById}" >
<f:ajax execute="myInput" render="resultRow" />
</h:commandButton>
<h:panelGroup id="resultRow" >
<br />
You retrived object which id is:
<h:outputText value="#{retrivedObject.id}" />
and its name is:
<h:outputText value="#{retrivedObject.name}" />
</h:panelGroup>
</h:form>
</h:panelGroup>
My problem is taht the "You retrived object which id is: " is rendered even before I retrive any object. I want it to be hidden until I click my command button. Is it possible to do only with jsf + html (this have to be done with ajax)? I could use some javascript if I will have to, but I prefer not.
I tried to solve this by rendered="#{!retrivedObject.id==0}" (my object can't have id 0), but this doesn't work - panel group isn't rendered at all and when I call ajax reqest it is unable to find "resultRow" id.
Thanks for help in advance.
It may not be exactly what you are looking for but you can always wrap the panelGroup in a div and set the div visibility to hidden, then use javascript to change the visibility when you click the command button.
You can use the rendered attribute like this :
<h:panelGroup>
<h:form>
Retrive object by id: <h:inputText id="myInput" value="#{myManager.id}"/>
<h:commandButton value="ok" action="#{myManager.getById}" >
<f:ajax execute="myInput" render="resultRow" />
</h:commandButton>
<h:panelGroup id="resultRow">
<h:panelGroup rendered="#{retrivedObject ne null}">
<br />
You retrived object which id is:
<h:outputText value="#{retrivedObject.id}" />
and its name is:
<h:outputText value="#{retrivedObject.name}" />
</h:panelGroup>
</h:panelGroup>
</h:form>
</h:panelGroup>

jsf f:ajax render ony if value in execute not null or empty

I have a trouble with my jsf page. I do not know how can make ajax render only when "input" not null or not empty.
Here is my code:
<h:inputText id="input" value="#{control.query}"/>
<h:commandButton id="search" value="Search" action="#{control.getdata()}">
<f:ajax execute="input" render="datatable"/>
</h:commandButton>
Thanks you!
Make use of rendered attribute on the target.
<h:panelGroup id="datatable">
<h:dataTable ... rendered="#{not empty control.query}">
...
</h:dataTable>
</h:panelGroup>

Ajax not working with primefaces

In my JSF page I have form when I click submit button in the same page I need to show an static content. But When I click <p:commandbutton> nothing appears in the page. When I put ajax="false" then only action taken place but the Static content display in new page.
In my Backing bean I have used Session scoped. I am using JSF 2.0 and Primefaces 3.2.
My JSF Page.
<h:form>
<h:panelGroup rendered="#{not license.showForm}">
<p:panel header="License Key Request" >
<h:panelGrid columns="2" >
..
<h:outputText value="Bla bla"/>
..
<h:outputText value="Bla Bla" />
</h:panelGrid>
<TABLE>
..
<h:outputLabel for="name" value="Requestor Name : *" />
..
<p:inputText id="name" value="#{license.name}" required="true" requiredMessage="Name is required."/>
..
<h:outputLabel for="company" value="Company : * " />
..
<p:inputText id="company" value="#{license.company}" required="true" requiredMessage="Company is required."/>
..
</table>
<p:commandButton value="Form" id="btnAdd" process="#form"
action="#{license.add}" />
..
</table>
</p:panel>
</h:panelGroup>
<h:panelGroup rendered="#{license.showForm}" >
<h:outputText value="Bla Bla"/>
</h:panelGroup>
</h:form>
Your source code is somewhat confusing (e.g. you have two closing table tags). But I assume that you want to show the panelGroup at the bottom if the button is clicked.
The easiest way would be to add an update ="#form" to your commandButton:
<p:commandButton value="Form" id="btnAdd"
process="#form" update="#form"
action="#{license.add}" />
You don't need to update the whole form but only the specific component. Then you need to give the panelGroup an id attribute and use this attribute instead of #form. However, since it is not clear for me how your naming containers are organized, it could be puzzling to find the correct relative id.

Rendering other form by ajax causes its view state to be lost, how do I add this back?

I have
<h:form>
<h:commandLink action="#{my_fake_ajax_link}">
<h:outputText value="Link" />
<f:ajax render=":mydiv" />
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="mydiv">
<h:form>
<h:commandLink action="#{mybean.delete(0)}">
<h:outputText value="Here" />
<f:ajax render="#form" />
</h:commandLink>
</h:form>
</h:panelGroup>
When I click once on "my_fake_ajax_link", then I have to click twice on "delete" link. This is only an example. I don't have this real case. I have multiple forms on a page and I can't just add all of them in a single form.
I checked what the problem is and it is:
When you click on "my_fake_ajax_link", the mydiv refreshs with ajax as it should.
ViewState of the refreshed form on ajax is missing.
How can I add the ViewState? How can I make it work without using only one form? This looks like an JSF bug to me. I don't want to refresh that div automatically with
jQuery("#mydiv").load(document.location.href);
but I will in my worst case possible.
This is a known problem in the auto-included jsf.js library of JSF which handles ajax responses. See also JSF spec issue 790 which is fixed in the upcoming JSF 2.3. In the meanwhile, with JSF 2.0/2.1/2.2, you have to explicitly specify the ID of the other <h:form> inside the render attribtue to trigger proper addition of the view state.
<h:form>
<h:commandLink action="#{my_fake_ajax_link}">
<h:outputText value="Link" />
<f:ajax render=":mydiv :mydivForm" />
</h:commandLink>
</h:form>
<h:panelGroup layout="block" id="mydiv">
<h:form id="mydivForm">
<h:commandLink action="#{mybean.delete(0)}">
<h:outputText value="Here" />
<f:ajax render="#form" />
</h:commandLink>
</h:form>
</h:panelGroup>
No, this does not cause any overhead or markup duplication in the ajax response. Alternatively, use OmniFaces fixviewstate.js.
See also:
Communication in JSF 2.0 - Ajax rendering of content which contains another form
h:commandButton/h:commandLink does not work on first click, works only on second click
Workaround for that:
First you need to set an onevent handler for the button that sends the ajax request:
<h:form id="newComment">
<h:commandButton id="saveNewComment" action="#{postBean.actionSaveNewCommentAjax}" value="#{rb['speichern']}">
<f:ajax execute="#form" render=":commentsBox" onevent="function(data) { fixOtherFormsViewState(data, 'newComment') }" />
</h:commandButton>
</h:form>
Then you need to declare this javascript methods that will take the correct viewState value and add it to all forms which doesn't have it:
<h:outputScript>
function fixOtherFormsViewState(data, goodFormId) {
if (data.status != "success") {
return;
}
var viewState = jQuery("#" + goodFormId + " input[name='javax.faces.ViewState']").val();
jQuery("form:not(:contains(input[name='javax.faces.ViewState']))").each(function (idx, elem) {
var form = jQuery(elem);
var input = jQuery("<input type='hidden' name='javax.faces.ViewState' />").val(viewState);
form.append(input);
});
}
</h:outputScript>

Resources