ADF toggle required attribute from checkbox - oracle-adf

In my jsff file I have some input fields which are required by default. Now we want a way to toggle the required attribute using a checkbox. Several solutions have been tested, one of them like this:
<af:selectBooleanCheckbox id="sbc1" label="myLabel" value="#{sessionBean.skipInput}" autoSubmit="true"/>
<af:selectOneChoice label="myLabel" id="soc1" partialTriggers="sbc1" value="#{sessionScope.sessionBean.someValue}" required="#{!sessionBean.skipInput}">
<f:selectItems value="#{applicationScope.applicationBean.myItems}" id="si1"/>
</af:selectOneChoice>
When I check the checkbox to set the required attribute to false, the selectOneChoice will be red indicating that no value has been selected in the drowdown. How can I prevent this and simply remove the required attribute from the dropdown?

Your solution is the right approach, but the issue is that ADF can not change the checkbox value as long as the required constraint of the choice box is not fulfilled. So you will always get the "A selection is required" message and the new value of the check box will not be updated on the server as long as there is nothing selected in the choice box.
To solve this, you need to set the immediate property on the checkbox to true to skip validation, and add a valueChangeListener to handle the changes of the checkbox and manually call the render response phase:
<af:selectBooleanCheckbox id="sbc1" label="Skip Choice"
value="#{sessionBean.skipInput}"
autoSubmit="true"
immediate="true"
valueChangeListener="#{sessionBean.toggleSkipInput}"/>
public class SessionBean {
...
public void toggleSkipInput(ValueChangeEvent vce) {
setSkipInput(Boolean.TRUE.equals(vce.getNewValue()));
FacesContext.getCurrentInstance().renderResponse();
}
}
For more information, see
http://docs.oracle.com/cd/E23943_01/web.1111/b31973/af_lifecycle.htm#CIAHCFJF
https://blogs.oracle.com/jdevotnharvest/entry/partial_submit_vs_auto_submit

Related

SetPropertyListener Problem when using with af:commandButton in oracle adf

Hi I want to set a pageflowScope using setPropertyListener and when I use that in h:commandButton it works but when I use that in af:commandButton and when I hit the button it does not work but the second time I hit the button it works ... when I hit the button at the first time it should put the method result into a pageflowScope variable but it always do that in the second click ... I don't know why
here is my code
<af:panelFormLayout id="pfl2">
<af:inputText value="#{bindings.usrname.inputValue}" label="نام کاربری"
required="#{bindings.usrname.hints.mandatory}"
columns="#{bindings.usrname.hints.displayWidth}"
maximumLength="#{bindings.usrname.hints.precision}"
shortDesc="#{bindings.usrname.hints.tooltip}" id="it1">
<f:validator binding="#{bindings.usrname.validator}"/>
</af:inputText>
<af:inputText value="#{bindings.passwrd.inputValue}" label="رمزعبور"
required="#{bindings.passwrd.hints.mandatory}"
columns="#{bindings.passwrd.hints.displayWidth}"
maximumLength="#{bindings.passwrd.hints.precision}"
shortDesc="#{bindings.passwrd.hints.tooltip}" id="it2">
<f:validator binding="#{bindings.passwrd.validator}"/>
</af:inputText>
<af:button actionListener="#{bindings.execPLSQLProcedure.execute}" text="execPLSQLProcedure"
disabled="#{!bindings.execPLSQLProcedure.enabled}" id="b1">
<af:setPropertyListener from="#{bindings['return'].inputValue}"
to="#{pageFlowScope.Result}" type="action"/>
</af:button>
</af:panelFormLayout>
how can I fix it or please tell me an alternative way ...thanks
If you have to click two times for the action to trigger it is because on your first click your form hit data validation issues.
1) If you don't see it, you first need to add a partialTrigger to your button :
<af:commandButton partialTriggers="pfl2" partialSubmit="true" actionListener="#{bindings.execPLSQLProcedure.execute}" text="execPLSQLProcedure" disabled="#{!bindings.execPLSQLProcedure.enabled}" id="b1" >
<af:setPropertyListener from="#{bindings['return'].inputValue}" to="#{pageFlowScope.Result}" type="action"/>
</af:button>
whether the action should be done through a partial page submit or
not. Default is false: no partial page submit; the full page will be
refreshed. When set to true, the full page will not be refreshed. To
re-render specific components on your page in response to the partial
page submit, you have to tell ADF Faces. The easiest way to do this is
with the partialTriggers attribute.
2) If you want to bypass validation you can also add an immediate="true" attribute. In your case it doesn't look like you should as you want to validate the password length and requirement. See 1)
<af:commandButton immediate="true" partialTriggers="pfl2" partialSubmit="true" actionListener="#{bindings.execPLSQLProcedure.execute}" text="execPLSQLProcedure" disabled="#{!bindings.execPLSQLProcedure.enabled}" id="b1" >
<af:setPropertyListener from="#{bindings['return'].inputValue}" to="#{pageFlowScope.Result}" type="action"/>
</af:button>
see docs : https://docs.oracle.com/cd/E12839_01/apirefs.1111/e12419/tagdoc/af_commandButton.html
whether data validation - client-side or server-side - will be skipped
when events are generated by this component. When immediate is true,
the command's action and ActionListeners, including the default
ActionListener provided by the JavaServer Faces implementation, will
be executed during Apply Request Values phase of the request
processing lifecycle, rather than waiting until the Invoke Application
phase. Because validation runs during Process Validators (after Apply
Request Values, but before Invoke Application), setting immediate to
true will skip validation.

