Rerender all h:inputText fields with same id inside h:dataTable - ajax

I think I am wasting my time yet again figuring out how to do such a simple thing in JSF, but assuming the following set-up:
<h:form id="form">
<h:dataTable id="table">
<! -- not shown: other columns with other input fields -->
<h:column>
<h:inputText id="myinput">
<f:ajax execute="#this" render="????" listener="#{bean.action}" />
</h:inputText>
</h:column>
</h:dataTable>
</h:form>
What do I specify in the render tag to ONLY re-render all "myinput" components across all rows in the datatable, ie without specifying "#form" that will re-render the other components as well? I have tried #this and ":form:table:myinput", but it always just re-renders the very first row of the dataTable. It seems like this should be such a simple use-case, so I have to obviously be misunderstanding something.
Note: I don't know if internally JSF creates N HtmlInputTextComponents for each row or just 1, but obviously when I say "all myinput components", I mean all rendered input fields back to the browser that were generated from the h:inputText tag and that have the same browser DOM id of form:table:myinput:n.
As a corollary and additional question, I don't want to process or re-render the whole form components because of possible validation/conversion errors. I simply want the following to happen: only the initiating "myinput" component that triggered the ajax call is validated, and if success, all of the other "myinput" components are populated and subsequently re-rendered with new model values that were changed from the action listener "#{bean.action}".
Additional information:
I am currently using the mojarra implementation version of JSF 2.1 (I think). I would like to avoid any third party JSF libraries.
Bonus questions (which perhaps the answer to my original question would also answer):
How to re-render and/or execute all input components but only for a single row
How to re-render and/or execute set of input components but only for a single row
How to re-render and/or execute all input components for a set of rows (not all)
How to re-render and/or execute set of input components for a set of rows (not all)
To everyone replying that I can set the id of the inputText based upon the current rowIndex or current iteration variable - NO, that does not work. See: Set id of a component within JSF dataTable to value from current item in the array
I really think the only way to accomplish what I want is to abandon using a datatable and render the table columns/rpws with JSTL myself such that I can assign unique ids and have full control. However, I still think this is a huge design flaw in JSF to not support such a seemingly simple use-case.

What do I specify in the render tag to ONLY re-render all "myinput" components across all rows in the datatable, ie without specifying "#form" that will re-render the other components as well?
TL;DR: How do I re-render the entire column?
This is not possible using standard JSF facilities. You basically need to (auto)generate the collection of client IDs form:table:0:myinput, form:table:1:myinput, form:table:2:myinput, etc yourself based on row count/index, and manually add them all to the PartialViewContext#getRenderIds() collection during #{bean.action}. It's not possible to specify them in render attribute as those client IDs don't exist in JSF component tree, but JSF strictly wants to validate them (and you thus end up with confusing "cannot find client ID" exceptions).
I'm aware that you want to avoid 3rd party libraries, but OmniFaces Ajax#updateColumn() provides exactly this functionality which only takes the table component and the (zero-based) column index as arguments. E.g.
public void action() {
// ...
UIData table = Components.findComponent("form:table");
Ajax.updateColumn(table, 2); // Updates third column.
}
Feel free to borrow/steal/improve the source under Apache 2.0 license if the remainder of OmniFaces isn't sufficiently convenient to not anymore consider it as an "average" 3rd party library.
We have by the way a possible enhancement in the queue for a future OmniFaces release, which must make this kind of requirements more hair-friendly: event driven updates.
How to re-render and/or execute all input components but only for a single row?
How to re-render and/or execute set of input components but only for a single row?
You can specify them in render attribute using relative client IDs like so:
<h:column><h:inputText id="input1" ... /></h:column>
<h:column><h:inputText id="input2" ... /></h:column>
<h:column><h:inputText id="input3" ... /></h:column>
<h:column><h:inputText id="input4" ...><f:ajax render="input1 input2 input3" ... /></h:inputText></h:column>
Note: there's no way to explicitly say "all input components". You'd have to specify them individually. If you happen to use PrimeFaces, or are open to using it, then PrimeFaces Selectors would make this much easier. See also among others How do PrimeFaces Selectors as in update="#(.myClass)" work?
How to re-render and/or execute all input components for a set of rows (not all)
How to re-render and/or execute set of input components for a set of rows (not all)
Also here, no standard facility. You could extend on the aforementioned Ajax#updateColumn() source code. The key problem is that you wanted to update other rows as well than only the current row. For that you'd really need to (auto)generate full client IDs and add them to PartialViewContext#getRenderIds().

<h:form id="form">
<h:dataTable id="table" rowIndexVar="idx">
<! -- not shown: other columns with other input fields -->
<h:column>
<h:inputText id="myinput#{idx.index}">
<f:ajax execute="#this" render="????" listener="#{bean.action}" />
</h:inputText>
</h:column>
</h:dataTable>
</h:form>
using firebug, you can see that all your inputs have an id now. Now, you can put in your render what you want according to this id.
you must use
RequestContext.getCurrentInstance().update(lstIndex);
in your java code where lstIndex is the list of ids that you want to update

Related

How to stop next ajax request until current one get completed?

Hi In my project I have input text box like following, where on "keyup" event I am making a call to managed bean where I perform searching operation in a arraylist.
That arraylist I show in p:dataTable which is named as userDataTable
My Code for xhtml
<p:inputText id="searchText" binding="#{searchText}"
value="#{userData.searchReq}" autocomplete="off">
<p:ajax listener="#{userManagement.userTable.searchListener}"
event="keyup" update="userDataTable/>
</p:inputText>
This basically gives user to perform filtering on table when he types in inputText. But problem is user can type very fast. I want to stop next ajax call until current ajax call completed. How I can achieve that?
Since you're already using Primefaces, you can use the AutoComplete component to perform exactly what you're ttrying to do. The first example shows a basic autocomplete functionality using arraylists.... you may refer that.
Autocomplete also has the feature of delaying your hit to the server to compensate for fast typing - the queryDelay attribute. Refer to the User Guide for complete details.

