What URL should I use in $.ajax() in order to submit a form - ajax

Working in JSF2 and ajax, i can't figure out what's the value of the $.ajax URL attribute in JSF context as i want to submit a form and update a div staying in the same page
Is it the following?
((HttpServletRequest) facesContext.getExternalContext().getRequest()).getContextPath()`

in my opinion you need pass value to the backing bean and set the parameter, after this you need to update this part (div).
see this http://www.mkyong.com/jsf2/4-ways-to-pass-parameter-from-jsf-page-to-backing-bean/
<p:commandButton action="#{bean.setId}" update="div">
<f:attribute name="id" value="12" />
</p:commandButton>
Another way is using flash, see this: https://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/context/Flash.html

lets say you have a form like this:
<div id="yourDivId">
<h:outputText value='#{yourControllerClass.yourAttribute}'></h:outputText>
</div>
<h:form>
<h:commandButton value="update">
<f:ajax execute="#form" listener="#{yourControllerClass.updateAttribute}"
render=":yourDiveId">
</f:ajax>
</h:commandButton>
</h:form>
in your ControllerClass/bean:
public final void updateAttribute(AjaxBehaviorEvent event){
// do what ever you want, get values, set another values, after that your Div will be auto updated
}
this way, you don't need to care about ajax params or URL...etc.
EDIT:
if you want to get a paramater from a request URL, then you can get it like this:
String paramVal = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);

Related

JSF Ajax method does not persist variable in bean

I have two forms: one to define some filter settings (ajax) and with sumbit buttons which reloads the page by action="null" and one form with a single command button which executes the ajax listener "#{bean.activate}":
<h:form id="settingsForm">
<h:selectBooleanCheckbox value="#{bean.boolean1}" id="bool1">
<f:ajax event="click" render="#all" execute="bool1"/>
</h:selectBooleanCheckbox>
<ui:repeat var="step" value="#{bean.availableSteps}">
<h:commandLink action="#{bean.navigate(step)}">
<h:outputText value="#{step.name}" />
</h:commandLink>
</ui:repeat>
</h:form>
<h:form id="activateForm">
<h:commandButton value="set activate bool and rerender" >
<f:ajax event="click" execute="#form" render="#all" listener="#{bean.activate}"/>
</h:commandButton>
</h:form>
The problem is following:
when I change the checkbox (boolean in backing bean) and click the submit button in the same form, only the changes (in the backing bean) are persisted which were set in the same form.
When I execute the second form (bean.activate), it rerenders fine (shows some more information), but when I THEN submit the first form, the changes of the second form are lost (but they are working on the same bean). I want that it remembers also the variables set in the second form...
It seems that the values set by the other form are not persisted, because when i perform a form submit, all the "information" stored by ajax of the second form is lost.
e.g.
boolean boolean1 = false; //set by form 1
boolean show = false; //set by form 2 (ajax)
public void activate(Ajaxbehaviour...){ show = true; }
Should there be by default only ONE form at all? it seems that two forms (one big and one just so set a variable by ajax) are too much...

render page title using jsf 2

is there any way to include the page's title inside an f:ajax tag, so that its content is also updated at run time?
currently my f:ajax tag looks like this -
<f:ajax render="#form">
i tried to add an id to the h:head tag, and add that id to the 'render' property of the f:ajax tag, but if i do so i get an error when the page loads -
<f:ajax> contains an unknown id 'pageHead' - cannot locate it in the context of the component B1
cheers,
eRez
Interesting question. I think there is no such command in render of ajax (like #form) to re-render the page title. What you can do is to wrap <title> with <h:form> or other "grouping" component (eg. h:panelGroup as Daniel said) like this :
<h:form id="titleForm">
<title>#{fooBean.fooTitle}</title>
</h:form>
And then call ajax update eg. with button :
<h:commandButton immediate="true" value="Change title">
<f:ajax event="click" render=":titleForm" listener="#{fooBean.changeTitle}"/>
</h:commandButton>
Bean:
private String fooTitle;
public void changeTitle() {
this.fooTitle= "updatedTitle";
}
// getter/setter
I don't know what else could you do, this should work. So wrap your title with <h:form id="..."> and then render it from ajax.

JSF f:ajax listener not called

I am trying to have an h:inputText switch out with a different one when an h:commandButton is clicked. To do this, I am trying to tie an f:ajax command with the h:commandButton, with the listener setting a value on the bean (deciding which one to display), and re-rendering the area.
I have tried using listener on the f:ajax, actionListener on the h:commandButton, action on the h:commandButton with execute on the f:ajax. Nothing worked. The mothed I am trying to call is not being called at all - there is no println (see what follows).
The panelGroup is being re-rendered, which is why I need the onevent attribute that re-attaches some JavaScript hint text based on the title (I had an earlier question involving this).
The method I am trying to call:
public void morePressed(AjaxBehaviorEvent e) {
easySearch = !easySearch;
System.out.println("Made it!");
}
The JSF segment that is not working (note the last h:commandButton is trying to re-render the panelGroup):
<h:form>
<h:panelGroup id="switchSearchTexts">
<h:inputText accesskey="s" alt="Search" id="searchBoxPeople" title="Search Plebeians" valueChangeListener="#{peopleBean.simplePersonQuery}" size="25" rendered="#{peopleBean.easySearch}">
<f:ajax render="peopleDataTable" event="keyup" />
</h:inputText>
<h:inputText accesskey="s" alt="Search First Name" id="searchBoxFN" title="Search First Name" size="25" rendered="#{!peopleBean.easySearch}">
<f:ajax render="peopleDataTable" event="keyup" />
</h:inputText>
</h:panelGroup>
<div id="expandBox">
<h:inputText id="searchBoxLN" alt="Search Last Name" styleClass="hideToggle" title="Search Last Name" size="25" />
<h:inputText id="searchBoxAddress" alt="Search Address" styleClass="hideToggle" title="Search Address" size="25" />
</div>
<h:commandButton type="button" styleClass="moreButtonAsText" id="moreButtonAsText" value="â–¸More">
<f:ajax listener="#{peopleBean.morePressed}" render="switchSearchTexts" event="click" onevent="callFunctionAjaxRequest" />
</h:commandButton>
This is the JavaScript (jQuery) that I attach to the More button on pageload. I give it not because I think it could help, but I don't know if this could interfere with the ajax listener in any way:
$(function() {
textboxHint();
$('input[id$="moreButtonAsText"]').toggle(function(e) {
$(this).prop('value', '\u25c2Less');
$(".hideToggle").show(300);
}
, function () {
$(this).prop('value', '\u25b8More');
$(".hideToggle").hide(100);
$('input[id$="searchBoxAddress"]').prop('value', function() {
return $(this).prop('title');
});
$('input[id$="searchBoxAddress"]').blur();
});
});
I have no idea. As I said, I have tried actionListener on h:commandButton with various appraoches there, as well as various approaches to the listener on the ajax. Can anybody see why the listener does not work?
Update:
What I ended up doing, before having an answer, is converting everything to display and hide based on JavaScript, with stuff I needed hidden if they didn't have javascript initially hidden, etc.
However I need the f:ajax elsewhere, now.
The solution is to take out event="click" on the h:commandButton. I still do now know why this was causing it to break, but hey, whatever works.
I had an issue like this. It turned out that an inputText somewhere had a value="#{something.something}" where the property wasn't settable. The exception wasn't being reported anywhere. I had to put a breakpoint on Exception and all subclasses to find it.
Do you really have a function named callFunctionAjaxRequest in your js code? cause if not it may cause the button not to work (because its being referenced to a not existing function) ,
look at the firebug for a possible errors...
try this version of your command button (event="click" can be removed too... and self execute too)
<h:commandButton type="button" styleClass="moreButtonAsText" id="moreButtonAsText" value="More">
<f:ajax listener="#{peopleBean.morePressed}" render="switchSearchTexts" />
</h:commandButton>
Another thing , in your ajax calls of the upper input texts you got reference to searchBoxPeople twice (instead to searchBoxFN in the second f:ajax), fix it cause otherwise when working with searchBoxFN its f:ajax will try to execute an element that its not being rendered ... (can cause serious issues...)
p.s prependId="false" in your h:form will simplify your selectors in jQuery...
The issue is that the managed bean needs to be set up with the right signature event as an input param. Through lots of testing, I was trying to use the same class taking an AjaxBehaviorEvent. As in the same example on the previous forum.
when I declared an ActionListener event (compliant with the button jsf action), the bean is executed!
I had the same problem and followed your example to help me exactly. I simply (20 hrs) fixed this by including the following in my bean:
The first one now gets fired!
public void actionListener(ActionEvent actionEvent) {
// Add event code here...
System.out.println("Made it!");
}
public void morePressed(AjaxBehaviorEvent e) {
System.out.println("Made it!");
}

JSF AJAX validation: execute="#this" render="#form" inconsistent depending on prior requests

I have an h:commandLink that calls a method that changes a property bound to a radio input.
I also have a text input on the same form with some validation (required=true).
If I leave the text input blank, and click on h:commandLink with execute="#this, the radio button updates from the model property as expected, because the text input is never processed and validation never fires.
However, if first I click on a different h:commandLink with execute="#form", then the link with execute="#this", the validation messages go away but the radio button value does not update from the model even though the UIInput for the radio button was never in an invalid state.
I'm finding it annoying that the execute="#this" behaves differently depending on what I had done previously, when my intent with #this was to force everything to update from the model and ignore any submitted values from the components.
I suspect what's happening is something like this:
with #form, radio button and text are both processed.
Radio button is valid so localValue is set
Process validations phase fails overall because of invalid text input, so localValue remains set and does not get cleared or propagate to value
the only way out of this is to explicitly call resetValue() or to re-process the component in question (e.g., execute="#this radio") to clear out localValue and then allow refreshing from bean.
My questions are:
is my understanding of the lifecycle correct?
Am I doing something wrong, or is this one of the annoying-by design things about JSF?
It feels like this may just be another example of this question
How can I populate a text field using PrimeFaces AJAX after validation errors occur?
Unfortunately I feel like I'm finding lots of those lately. :-(
Code example below:
<h:form>
<h:messages/>
Radio =
<h:selectOneRadio value="#{testBean.radioValue}" id="radio" binding="#{radio}">
<f:selectItem itemValue="foo" itemLabel="Foo"/>
<f:selectItem itemValue="bar" itemLabel="Bar"/>
</h:selectOneRadio>
<br></br>
radio bean value = <h:outputText value="#{testBean.radioValue}"/>
<br></br>
radio UIInput localValue = <h:outputText value="#{radio.localValue}"/>
<br></br>
radio UIInput value = <h:outputText value="#{radio.value}"/>
<br></br>
String w/validation = <h:inputText value="#{testBean.stringValue}" required="true" />
<br></br>
<ul>
<li>
<h:commandLink actionListener="#{testBean.changeRadioValue}" value="execute = #form">
<f:ajax render="#form" execute="#form"/>
</h:commandLink>
</li>
<li>
<h:commandLink actionListener="#{testBean.changeRadioValue}" value="execute = #this">
<f:ajax render="#form" execute="#this"/>
</h:commandLink>
</li>
<li>
<h:commandLink actionListener="#{testBean.changeRadioValue}" value="execute = #this radio">
<f:ajax render="#form" execute="#this radio"/>
</h:commandLink>
</li>
</ul>
</h:form>
And this bean:
#ManagedBean
#ViewScoped
public class TestBean {
private String radioValue = "foo";
private String stringValue;
public void changeRadioValue() {
radioValue = "bar";
}
// + getters/setters
}
is my understanding of the lifecycle correct?
Yes.
Am I doing something wrong, or is this one of the annoying-by design things about JSF?
It's one of the "annoying by-design things" of JSF. As stated in my answer on that related question:
Coming back to the concrete problem, I'd imagine that this is an oversight in the JSF2 specification. It would make much more sense to us, JSF developers, when the JSF specification mandates the following:
When JSF needs to update/re-render an input component by an ajax request, and that input component is not included in the process/execute of the ajax request, then JSF should reset the input component's value.
I only don't remember anymore if I have ever reported this against JSF spec. Edit: I reported it: JSF spec issue 1060.

How to call several methods with JSF <f:ajax listener?

Good Afternoon,
I have a search page that uses ajax to render a several datatables without refreshing the page.
It is mandatory for me to call a Method as a Listener for each table.
Below is the snippet for the first datatable that works fine.
To render a second datatable I need to call a method #{evalController.prepareList} as a Listener for the ajax. The problem is that <f:ajax "Listener" attribute won't take more than one method.
So the remaining way is to call <f:ajax several times, and each time with a different listener, which does not work. Is there a way to achieve this?
If not, should I create a method in the managed Bean that calls all the methods that I need and use it as the one listener?
Thanks in advance for your help.
<h:form id="searchform">
<h:panelGrid columns="3" >
<p:inputText value="#{ddnController.patientID}" id="pidinput" maxlength="7" size="7">
<f:ajax execute="#this" event="keyup" render="searchbutton ddntable" listener="#{ddnController.prepareList}"/>
</p:inputText>
<h:commandButton image="#{resource['images/search.png']}" id="searchbutton" value="#{bundle.Search}"
action="submit" actionListener="#{ddnController.prepareList}"
disabled="#{empty ddnController.patientID or ddnController.patientID.equals('0')}"/>
<p:panel><h:outputText value="Saisir 0 pour avoir tous les Patients" style="font-style: italic;"/></p:panel>
</h:panelGrid>
<p:dataTable id="ddntable" value="#{ddnController.items}" var="ddn" rendered="#{!empty ddnController.items}" paginator="true" >....
I am still not sure why the composite method do not have effect when called. Probably it is not called during before or after the right phase (I'll be profiling it later). Anyway, I found a solution with two edges (it is solving my problem but makes me sacrifice the use of ajax) :
So Instead of calling - from each managed bean - the method (prepareList()) which I use as listener:
private DataModel items = null; // Getter to retrieve items
// ......
public String prepareList() {
recreatemodel();
return "List";
}
private void recreatemodel(){
items=null;
}
(by the way, this method sets the datamodel to NULL to refresh it, and that is how my datatables get refreshed).
Inside the command button I nested property action listener:
<h:commandButton image="#{resource['images/search.png']}" id="searchbutton" value="#{bundle.Search}"
action="submit"
disabled="#{empty ddnController.patientID or ddnController.patientID.equals('0')}">
<f:PropertyActionListener target="#{ddnController.items}" value="#{null}" />
<f:PropertyActionListener target="#{evalController.items}" value="#{null}" />
<f:PropertyActionListener target="#{corController.items}" value="#{null}" />
<!--...etc -->
</h:commandButton>
I wish <f:PropertyActionListener /> could be nested inside <h:ajax/>.
If somebody has a solution that allows to use property action listener and ajax to avoid submitting the form with a button, s/he is welcome. I'll make then his/her answer as accepted.

Resources