Image not updated after clicking the ajax enabled command link - ajax

I am wrirting a captcha code for my jsf project. I have done almost everything but the problem is the refreshing og the image. I'd like to do it with ajax so that when I click the image, it be replaced by new one. But when I click it the image doesn't get updated. But it is updated after reloading the page.
<h:form>
<h:commandLink>
<h:graphicImage value="/captcha/test.png"
style="width:35mm;height:2cm;" />
<f:ajax render="#all" listener="#{captcha.recaptcha()}"></f:ajax>
</h:commandLink>
</h:form>
every time I click the image , it is changed on disk but not updated in the html page.
Thanx for any useful responses !

Try the following code using execute and render tags
<h:form>
<h:commandLink>
<h:graphicImage value="/captcha/test.png" style="width:35mm;height:2cm;" />
<f:ajax render="#form" execute="#form" listener="#{captcha.recaptcha()}" />
</h:commandLink>
</h:form>

You have need to use update attribute.
take a look-
<h:form id="form1">
<h:commandLink>
<h:graphicImage value="/captcha/test.png"
style="width:35mm;height:2cm;" id="img1"/>
<f:ajax render="#all" listener="#{captcha.recaptcha()}" update=":form1:img1"></f:ajax>
</h:commandLink>
</h:form>
Hope this will work

Related

h:commandButtoon and f:ajax does not render a h:dataTable if no action property is provided

I have the followig form with a dataTable and a edit section with input fields to manipulate the table data. I want to refresh the datatable after a the commandButton was clicked:
<f:ajax>
<h:panelGroup id="timesheet_panel">
<h:dataTable id="datatable"
value="#{timesheetController.myTimeSheet}" var="child">
......
<h:column>
<!-- update editor panel data -->
<h:commandLink
action="#{timesheetController.load(child.item['$uniqueid'])}">
<h:outputText value="#{message.edit}" />
<f:ajax
render=":#{component.parent.parent.parent.parent.clientId}:editorpanel" />
</h:commandLink>
</h:column>
</h:dataTable>
<!-- Editor -->
<h:panelGroup id="editor">
<h:inputText value="#{timesheetController.workitem.item['_category']}" />
<h:commandButton action="/mypage"
actionListener="#{timesheetController.process('10')}"
value="Update Tabledata">
<f:ajax render="datatable" />
</h:commandButton>
</h:panelGroup>
</h:panelGroup>
</f:ajax>
Note: I have a h:column with a h:commandLink to update the data shown in the editor panel below the table.
The question is: why is it necessary to provide the action property for the commandButton in the editor panel? If I did not provide the action property the f:ajax render="datatable" will not refresh the datatable.
So it seems to me that only a actionListener can be used here to update backend data. A action method will only work if the result of the action is equal to the current page.
Can anybody explain this behavior?
I am working on GlassFish 3.1.2
To refresh the table you need to put your bean in #ViewScoped at least. Ortherwise, your beed will be recreated after values are set so you'll get to same point.

Ajax not working in JSF

I don't know why Ajax is not working in my JSF files.Even I have a latest Mojarra which is 3.2.13 in my GlassFish. Here is my code
<h:head></h:head>
<h:body>
<h:panelGroup id="panel" rendered="#{chartBean.showCharts}">
<p:barChart id="basic" value="#{chartBean.categoryModel}"
legendPosition="ne" title="Basic Bar Chart" min="0" max="200"
style="height:300px" />
</h:panelGroup>
<h:commandButton value="Display Chart" action="#{chartBean.createCategoryModel}">
<f:ajax render="panel"/>
</h:commandButton>
</h:body>
Now when I run this code, button doesn't work.
Another thing, if I change my code like remove panel and just render on barchart like
<f:ajax render="basic"/> and placed it in <form>
then it throws NullPointerException. Because it render the chart and expect value from chartBean.categoryModel. Now AFAIK it should not be rendered because of ajax.
I am unable to understand ajax behavior in JSF. I also tried <f:ajax execute="#form" render="basic"> but it didn't work too. How is this caused and how can I solve it?
You cannot re-render a component that is not there on your page at the time you click the ajax button.
A simple solution would be to move the rendered attribute from the h:panelGroup to the p:barChart. Then the panelGroup will always be rendered and JSF finds it during your ajax request.
<h:panelGroup id="panel">
<p:barChart rendered="#{chartBean.showCharts}"
id="basic" value="#{chartBean.categoryModel}"
legendPosition="ne" title="Basic Bar Chart" min="0" max="200"
style="height:300px" />
</h:panelGroup>
<h:commandButton value="Display Chart" action="#{chartBean.createCategoryModel}">
<f:ajax render="panel"/>
</h:commandButton>

f:ajax does not update t:dataTable on complete

