Parameters from f:param not submitted with AJAX request when form enctype is multipart/form-data - ajax

I'm running Wildfly 8.2 and I'm using the JSF version bundled with it, 2.2.8-jbossorg-1.
I have the following facelet:
<h:form enctype="multipart/form-data">
<h:commandButton value="Submit">
<f:param name="myparam" value="true"/>
<f:ajax execute="#this" render="#this"/>
</h:commandButton>
</h:form>
When I press the submit button, several parameters are submitted, but not myparam. If I remove enctype="multipart/form-data" from the form, myparam=true is submitted just fine.
With or without enctype="multipart/form-data", if I remove f:ajax, myparam=true is always submitted.
Why is it working without enctype="multipart/form-data", but not with? And how can I get it to work?

This is a bug in Mojarra. I've just reported it as issue 3968.
For now, one work around is to pass them as EL method arguments instead.
<h:form enctype="multipart/form-data">
<h:commandButton value="Submit" action="#{bean.action(true)}">
<f:ajax execute="#this" render="#this"/>
</h:commandButton>
</h:form>
public void action(boolean myparam) {
// ...
}

Related

ajax does not work with multipart/form-data in jsf

I have the below code
<h:form enctype="multipart/form-data">
<p:panel id="panelEmployee">
<h:commandButton value="Go" action="#{employee.getFirstEmployee()}">
<f:ajax render="panelEmployee" execute="#form"/>
</h:commandButton>
<p:fileUpload value="#{employee.file}" mode="simple" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
</p:panel>
</h:form>
When i clicked on go button and if the form enctype is multipart/form-data then the first ajax call is ok, the second one gives this javascript error
SCRIPT5007: Unable to get value of the property 'contentWindow': object is null or undefined
Can anyone please suggest?
Thanks.

How to use ajax update content but without submit button

I have a jsf code like this. When user finish to input name and comment and press 'Enter', the content can show in 'Content........' this part.
<h:form id="all_comments">
Content........
</h:form>
<h:form id="submit_comment">
<h:inputText id="name_box" value="#{ManagedBean.user}"/>
<h:inputText id="content_box" value="#{ManagedBean.comment}" />
</h:form>
I want to use ajax finish it, and I try like this:
<h:form id="all_comments">
Content........
</h:form>
<h:form id="submit_comment">
<h:inputText id="name_box" value="#{ManagedBean.user}"/>
<h:inputText id="content_box" value="#{ManagedBean.content}">
<f:ajax event="keydown"
listener="#{ManagedBean.addComment}"
execute="comment_name_box comment_content_box"
rendered=":all_comments" />
</h:inputText>
</h:form>
But I failed, can I achieve that when user press 'Enter', data will be processed by ManagedBean, then using ajax update the page.
You've got some points missing:
You need to send an AJAX call only when enter key was pressed, so you need to bind <h:inputText> tag's onkeydown attribute with JavaScript code for that;
<f:ajax> attribute is render, not rendered;
submit_comment form should be rerendered as well, so that new data will be presented to the user, and the placeholders have to be refreshed in AJAX listener as well.
Here is the solution when you want to submit the second form on that event:
<h:form id="all_comments">
Content........
</h:form>
<h:form id="submit_comment">
<h:inputText id="name_box" value="#{managedBean.user}"/>
<h:inputText id="content_box" value="#{managedBean.content}"
onkeydown="return (event.keyCode == 13);">
<f:ajax event="keydown"
listener="#{managedBean.addComment}"
execute="#form"
render="#form :all_comments" />
</h:inputText>
</h:form>
with
public void addComment(AjaxBehaviorEvent abe) {
comments.add(new Comment(user, content));
user = "";
content = "";
}

Invoke aciton method with input value as parameter