reduxform - how to handle change on a radio button using a single handleChange function

I am using redux-form in my Laravel project (implementing React 15.4.2) and the form I have includes several radio buttons. I need a handleChange function in order for these to remember what is checked (if they are changed from a previous value or selected for the first time) but I don't want to have to write a separate one for each radio button, or implement a huge if else set of rules to handle each one.
Here's one of my fields (just the 'yes' value):
<input type="radio" onChange={this.handleChange.bind(this, 'maintain_licence', 'yes')} checked={maintain_licence.value === 'yes'} id="maintain-licence-yes" value="yes" name="maintain_licence" /><span>Yes</span>
And this is what I have for a single radio button on change, based on the radio button called maintain_licence being interacted with:
handleChange(fieldName, value) {
if(fieldName === 'maintain_licence') {
this.props.fields.maintain_licence.onChange(value);
}
}
This works fine - however, since I have about 20 radios in my form, I can imagine this function getting rather long. Ideally, I'd want something similar to:
handleChange(fieldName, value) {
this.props.fields.fieldName.onChange(value);
}
But as it's trying to find a field actually named 'fieldName' it throws an error stating that it cannot run onChange on an undefined value.
Basically I just need to find a way of using a single function to handle the changes on all radio buttons but I don't know how to do this.
You could use property accessors to get the property you want. Something like:
handleChange(fieldName, value) {
this.props.fields[fieldName].onChange(value);
}
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors

adf selectOneChoice valueChangeListener not firing

My valueChangeListener for SelectOneChoice is not getting invoked when I am trying to select a value in the dropdown. It is invoked only when I click on the Blank Item in the dropdown (which we configure in ListOfValues).
On some research I have learnt that in your valueChangeListener, we must add
vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
as our first line. But It is still not getting invoked on selection of any other value apart from null.
Code for my SelectOneChoice
<af:selectOneChoice value="#{bindings.Prefix.inputValue}"
label="#{bindings.Prefix.label}"
shortDesc="#{bindings.Prefix.hints.tooltip}"
id="soc3"
partialTriggers="formatIdId"
visible="#{bindings.Prefix.hints.visible}"
binding="#{backingBeanScope.CreateItemBackingBean.prefixField}"
required="#{bindings.ItemNumberType.attributeValue eq 'VPLU'}"
showRequired="#{bindings.Prefix.hints.mandatory}"
validator="#{backingBeanScope.CreateItemBackingBean.onValidatePrefix}"
autoSubmit="true"
valueChangeListener="#{backingBeanScope.CreateItemBackingBean.onChangePrefix}">
<f:selectItems value="#{bindings.Prefix.items}" id="si3"/>
<af:convertNumber groupingUsed="false"
pattern="#{bindings.Prefix.format}"/>
</af:selectOneChoice>
Code for my ValueChangeListener
public void onChangePrefix(ValueChangeEvent vce) {
vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
System.out.println("vce.getOldValue()"+vce.getOldValue());
System.out.println("vce.getNewValue()"+vce.getNewValue());
System.out.println("I am in changed prefix");
}
valueChangeListener will fire only when you submit form. You can use any submit action for it or just turn on autosubmit property on component.
If you need to catch selection event without actually submitting data, you should use clientListener and handle it with javascript functions.
It may be your required tag preventing the valueChangeListener from firing.
required="#{bindings.ItemNumberType.attributeValue eq 'VPLU'}"
If "required" returns true, valueChangeListener won't be executed.
Also, remove "showRequired" attribute completely. Is not only not necessary, but is confusing because it has a different condition than "required" attribute.
Try a bit of debugging and set required="false".You can also remove "validator", "visible", see if it works without them, then add them back one by one.

Why submit called from inside of panelCollection doesn't submit data changes from the rest of page

