I have a page with several conditions and when I try to open selectCheckBoxMenu I want the method to be called from server but I get something strange. List with my items doesn't show and twitches all times.
<p:selectCheckboxMenu id="scroll"
value="#{adminManageTournamentController.teamListSelected}"
label="#{msg.teams}" filter="true" filterText="Filter"
filterMatchMode="startsWith" panelStyle="width:auto"
onShow="sourceFilterCommand();">
<f:selectItems value="#{adminManageTournamentController.teamList}"
var="team" itemLabel="#{team.name}"
itemValue="#{team.id}"/>
<p:column>
#{team.name}
</p:column>
<p:remoteCommand name="sourceFilterCommand" update="scroll"
actionListener="#{adminManageTournamentController.selectTeamsByConditions}"/>
</p:selectCheckboxMenu>
Did I choose correct way for decision? How to get rid of the twitching list?
Probably reason of those twitches is endless loop. When your p:selectCheckboxMenu is shown remote command is called, and p:selectCheckboxMenu is updated and it is shown again and remote command is called again... And this never ends. It is strange that you are updating component in onShow. You probably should do this in moment when conditions for updating are changed, this is not place where you should update component. If this p:selectCheckboxMenu is for example dependent on some p:selectOneMenu update it when value of p:selectOneMenu is changed.
Related
I want to get the selected value in the SelectOneRadio in Oracle ADF jsff.
The problem is that i dont want to refer each and every click to a ValueChangeListener.
That creates a lot of server load.
is there any way to get the value selected in the radio button and display it in an output text by partially updating it and all..
I have tried multiple Blogs all referring to use of BackingBean.
Thanks in advance
You can create a binding to that component, and get it's value within the same method where the bind is. For example:
<af:selectOneRadio value="#{bindings.Deptno.inputValue}" label="Select Department"
required="true" shortDesc="#{bindings.Deptno.hints.tooltip}"
id="soc1" autoSubmit="true" binding="#{managedBeanName.selectOneRadio}>
<f:selectItems value="#{bindings.Deptno.items}" id="si1"/>
and then the bean should look like this:
import oracle.adf.view.rich.component.rich.input.RichSelectOneRadio
public class ManagedBeanName{
private RichSelectOneRadio radio;
//getters/setters for 'radio' here
public void printValue(){
System.out.println(radio.getValue());
}
The last thing would be the call to this method each time YOU want to print/get the selected value.
A call to a ValueChangeListener should not overload the server.
Try
<af:selectOneRadio value="#{bean.aValue}" id="sor1" autoSubmit="true">
<f:selectItem itemLabel="Option1" itemValue="1"/>
<f:selectItem itemLabel="Option2" itemValue="2"/>
<f:selectItem itemLabel="Option3" itemValue="3"/>
</af:selectOneRadio>
<af:outputText value="#{bean.aValue}" partialTriggers="sor1"/>
No ValueChangeListener but still a trip on the server. You can't avoid that. ADF is based on JSF and this is the way the technology works.
I am using a <h:selectBooleanCheckbox> in the facet header of a DataTable. All the rows content for that <h:column> DataTable are <h:selectBooleanCheckbox>. The rows are getting selected perfectly the way I wanted. Below is the code I used:
<h:form>
<h:dataTable
value="#{employeeService.employeeList }"
var="empl"
binding="#{employeeService.dataTablebinding }">
......
......
......
<h:column>
<f:facet name="header">
<h:selectBooleanCheckbox id="chkBoxAll" value="#{employeeService.checkedHdr }" valueChangeListener="#{employeeService.checkAll }" onclick="submit()"></h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox id="tableChkBox" value="#{empl.checked }" valueChangeListener="#{employeeService.getCheckChanged }" onclick="submit()"></h:selectBooleanCheckbox>
</h:column>
</h:dataTable>
This is the code for the ValueChangeListener:
public void checkAll(ValueChangeEvent event){
if(isInvokeApplicationPhase(event)){
Iterator<Employee> empl = employeeList.iterator();
while(empl.hasNext()){
Employee emp = empl.next();
emp.setChecked(checkedHdr);
}
}
}
This is the isInvokeApplicationPhase utility I added up for making this code work (referred the solution suggested by BalusC in this link: JSF 1.2: valueChangeListener event not returning newly selected value ):
public boolean isInvokeApplicationPhase(FacesEvent event){
if(event.getPhaseId() != PhaseId.INVOKE_APPLICATION){
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return false;
}
return true;
}
Now my Question:
What is the use of that isInvokeApplicationPhase check in the ValueChangeListener method? If I comment out this check then it does not work - WHY? I thought I have understood the JSF life cycle properly but this behavior proves that I have not :(
Kindly let me know the explanation based on the JSF life cycle phases.
The value change listener runs during validations phase and is intented to hook on the value change event. I.e. the newly submitted value is different from the original model value.
The validations phase runs before update model values phase, wherein JSF set all submitted, converted and validated values in the model (the backing bean's properties). So when you attempt to change the model value of a different field in the value change listener, then it would be overridden during the update model values phase.
This particular trick re-queues the value change event to the invoke application phase, which runs after update model values phase. So when you attempt to change the model value of a different field, then it won't be overriden.
In a nutshell: the validations phase is simply the wrong moment to manually manipulate the model values and the invoke application phase is the right moment to manually manipulate the model values.
Actually, the value change event is being abused here. You should rather be using an action event here, but this was not available for inputs in JSF 1.x. This was only available in JSF 2.x in flavor of <f:ajax listener>.
See also:
When to use valueChangeListener or f:ajax listener?
Setter not called for input text
I have a weird problem, which is probably a bug in IE8, but I am seeking for a workaround.
Description of the UI:
I have a form that displays many rows. When the user enter a value in one of the row, it will perform some basic validation and then it will add a "delete" link next to it. (the goal is to delete the entered row).
Description of the problem:
User enter some data
User switch window (go in any other IE tab or even switch to another software, like notepad)
come back to IE, and enter another row
--> The "onchange" event is not fired when the user clicks elsewhere.
This works fine with Chrome or other browsers (the event is fired normally even if we switch window).
Workaround
- before switching to another software, if the user just press tab or click in another cell, the "onchange" event works as expected.
Anybody got a similar problem, or know another method that would do simiar behavior and work in all browsers?
Here is the code:
<rich:column>
<h:inputText id="batchSaid" value="#{currentBatch.batchSaid}" onkeypress="enableValidateitemsButton(this);"
onblur="validateCase(this,'MYVALUE');enableValidateitemsButton(this);">
<a4j:support event="onchange" process="batchAdd" action="#{itemsPageFormImpl.enableValidateBtnDisableActivateBtn(currentBatch, tRowId)}"
reRender="deleteBatchLink, deleteBatchLinkId" ajaxSingle="true"/>
</h:inputText>
</rich:column>
<rich:column id="deleteBatchLinkId">
<div align="right">
<a4j:commandLink id="deleteBatchLink" style="font-weight:bold;" value="Delete" action="#{itemsPageFormImpl.deletBatch}" reRender="batchdataTable"
rendered="#{currentBatch.showBatchRowDelBtn}" ajaxSingle="true">
<f:setPropertyActionListener target="#{itemsPageFormImpl.deleteBatchId}" value="#{currentBatch.batchId}" />
</a4j:commandLink>
</div>
</rich:column>
The problem is with the deleteBatchLink not being displayed.
We finally never found a solution to this. The users uses the workaround.
I have a an a4j:outputPanel that is rendered based on some boolean condition:
<a4j:outputPanel id="someDisplayRegion" rendered="#{doc.ready && someClass.someBooleanMethod}">
// bunch of stuff //
</a4j:outputPanel>
Then on the same .xhtml page, I have a drop-down menu and selecting one of its options should reRender the above region:
<rich:dropDownMenu>
<f:facet name="label">
<a4j:commandLink styleClass="btn-pulldown">
<span><h:outputText value="Export"></h:outputText></span>
<span class="opener"></span>
</a4j:commandLink>
</f:facet>
<rich:menuItem submitMode="none">
<s:link
rendered="#{someOtherBooleanMethod}"
value="#exportDoc"
action="#{runSomething.exportDoc()}"
reRender="someDisplayRegion"
target="downloadfile"
><s:conversationId /></s:link>
</rich:menuItem>
</rich:dropDownMenu>
However, when I click on the menu item from the drop-down menu, it does not go into someClass.someBooleanMethod and thus, does not re-render someDisplayRegion. Am I doing something wrong?
Consider this point of the RichFaces documentation:
As with most Ajax frameworks, you should not attempt to append or
delete elements on a page using RichFaces Ajax, but should instead
replace them. As such, elements that are rendered conditionally should
not be targeted in the render attributes for Ajax controls. For
successful updates, an element with the same identifier as in the
response must exist on the page. If it is necessary to append code to
a page, include a placeholder for it (an empty element).
So add a wrapper around your outputPanel and target the wrapper in the reRender attribute.
<a4j:outputPanel id="wrapper">
<a4j:outputPanel id="someDisplayRegion" rendered="#{doc.ready && someClass.someBooleanMethod}">
// bunch of stuff //
</a4j:outputPanel>
</a4j:outputPanel>
<s:link reRender="wrapper" [...] />
s:link doesn't have reRender attribute, it's only available on RichFaces components.
rich:menuItem and s:link aren't the best of friends. (especially not in earlier version of RichFaces).
Is there a specific reason why you want to use s:link here ?
Putting the action and the reRender on the menuItem itself should work fine.
I don't understand why you think clicking on the menu item should go into someClass.someBooleanMethod and not into runSomething.exportDoc(). At what point are doc.ready and someClass.someBooleanMethod being set to true? You might put a debugging statement in your code that verifies these are being set to true. If they are set to true and your a4j:outputPanel is still not rendering then you have a problem. I use the s:link as you do here and it works, but I remember having to fiddle with it. Make sure the action fired in the s:link returns a String. "actions" have to return strings that can be used for navigation though in my case the page navigates to itself (like yours).
Found strange problem, possibly bug.
I have 2 identical web-pages with Richfaces:suggestionbox.
On the first one my suggestionBox is doing well, everything works fine, but on another one i have some problems. SuggestionBox doesn't show my suggestions. In logs i have something like this:
WARNING: No component found to process as 'ajaxSingle' for clientId remains-form:konta-suggest
2010.1.9 12:02:29 org.ajax4jsf.component.AjaxViewRoot processPhase
Any conclusions?
UPD:
<h:inputText value="#{repobean.kont}" id="kont" label="Payer" style="width:230px;"/>
<rich:suggestionbox onobjectchange="printObjectsSelected(#{rich:element('konta-id')}, #{rich:component('konta-suggest')}, 'id');" usingSuggestObjects="true" width="230" var="result" fetchValue="#{result.kont}" suggestionAction="#{kontabean.suggest}" id="konta-suggest" for="kont">
<h:column>
<h:outputText value="#{result.kont}"/>
</h:column>
<h:column>
<h:outputText value="#{result.kontName}"/>
</h:column>
</rich:suggestionbox>
<h:inputHidden id="konta-id" value="#{repobean.kontId}" />
Javascript inside onobjectchange is a function which prints id into konta-id.
The code of jsp on the second page is copy-pasted from the first page.
I know, the question is 5 years old, but we had this same error (with different components)
In our case we have changed the outer ui:repeat to an a4j:repeat.
After that, our components worked as expected.
What you can do, when you encounter Ajax problems, is to add the <a4j:log> component:
<a4j:log popup="false"/>
This will create a box in your page with all the Ajax logs from Richfaces. Eventually, you can set popup="true" and then display the popup by Ctrl + Shift + L
There are many logs in this panel, but generally the important things to look at is the WARN or ERROR messages.
Other concern about your error message: it is talking about some ajaxSingle processing. In your JSF code, you have no ajaxSingle attribute defined. When does this error happens? When you start typing some characters in your inputText component?
Isn't there any conditional rendering (rendered="#{some expression}") around this input and suggestion components? Or an iteration?
Does .suggest() action get invoked before this error?
Situations like you've described happen when an action-related (causing) component is within a conditional render (or an iteration) which does not allow a component to be created on RestoreView phase. Then action is not called at all and component-id is not found in the component tree.
Example: if you have something like this:
<h:panelGroup rendered="#{not empty myBean.valueSetInActionHandler}">
<h:commandLink id="action1" action="#{myBean.callOtherAction" value="appears after action"/>
</h:panelGroup>
<h:commandLink id="action2" action="#{myBean.setValueInActionHandler}" value="display button above"/>
First render - only one, second button is rendered. If setValueInActionHandler sets some value and displays the same page - first button ("appears after action") will get rendered too. But clicking it won't fire a callOtherAction - because on second request, during RestorePhase valueInActionHandler is empty again, so action1 will not be available...
Hope I managed to make myself clear :)
I think a4j taglib is missing on the page.