I was originally posting a value in the h:inputText field with an a4j:commandButton but I had to change the commandButton to s:link because the commandButton is also triggering a pdf document to be exported, and I believe that with an ajax call, the doc is rendered on the browser instead.
So now I am trying to post the value using h:inputText and a4j:support
<h:inputText id="numberOfPatients"
value="#{printLabelsReqFormsAction.numberOfPatients}">
<a4j:support event="onkeyup"
action="#{printLabelsReqFormsAction.setNumberOfPatients(numberOfPatients)}"/>
</h:inputText>
(sorry for the weird formatting..)
My setNumberOfPatients(x) is getting called but I don't think I am passing the value correctly. How should I pass the value of the h:inputText field?
You don't need to explicitly set the value of numberOfPatients while executing ajax support. a4j:support tag processes its parent component during its execution, meaning the value for numberOfPatients will be set for each onkeyup event, even you don't invoke an action event. You can see it better at Richfaces' site:
RichFaces uses form based approach for Ajax request sending. This means each time, when you click an Ajax button or produces an asynchronous request, the data from the closest JSF form is submitted with the XMLHTTPRequest object. The form data contains the values from the form input element and auxiliary information such as state saving data.
When "ajaxSingle" attribute value is "true" , it orders to include only a value of the current component (along with or <a4j:actionparam> values if any) to the request map. In case of <a4j:support> , it is a value of the parent component. An example is placed below:
<h:form>
<h:inputText value="#{person.name}">
<a4j:support event="onkeyup" reRender="test" ajaxSingle="true"/>
</h:inputText>
<h:inputText value="#{person.middleName}"/>
</form>
In other words, for your case this should work:
<h:inputText id="numberOfPatients"
value="#{printLabelsReqFormsAction.numberOfPatients}">
<a4j:support event="onkeyup" ajaxSingle="true"/>
</h:inputText>
Specify an action method only if you want to add extra logic when the event happens.
Related
What i want to do is like basic row selection example at Primefaces showcase(http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf) I want to update my datatable's row. The problem is when i click to update button at datatable, dialogbox appears with validation errors.
Second thing is what is the order of method execution times.(action-update-onclick-f:setPropertyActionListener)
<p:commandButton id="updateButtonId"
action="#{myController.showCompanyEditPanel}"
update=":tabView:companyForm:companyEditPanel"
onclick="companyDialog.show()"
icon="ui-icon-pencil" title="update">
<f:setPropertyActionListener value="#{company}" target="#{myController.selectedCompany}" />
</p:commandButton>
<p:dialog id="editCompanyDialogId" header="CompanyEdit" widgetVar="companyDialog" resizable="false">
<p:panel id="companyEditPanel" >
//some stuff here
</p:panel>
</p:dialog>
You seem to be missing a major point of using a <p:commandButton> here, as well as seem to be mixing client-side and server-side events.
First on <p:commandButton>. This component is designed to POST (partial) form data to the current URL, do business job in action(listener) method and return updated components / perform navigation. You can of course 'attach' JavaScript events to all those attributes.
Second, onclick, oncomplete, and other on... attribute are corresponding to some client-side events. In particular, onclick function is triggered when button was clicked, oncomplete function is called when DOM was updated after the AJAX call, i.e. the elements specified in <p:ajax update="..."> or simply in update="..." attribute of <p:commandButton>.
Third, all action listeners (thus, actionListener attribute, <f:actionListener> tag, <f:setPropertyActionListener> tag) will be executed right in the order they are specified in your tag, see this answer for more elaboration. The last one to be executed is action method, after which response is sent back.
This JSF1 code has me totally puzzled for hours. The basic setup is this page displayed with Seam2:
<h:form encType="multipart/form-data">
<rich:dataTable value="#{results}">
...
</rich:dataTable>
<h:selectOneMenu value="#{contact.type}">
<s:selectItems value="#{contactTypes}" var="t" label="#{t.label}" />
<s:convertEntity />
<a4j:support event="onchange" reRender="submitControls" />
</h:selectOneMenu>
<h:selectOneMenu value="#{template}">
<s:selectItems value="#{allTemplates}" var="t" label="#{t.label}" />
<s:convertEntity />
<a4j:support event="onchange" reRender="submitControls" />
</h:selectOneMenu>
<a4j:outputPanel id="submitControls" layout="block">
<a4j:outputPanel rendered="#{null != results and results.size gt 0 and ('ONE' == contact.type.label or template != null)}">
<h:commandButton value="submit" action="#{manager.generate}" />
</a4j:outputPanel>
<h:outputText value="Search first" rendered="#{results == null or results.size == 0}" />
<h:outputText value="Select template first" rendered="#{'ONE' == contact.type.label and template == null}" />
</a4j:outputPanel>
</h:form>
Obviously, the original page is a bit larger. What has me scratching my head is that if I don't change contact.type (leave it at a default selected by the backing bean) the form submits fine. If I switch the type to ONE this correctly renders the "Select template first" text instead of the submit control. Restoring the submit button by selecting another type re-produces the <input> BUT without the onclick handler that was there when the form was first rendered.
Now a click on the <h:commandButton> sends a request to the server but does NOT trigger the associated action. However, it now restores the onclick handler and a second click triggers a proper submit.
I'm at a loss why this is so. Any suggestions?
EDIT: moving the rendered attribute to the button results in the same behavior (even if it did work, the original panels contain more controls that share the same condition, so they do serve a purpose)
EDIT2: I've just tested that simply re-adding the "lost" onclick handler (via firebug) that gets rendered on the submit button makes the action work as intended. I'm beginning to suspect a bad interaction between richfaces and the trinidad libs also included in this project (but not used on this page).
It's a safeguard against tampered/hacked requests. Otherwise a hacker would be able to invoke actions s/he isn't allowed to invoke by just editing the sent HTTP request parameters accordingly that the non-rendered (e.g. due to missing "ADMIN" role) command button will be invoked.
You need to make sure that you prepare the same model (managed bean instance with all properties responsible holding the conditions behind rendered attribute) during the HTTP request of processing the form submit as it was during the HTTP request of displaying the form. In JSF2, this is easy achievable by placing the bean in the view scope instead of the request scope. The view scope lives as long as you're interacting with the same view. In JSF1, you'd need to grab a 3rd party framework tag like Tomahawk's <t:saveState> or RichFaces' <a4j:keepAlive> in order to simulate the JSF2 view scope.
<a4j:keepAlive beanName="results" />
The same story applies to disabled attribute by the way.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
JSF 1.2: How to keep request scoped managed bean alive across postbacks on same view?
I think that with the rendered attribute and anything inside you have to take care that the evaluation of it is the same on the initial request AND the submit. It may change just before the render phase but if its not the same during application invoke it will most likely ignore the action if in this phase the button would not be rendered.
As far as i remember this happend for me mostly when the rendered expression uses something like an entity attribute that will be changed during the apply request values phase already.
I am trying to use <a4j:ajax> to feed a method with a value just entered on the form;
<h:selectOneMenu id="aa" value="#{colorClass.color}">
<f:selectItems value="#{myChoices.colorOptions}"/>
<a4j:ajax event="change" render="colorCode"
execute="#{myChoices.getColorCode(colorClass,colorClass.color)}"/>
</selectOneMenu>
Color on the form is selected correctly;
my problem is that when I pass colorClass.color as part of the execute, it is blank;
if I replace colorClass.color with a literal
<a4j:ajax event="change" render="colorCode"
execute="#{myChoices.getColorCode(colorClass,'green')}"/>
the method is called, finds the colorCode and repaints the form
How can I "grab" the value just entered so that I can pass it as a parameter to the method?
You need listener attribute instead of execute attribute. The execute attribute should point to a collection of client IDs which are to be submitted (which defaults to #this in <f:ajax> and #form in <a4j:ajax>). However in your particular case it returns void and keeps the execute empty. The listener attribute is supposed to point to a bean action listener method. Fix it accordingly:
<a4j:ajax event="change" render="colorCode"
listener="#{myChoices.getColorCode(colorClass,colorClass.color)}"/>
Note that the colorClass argument seems superfluous here, or at least the colorClass.color as you could also just do colorClass.getColor() inside the getColorCode() method. Just passing one of them ought to be sufficient. Passing colorClass.color would be preferable so that your myChoices bean is not tight coupled with the colorCode bean.
<a4j:ajax event="change" render="colorCode"
listener="#{myChoices.getColorCode(colorClass.color)}"/>
I have a input text like this:
<h:inputText value="#{someValue}">
<f:ajax event="change" listener="#{someMethod}" render="someDataTable"/>
</h:inputText>
I have a data table like this:
<h:dataTable value="#{someList}" var="anyVar" id="someDataTable">
some things
</h:dataTable>
When I change the text in the input text, the change is not hapenning immediately, rather I have to click on the page on anything to get the required result in the data table.
Does anyone know how to solve this problem?
On HTML input text elements, the HTML DOM change event is only fired when the element's value has been changed and the element loses focus (i.e. the blur event has been fired as well). Clicking anywhere else on the page or tabbing to next element would fire the blur event. So the described symptoms perfectly matches the specified behaviour.
You're most probably interested in the keyup event.
<f:ajax event="keyup" ... />
Keep in mind that this fires the Ajax request on every keystroke which is not necessarily cheap. You might want to add a delay of ~200ms.
<f:ajax event="keyup" delay="200" ... />
See also:
What values can I pass to the event attribute of the f:ajax tag?
I'm new to JSF and EL, and was wondering if there is a way to use EL to get the current value of an h:inputText field. Am I doing it wrong, or is it possible at all?
Thanks,
-Ben
(Based on your comment) If you want to validate it server-side then you should look at an Ajax library like Richfaces.
You can then easily add an ajax call to your input field
<h:inputText id="myInput" value="#{myBean.myValue}">
<a4j:support event="onchange" ajaxSingle="true"/>
</h:inputText>
When you change the text the Ajax call will update your model on the Server-side. If you have a validator then you can add it to the inputText tag or use the action attribute on the support tag to call another method.
I don't really understand what you are looking for...
With this code:
<h:form id="myForm">
<h:inputText id="myInput" value="#{myBean.myValue}"/>
The value of the input field, at the creation of the HTML page, will be equal to the value of the myValue property of the bean myBean.
If the value is changed by the user, JSF will automatically update the value of myBean.myValue when the form will be submitted.
If you need to get the value of the input on the client side, i.e. using Javascript, you need to do the following code:
<script type="text/javascript">
function getInputTextValue() {
var valueOfInput = document.getElementById("myForm:myInput").value;
}
</script>
Note that you must prefix the ID by the ID of the form that contains the input ("**myForm:**myInput").