I have a JSF search command button and a tomahawk dataTable that showing the result from a search. When clicking on the command button, the dataTable should output the search result. Anyway, since I use the JSF Ajax, the dataTable doesn't show. I am just wondering whether JSF Ajax cause the problem?
Here is the problematic code that cause the table now render:
<h:commandButton id="search" value="#{msg.Label_Search}" action="#{theBean.doSearch}">
<f:ajax render="searchStatus" execute="#form" />
</h:commandButton>
<h:outputText id="searchStatus" value="Loading data now..." rendered="#{theBean.searchingNow}" />
<h:panelGroup id="searchResultTable">
<t:dataTable ... />
</h:panelGroup>
*Take note on this. If the ajax code were removed. It is working fine.
You're only updating the searchStatus, not the searchResultTable when the ajax request completes. So the enduser will indeed never see a visual change in the HTML representation of the searchResultTable.
Fix the <f:ajax render> accordingly so that the searchResultTable is also really updated:
<f:ajax render="searchStatus searchResultTable" execute="#form" />

JSF2: Form ajax action makes another form's view state to be lost

I have a simple page consisting of two forms. They cannot be displayed simultaneously (one toggles the other). Here is the code:
<h:body>
<ui:composition template="/elements/templateWithMenu.xhtml">
<ui:define name="content">
<p:dialog id="question1DialogId" widgetVar="question1Dialog" resizable="false" closable="false" visible="true">
<h:panelGroup id="questionStep1Group">
<h:form id="questionStep1Form" rendered="#{newPoll2.displayQuestionStep1}">
<h:commandLink value="next" action="#{newPoll2.questionStep1Completed()}" class="btn" >
<f:ajax execute="#form" render=":questionStep2Form :questionStep1Group :questionStep2Group"/>
</h:commandLink>
</h:form>
</h:panelGroup>
<h:panelGroup id="questionStep2Group">
<h:form id="questionStep2Form" rendered="#{newPoll2.displayQuestionStep2}">
<h:commandLink value="cancel" action="#{newPoll2.questionStep2Cancelled()}" class="btn" >
<f:ajax execute="#form" render=":questionStep1Form :questionStep1Group :questionStep2Group" />
</h:commandLink>
</h:form>
</h:panelGroup>
</p:dialog>
</ui:define>
</ui:composition>
</h:body>
questionStep1Completed() and questionStep2Cancelled() simply toggle the booleans used in rendered attribute.
The problem is with the view states. When the page is first loaded, clicking on "next" will work, and it will be replaced with the "cancel" link. But when I click on the "cancel" link, it needs to be clicked twice in order for it to be replaced with with the "next" link. I can see that the first click makes the request with no view state, and the second (successful) one makes a request with it.
I saw this question, and this link, and as you can see, I've added form ids in the render attribute, but it still doesn't work. Any ideas?
Thanks
You're conditionally rendering the forms themselves and hence the other form isn't physically available in the HTML DOM tree at the moment the ajax request is been prepared. If you wrap the form's content in another <h:panelGroup> and move the rendered attribute to there, then it ought to work.

JSF form post with AJAX

I want the following form to use AJAX. So the comments are shown after clicking the command button and without reloading the page. What needs to be changed, using Java Server Faces 2.0?
Functionality: This form provides an inputText to define a topic. After pressing the commandButton, it is searched for comments regarding this topic. Comments are shown in a dataTable, if there are any. Otherwise Empty is shown.
<h:form id="myForm">
<h:outputLabel value="Topic:" for="topic" />
<h:inputText id="topic" value="#{commentManager.topic}" />
<h:commandButton value="read" action="#{commentManager.findByTopic}" />
<h:panelGroup rendered="#{empty commentManager.comments}">
<h:outputText value="Empty" />
</h:panelGroup>
<h:dataTable
id="comments"
value="#{commentManager.comments}"
var="comment"
rendered="#{not empty commentManager.comments}"
>
<h:column>
<h:outputText value="#{comment.content}"/>
</h:column>
</h:dataTable>
</h:form>
You need to tell the command button to use Ajax instead. It's as simple as nesting a <f:ajax> tag inside it. You need to instruct it to submit the whole form by execute="#form" and to render the element with ID comments by render="comments".
<h:commandButton value="read" action="#{commentManager.findByTopic}">
<f:ajax execute="#form" render="comments" />
</h:commandButton>
Don't forget to ensure that you've a <h:head> instead of a <head> in the master template so that the necessary JSF ajax JavaScripts will be auto-included.
<h:head>
...
</h:head>
Also, the element with ID comments needs to be already rendered to the client side by JSF in order to be able to be updated (re-rendered) by JavaScript/Ajax again. So best is to put the <h:dataTable> in a <h:panelGroup> with that ID.
<h:panelGroup id="comments">
<h:dataTable rendered="#{not empty commentManager.comments}">
...
</h:dataTable>
</h:panelGroup>
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
You need to modify your button:
<h:commandButton value="read" action="#{commentManager.findByTopic}">
<f:ajax render="comments" />
</h:commandButton>
This means, when the button is clicked, the action is executed, and the dataTable will be rendered and updated. This only works if the backing bean is at least view-scoped.

Resources