I have this view:
<h:form id="carlin">
<h:outputText id="carlinInput" value="#{userBean.model.varAjax}"/>
<a class="btn" data-toggle="modal" href="#myModal" >Launch Modal</a>
</h:form>
And I have a modal dialog that shows another form:
<h:form>
<h:inputText value="#{userBean.model.varAjax}"/>
<h:commandLink action="#{userBean.processPage1()}" value="Ok">
<f:ajax render=":carlin:carlinInput" />
</h:commandLink>
</h:form>
I need to set the value typed on the <h:inputText> and pass it as a parameter to my <h:commandLink action="#{userBean.processPage1()}" value="OK">`
Here is my processPage1() method:
public void processPage1(String zip) {
this.model.varAjax = zip;
}
I have tried this:
<h:commandLink action="#{userBean.processPage1(userBean.model.varAjax)}" value="OK">
But it doesn't work. If I pass a hardcoded value, it works:
<h:commandLink action="#{userBean.processPage1('teste')}" value="OK">
But I need to pass what the user typed on that inputText to my action method. How can I achieve this?
This is not the right approach. You need to specify the client IDs of the input components which you need to process/execute by the execute attribute of <f:ajax>.
<h:form>
<h:inputText id="varAjax" value="#{userBean.model.varAjax}"/>
<h:commandLink action="#{userBean.processPage1}" value="Ok">
<f:ajax execute="varAjax" render=":carlin:carlinInput" />
</h:commandLink>
</h:form>
This way JSF will set the model value with the submitted value.
public void processPage1() {
System.out.println(model.getVarAjax()); // Look, JSF has already set it.
}
An alternative is to use execute="#form" which will process the entire form and this is what you usually need in standard ajaxified buttons.
<f:ajax execute="#form" render=":carlin:carlinInput" />
Note that componenent libraries like PrimeFaces and RichFaces have already made the #form the default execute attribute, so you don't need to explicitly specify it in their command components. In standard <f:ajax> it namely defaults to #this in command components which is indeed unintuitive.

understanding ajax execute behavior with datatable using jsf 2.0

i'm trying to use an search button which brings back the selected items (can be more than one) and it updates the datatable. Then i have a selectBooleanCheckbox next to each colomn, when user selects "n" items then presses the Select the checked Items it insert DB.
The code can be seen below:
<h:panelGrid columns="5">
<h:form>
<h:outputText value="Item Name"/>
<p:inputText value="#{StockController.itemName}"/>
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results"/>
</h:commandButton>
</h:form>
//The code sample below belongs to BalusC see the post here
<h:panelGroup id="results">
<h:form>
<h:dataTable value="#{bean.entities}" var="entity">
<h:column>
<h:selectBooleanCheckbox value="#{bean.checked[entity.id]}" />
</h:column>
...
</h:dataTable>
<h:commandButton value="Select the checked Items" action="#{StockController.insertDao}" >
<f:ajax execute="#form" render=":results"/>
</h:commandButton>
</h:form>
</h:panelGrid>
Now, i have read many blogs and Core javaServer Faces 3, i don't think there is logical error in ajax usage. I tested by removing each ajax then both works fine but whenever i try to use both of cummondButtons with ajax, the second one "Select the checked Items" does not even call the "StockController.insertDao" method.
Any help is appreciated.
Thanks all.
When you want to ajax-render content which in turn contains another form, then you need to include the ID of that form in the render attribute as well, otherwise the other form will lose its view state and nothing will be processed on submit.
<h:form>
...
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results :resultsForm" />
</h:commandButton>
</h:form>
<h:panelGroup id="results">
<h:form id="resultsForm">
...
</h:form>
</h:panelGroup>
If there's however nothing which goes outside <h:form> inside the same <h:panelGroup>, then you can just omit the <h:panelGroup> altogether and re-render the form directly.
<h:form>
...
<h:commandButton value="Search" action="#{StockController.Search}">
<f:ajax execute="#form" render=":results" />
</h:commandButton>
</h:form>
<h:form id="results">
...
</h:form>
This is related to JSF spec issue 790.
See also:
Communication in JSF2 - Ajax rendering of content which contains another form

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