How to update "nothing" in ajax events?

I have an ajax event triggered via some events in Primefaces JSF components.
I want this event to only process the values of the specific field that contains this event, but not to update anything, only process. Something like this:
<p:ajax event="itemSelect" process="#this" update="#none"/>
Is something like this possible to do?
Yes, #none is a valid keyword to say that nothing will be updated.
There is standard keywords which can be used in JSF2 in the render attribute:
If a literal is specified the identifiers must be space delimited. Any
of the keywords "#this", "#form", "#all", "#none" may be specified in
the identifier list.
PrimeFaces uses the update attribute for the same purpose with the almost the sames values.
Partial tree processing

Should immediate="true" never be used when dealing with an AJAXified JSF 2.0 component?

Should immediate="true" never be used when dealing with an AJAXified JSF 2.0 component?
The example might be:
If I want to implement a "Cancel" button on JSF 2.0 page where if the user hits "Cancel", no validations should run, should I set immediate="true" on the component if it is an ajaxified component or should specify that no components on the form should be processed? If so, what is the way to implement this functionality using the AJAXified features of the component and not the "old way" of using immediate="true"?
Indeed, the purpose of using immediate="true" on a cancel button has become useless since <f:ajax> which you can just set to execute="#this" (which is the default already) to skip the processing of all input components in the same form.
You may only run into problems when the form was already been submitted beforehand but failed due to a conversion/validation failure. If you hit the cancel button by ajax and render the form thereafter, the inputs would still be marked invalid and any changes in the model value are not reflected (you're probably doing a entity = new Entity(); or something in cancel action method to clear out the old values of the form). This problem does not happen when using a synchronous (non-ajax) request with immediate="true". This issue has actually nothing to do with immediate="true", but with the JSF lifecycle of ajax requests. You basically need to reset the invalidated state of the involved input components by calling EditableValueHolder#resetValue() on the components which are not included in the ajax execute, but are included in the ajax render. OmniFaces has a ResetInputAjaxActionListener for exactly this purpose.

JSF 2.0 values not being submitted

I’m struggling to get my bean to update with the new page values. I have two submit buttons on my page and I toggle which one displays based on a Boolean value for what mode my page is in. When my page is in update only (no validation) I show the submit button that has immediate=”true”. When the page is in process mode (validate) I show the submit button that does not have immediate=”true”.
The problem I’m running into is when I am in update mode (no validation) the values in the input fields are not being set in the bean. All I want to do when in this mode is save the page as is and exit. No validation is needed because the information on that page is not ready to process or “really use” if you will. That said, if I have my page in process mode (validate) then everything works as intended. Values are submitted and saved.
I’m not posting any code yet as there is nothing special about what I’m trying to do. I simply have a value binding that points to simple getter / setter. My bean is in #ViewScope.
I’ve tried using the examples by BalusC in his excellent blogspot post: debug-jsf-lifecycle.
Putting immediate=”true” on the input fields has no affect when clicking on the submit button with immediate="true". All and all though, the way I understand it is immediate=”true” on the UICommand is what tells the application to skip validation or not. Putting it on the input fields simply makes validation happen sooner. Am I missing something?
Any ideas? Any and all help with this is most appreciated!
App specifics:
JSF 2.0.3
Tomcat 6.0.14
The immediate="true" is not intented to disable validation. It's intented to either prioritize validation or to skip processing of the input altogether. See also the summary at the bottom of the article.
You need to disable validation by setting required="false", or <f:validator disabled="true">. Here's an example which assumes that you've a boolean process property which represents the form's state:
<h:inputText value="#{bean.value1}" required="#{bean.process}" />
<h:inputText value="#{bean.value2}" required="#{bean.process}">
<f:validator validatorId="someValidatorId" disabled="#{!bean.process}" />
</h:inputText>
...
This way the fields aren't required and won't be validated when process evaluates false.

Bypass JSF validation for a UIInput component

Here is the issue, JSF validation keeps flipping a field back to the last known value.
We are editing a page where the backing bean already has values.
(frequency = "weekly")
And we are required to show the default value of "please select.." even though that value will not pass validation (yes, I just want to leave the user on the page with the error message).
Is there any way to allow the user to choose "Select.." and not reset it to the last good value?
The user wont be allowed to save obviously, but we want to leave their invalid value selected.
User adds new object, selecting proper value from drop down
User saves successfully.
User Clicks "edit" and displays object with known value ("weekly")
User changes "weekly" to "select"
User clicks save
Validation message is shown (good) but frequency goes back to last value "weekly" (bad, I need it to stay on "Please select.." and let the user fix the drop down manually.
immediate="true" does not work on inputComponents, only commandComponents.
I recognize this, I've reported this more than one year ago as JSF issue 1299. This is still not resolved since it has a low priority. This is not specific to all UIInput components, but to MenuRenderer which is responsible for rendering the HTML <select> elements. All other HTML input elements behave as you would expect, the submitted value will be redisplayed (well, which is actually nothing as well).
Since you're already on JSF 2.0, I suggest you to solve this with a little help of f:ajax so that the dropdown won't be re-rendered and thus keeps its selection.
<h:selectOneMenu id="frequency" value="#{bean.frequency}" required="true">
<f:selectItems value="#{bean.frequencies}" />
<f:ajax render="frequencyMessage" />
</h:selectOneMenu>
<h:message id="frequencyMessage" for="frequency" />
The additional benefit is that the enduser has instant feedback and this is better for user experience.

Resources