My application is build using Oracle ADF 11gR1 (JDeveloper 11.1.1.7.0), and I have a problem with data submitted by commandLink placed inside of panelCollection.
I have following page fragment structure:
<af:panelAccordion id="pa1">
<af:showDetailItem id="sdi1">
<af:panelFormLayout id="panelFormLayout1">
<af:inputText value="#{bindings.C11.inputValue}" id="it34" />
<af:inputText value="#{bindings.N04.inputValue}" id="it32" />
<af:selectOneChoice value="#{bindings.N13.inputValue}" id="soc4" autoSubmit="true" >
<f:selectItems value="#{bindings.N13.items}" id="si4"/>
</af:selectOneChoice>
...
</af:panelFormLayout>
<af:showDetailItem>
...
<af:showDetailItem id="sdi4">
<af:panelCollection id="pc2">
<af:table value="#{bindings.Table.collectionModel}"
var="row" rows="#{bindings.Table.rangeSize}"
filterModel="#{bindings.Table.queryDescriptor}"
queryListener="#{bindings.Table.processQuery}"
varStatus="vs"
selectedRowKeys="#{bindings.Table.collectionModel.selectedRow}"
selectionListener="#{bindings.Table.collectionModel.makeCurrent}"
rowSelection="single" id="t2">
<af:column id="c19">
<af:commandLink id="cl1" textAndAccessKey="#{row.bindings.C0.attributeValue}" actionListener="#{pageFlowScope.Bean.handle}"/>
</af:column>
<af:column id="c17">
<af:inputText value="#{row.bindings.C1.inputValue}" id="it17" />
</af:column>
<af:column id="c16">
<af:inputText value="#{row.bindings.C2.inputValue}" id="it42" />
</af:column>
...
</af:table>
</af:panelCollection>
</af:showDetailItem>
</af:panelAccordion>
CommandLink (id="cl1") placed in table column c19 has defined actionListener. Method of this performs operation which base on data given in selected row in table and in controls from panelFormLayout above.
When commandLink is pressed, and actionListener method fired, I see (in the results and in debug) that data changes from panelFormLayout are not submitted, except the ones which has autosubmit set to true. But if I place the same commandLink outside of panelCollection all data are submitted.
My question is how I can force submit of data from whole pageFragment when actionListener is fired from panelCollection inside?
Autosubmit on all controls outside of panelCollection doesn't seem to be a good solution because of many uncessary POST requests.
The reason for this behaviour is the had optimised lifecycle which is used for some components including table and panelAccordion. His means that the values are only submitted inside the boundary of the component. In your case it means that only the showDetailItem is submitted.
To submit the form to you have to set the id if the link as partial trigger to the form.
A detailed description can be found in this presentation http://de.slideshare.net/mobile/stevendavelaar/18-invaluable-lessons-about-adfjsf-interaction in lesson 17
Perhaps try putting the panel collection inside a subform?

Uncheck selectBooleanCheckbox just after user checked it if condition true

excuse my poor English ;)
I have tabView with 2 tab that have alternative rendered by a selectBooleanCheckbox so I did:
<p:selectBooleanCheckbox id="check"
value="#{prestationComponent.prestation.condUnique}">
<p:ajax event="change" update="tabV"/>
</p:selectBooleanCheckbox>
<p:tabView id="tabV" orientation="top">
<p:tab title="#{refMessage_fr.taxe_condunique_title}"
rendered="#{prestationComponent.prestation.condUnique}">
</p:tab>
<p:tab title="#{refMessage_fr.taxe_formullelist_title}"
rendered="#{!prestationComponent.prestation.condUnique}">
</p:tab>
this work perfectly
In one of the tow tab, i have a list, so i want to let this tab active if the list has more than 1 element so i changed my selectBooleanCheckbox to this:
<p:selectBooleanCheckbox id="check"
value="#{prestationComponent.prestation.condUnique}"
onchange="if(#{prestationComponent.addPrestationFormulesList.size()>1}) {PF('messageDialogue').show();#{prestationComponent.prestation.setCondUnique(false)};}">
<p:ajax event="change" update="tabV,check"/>
</p:selectBooleanCheckbox>
and this work with the tab with the list, it's sty active but the selectBooleanCheckbox stay checked
so I want to selectBooleanCheckbox stay unchecked when i checked it if(#{prestationComponent.addPrestationFormulesList.size()>1})
thank you.
==========================================EDIT====================================
I found the solution, i create a function in the managed bean that test the condition and set the value of check box to false if condition is true and i call it in the listener of the ajax event of the check box
<p:selectBooleanCheckbox id="check"
value="#{prestationComponent.prestation.condUnique}"
onchange="if(#{prestationComponent.addPrestationFormulesList.size()>1}) PF('messageDialogue').show();">
<p:ajax listener="#{prestationComponent.checkBoxListner()}" event="change" update="tabV,check"/>
</p:selectBooleanCheckbox>
I found the solution, i create a function in the managed bean that test the condition and set the value of check box to false if condition is true and i call it in the listener of the ajax event of the check box
<p:selectBooleanCheckbox id="check"
value="#{prestationComponent.prestation.condUnique}"
onchange="if(#{prestationComponent.addPrestationFormulesList.size()>1}) PF('messageDialogue').show();">
<p:ajax listener="#{prestationComponent.checkBoxListner()}" event="change" update="tabV,check"/>
</p:selectBooleanCheckbox>

Resources