当您输入电子邮件,旧密码,新密码并重复修改个人资料的新密码时,我会有一些基本形式。我想要实现的是在传球错误时显示反馈信息。一段代码看起来像这样:
public class EditProfileForm extends Form<Void>
{
private static final long serialVersionUID = 1L;
// El-cheapo model for form
private final ValueMap properties = new ValueMap();
private ModalWindow modalWindow;
@SpringBean
UserManager userManager;
@SpringBean
Validator validator;
private User user;
private static final String EMAIL = "mp-email";
private static final String OLD_PASS = "mp-oldpass";
private static final String NEW_PASS = "mp-newpass";
private static final String NEW_PASS_REPEAT = "mp-newpassrepeat";
private static final String ERROR_WRONG_PASS = "Wrong pass";
private static final String ERROR_PASS_DIFF = "Pass diff";
private static final String ERROR_EMAIL_INVALID = "Wrong email";
private static final String ERROR_EMAIL_EXISTS = "Email used";
public EditProfileForm( String id, final ModalWindow modalWindow,final User u )
{
super( id );
this.user = u;
this.modalWindow = modalWindow;
add( new TextField<String>( EMAIL, new PropertyModel<String>( properties, EMAIL ) ).setRequired(true).setOutputMarkupId(true) );
add( new PasswordTextField( OLD_PASS, new PropertyModel<String>( properties, OLD_PASS ) ).setOutputMarkupId(true) );
add( new PasswordTextField( NEW_PASS, new PropertyModel<String>( properties, NEW_PASS ) ).setOutputMarkupId(true) );
add( new PasswordTextField( NEW_PASS_REPEAT, new PropertyModel<String>( properties, NEW_PASS_REPEAT ) ).setOutputMarkupId(true) );
final FeedbackPanel feedbackPanel = new FeedbackPanel( "feedback" );
feedbackPanel.setOutputMarkupId( true );
//feedbackPanel.setMaxMessages( 5 );
add( feedbackPanel );
AjaxSubmitLink closeBtn = new AjaxCloseCancelBtn( "close-x", this );
AjaxSubmitLink cancelBtn = new AjaxCloseCancelBtn( "cancel", this );
add( new AjaxSubmitLink( "save", this )
{
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit( AjaxRequestTarget target, Form<?> form )
{
if ( !user.getCryptedPassword().equals( CypherUtil.encodeMd5( getOldPassword() ) ) )
{
error( ERROR_WRONG_PASS );
}
else if ( !getNewPassword().equals( getNewPasswordRepeat() ) )
{
error( ERROR_PASS_DIFF );
}
else if ( !validator.validateEmailFormat( getEmail() ) )
{
error( ERROR_EMAIL_INVALID );
}
else if ( validator.emailExists( getEmail() ) )
{
error( ERROR_EMAIL_EXISTS );
} else
{
//save user data
}
}
@Override
protected void onError( AjaxRequestTarget target, Form<?> form )
{
target.add( feedbackPanel );
}
} );
add( closeBtn );
add( cancelBtn );
}
/**
* @return
*/
private String getEmail()
{
return properties.getString( EMAIL );
}
/**
* @return
*/
private String getOldPassword()
{
return properties.getString( OLD_PASS );
}
/**
* @return
*/
private String getNewPassword()
{
return properties.getString( NEW_PASS );
}
/**
* @return
*/
private String getNewPasswordRepeat()
{
return properties.getString( NEW_PASS_REPEAT );
}
}
现在,当我将这些表格留空时,我会收到很好的反馈信息,表示需要这些字段。同时,当我输入错误的密码,电子邮件或其他任何我什么都没有的时候,我的服务器日志就像这样留下了msg:
WARNING: Component-targetted feedback message was left unrendered.
This could be because you are missing a FeedbackPanel on the page.
Message: [FeedbackMessage message = "Wrong pass", reporter = save, level = ERROR]
表单位于一个弹出窗口的WebPage中:
public class ProfilePopup extends WebPage
{
private static final long serialVersionUID = 2929269801026361184L;
public ProfilePopup(final ModalWindow modal, final User user)
{
add( new EditProfileForm("profileModifyForm", modal, user).setOutputMarkupId(true) );
}
}
和HTML,在表单之外放置反馈也无济于事:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body class="stats-popup-body">
<div class="stats-popup" id="car-info-edit-popup">
<p class="popup_title"> Edytuj Profilu </p>
<form wicket:id="profileModifyForm" class="stats-popup-form">
<div>
<label class="popup_field_label">Email:</label>
<input type="text" wicket:id="mp-email" />
</div>
<div class="clear9"></div>
<div>
<label class="popup_field_label">Stare hasło:</label>
<input type="password" name="E-mail" title="E-mail1" id="E-mail2" wicket:id="mp-oldpass" />
</div>
<div>
<label class="popup_field_label">Nowe hasło:</label>
<input type="password" wicket:id="mp-newpass" />
</div>
<div>
<label class="popup_field_label">Powtórz nowe hasło:</label>
<input type="password" wicket:id="mp-newpassrepeat" />
</div>
<span wicket:id="feedback"></span>
<div class="button-box-bottom">
<input class="btn btn_save" style="margin-right: 9px;"
wicket:id="save" type="button" value="Zapisz"
onmousemove="this.className='btn btn_save btn_hover'"
onmouseout="this.className='btn btn_save'" />
<input
class="btn btn_cancel" wicket:id="cancel"
value="Anuluj" type="button"
onmousemove="this.className='btn btn_cancel btn_hover'"
onmouseout="this.className='btn btn_cancel'" />
</div>
<div class="stats-popup-close-x" wicket:id="close-x"></div>
</form>
</div>
</body>
</html>
答案 0 :(得分:11)
在onSubmit
中执行输入验证是不好的做法,因为一旦到达那里,(无效)输入已到达模型。正如您已经遇到的那样,在验证阶段结束后调用onSubmit
,因此输入将被视为有效,因此不会调用Form.onError
。
使用FormValidator
代替(在构造函数中向IFormValidator
添加Form
),如果您需要执行不那么简单的验证或涉及两个或更多组件输入的验证。请记住,用户输入尚未到达FormValidator.validate()
中的组件模型,因此您需要使用Component.getConvertedInput()
来验证输入。
如果您的验证仅涉及一个组件,并且只对其输入进行操作,则建议您使用IValidator
代替。
另请注意,Wicket提供的验证程序可以执行您要执行的某些验证:EqualPasswordInputValidator和EmailAddressValidator对您有用。
例如:
emailField.add(EmailAddressValidator.getInstance());
form.add(new EqualPasswordInputValidator(passwordField, passwordRepeatField));
查看这个(有点过时的)wiki页面,了解有关FormValidators的信息:Validating related fields