Howto skip Form validation for a Reload
Hi,
we have a simple page where i can edit my applications users.
The users are listet by a datatable and every row holds a radiobutton with the users id. After clicking on one of this buttons the selected users data should be loaded into my form. All worked well ... until i introduced validation in my form (some required="true" and one email validation). PS: I磎 using MyFaces + Tomahawk.
When I click on my radiobutton, the form gets submitted and validation fails when the form is empty. Due to this validation errors my INVOCE_APPLICATION phase is never called --> my business logic where i load the users data is never executed.
How can i solve this problem?
My idea was to add a phase listener after PROCESS_VALIDATIONS phase where i search for a special named hidden field (e.g. id="do_not_validate") an set the valid state of all invalid components to true (valid) if this field exists. But this does not work at all.
Here my code withoud the hidden field thing:
One interesting point is, that input.setValid( true ) seems not to work, but input.setRequired(false) does it磗 job.
package de.example.jsf.utils;
import java.util.Iterator;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import org.apache.log4j.Logger;
publicclass SkipValidationListenerimplements PhaseListener
{
final Loggerlog= Logger.getLogger( this.getClass() );
public SkipValidationListener()
{
}
publicvoid beforePhase( PhaseEvent pe )
{
}
publicvoid afterPhase( PhaseEvent pe )
{
log.info("Try to skip all validation" );
FacesContext cx = JSFUtil.getFacesContext();
UIViewRoot root = cx.getViewRoot();
Iterator it = cx.getClientIdsWithMessages();
while ( it.hasNext() )
{
String id = (String) it.next();
log.info("clientID: " + id );
UIComponent c = root.findComponent( id );
UIInput input = (UIInput) c;
if ( input.isValid() )
log.info("Status valid (" + id +")" );
else
log.info("Status invalid (" + id +")" );
input.setValid(true );
input.saveState( cx );
}
}
public PhaseId getPhaseId()
{
return PhaseId.PROCESS_VALIDATIONS;
}
}
Best regards
[3919 byte] By [
zzza] at [2007-11-27 9:47:57]

# 4
Oh, sorry. My fault.
But now i have another problem:
because the selectoneradio tag has no actionListener property (because it磗 no action control) i implemented a invisible commandbutton. When clicking on the radiobutton i call the buttons javascript click() method to simulate a buttonclick and call its actionlistener method. But the model is not updated when i use immediate="true" on the button.
How can i get the value of the radiobuttons?
<div style="visibility: hidden;position: absolute;z-index: 1000;">
<t:commandButton immediate="true" id="btnLoad" actionListener="#{BenutzerkontenBacking.loadBenutzer}" value="Laden"></t:commandButton>
</div>
.
.<some code>
.
<t:selectOneRadio id="radio" forceId="true" forceIdIndex="false" value="#{BenutzerkontenBacking.bnId}" onmouseup="(document.getElementById('mainfrm:content:btnLoad')).click();">
<f:selectItem itemValue="#{crow.bnId}" itemLabel=""/>
</t:selectOneRadio>
zzza at 2007-7-13 0:01:09 >

# 5
> Oh, sorry. My fault.
>
> But now i have another problem:
>
> because the selectoneradio tag has no actionListener
> property (because it磗 no action control) i
> implemented a invisible commandbutton. When clicking
> on the radiobutton i call the buttons javascript
> click() method to simulate a buttonclick and call its
> actionlistener method. But the model is not updated
> when i use immediate="true" on the button.
> How can i get the value of the radiobuttons?
Do don't need the value of the radio button, correct? What you really want is the bean that corresponds to the row that was clicked, correct? The dataTable component was designed to help you with this. Google for BalusC's dataTable component page for details.
# 6
Hi,
this page describes my problem (see the possible solutions):
http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works
I decided to use solution 2, to access the components directly:
so I ... :
1. set the commandbutton immediate="true"
2. set the selectoneradio to immediate="true"
3. created 2 component properties in my backing bean (selectoneradio and seledtitem)
4. set the binding attribute of the components to this bean properties
5. wrote some code to access the components inside my actionlistener method
But the getValue() on these properties is always null.
<t:commandButton immediate="true" id="btnLoad" actionListener="#{BenutzerkontenBacking.loadBenutzer}" value="Laden"></t:commandButton>
.
<some code>
.
<t:selectOneRadio binding="#{BenutzerkontenBacking.radiocomponent}" immediate="true" id="radio" forceId="true" forceIdIndex="false" value="#{BenutzerkontenBacking.bnId}" onmouseup="(document.getElementById('mainfrm:content:btnLoad')).click();">
<f:selectItem binding="#{BenutzerkontenBacking.selectItem}" itemValue="#{crow.bnId}" itemLabel=""/>
</t:selectOneRadio>
Here some details from the backing bean:
HtmlSelectOneRadioradiocomponent;
UISelectItemselectItem;
.
<some code>
.
public void loadBenutzer( ActionEvent event )
{
log.info( "Lade Benutzer mit id " + getBnId() );
Benutzer b;
try
{
Integer id_to_load = null;
if ( getBnId() == null )
{
log.info( "Wert aus RadioButton: " + radiocomponent.getValue() );
if( radiocomponent.getValue() != null )
id_to_load = (Integer) radiocomponent.getValue();
else
{
log.info( "Wert aus RadioButton (SelectItem): " + radiocomponent.getValue() );
if( selectItem.getValue() != null )
id_to_load = (Integer)selectItem.getValue();
}
}
else
id_to_load = getBnId();
.
<rest of code>
.
Do you see an error ?
Thank you very much
zzza at 2007-7-13 0:01:09 >

# 7
Hi,
good news: ... It works ... :-)
Like RaymondDeCampo already said, goggle for BalusC磗 dataTable solved my problem.
Here is a good tutorial for handling dataTables:
http://balusc.xs4all.nl/srv/dev-jep-dat.html
My problem was, that i placed a commandbutton outside the datatable and executed the click event on this button via javascript after an onclick on my radiobuttons.
The solutions is, to place the radiobutton inside a commandlink (inside the datatable), then you can access the rowdata via component binding.
Thanks RaymondDeCampo
zzza at 2007-7-13 0:01:09 >
