如何在Apache Wicket中将焦点设置在组件上?搜索得到的信息很少,大多是关于设置默认字段的。我不想设置默认字段,而是希望在选择特定单选按钮时设置焦点。
我建议使用原生的org.apache.wicket.ajax.AjaxRequestTarget#focusComponent()
。例如:
/**
* Sets the focus in the browser to the given component. The markup id must be set. If
* the component is null the focus will not be set to any component.
*
* @param component
* The component to get the focus or null.
*/
org.apache.wicket.ajax.AjaxRequestTarget#focusComponent(Component component)
myRadioButton.add(new AjaxEventBehavior("onchange") {
@Override
protected void onEvent(AjaxRequestTarget target) {
myOtherComponent.add(new DefaultFocusBehavior());
target.addComponent(myForm);
}
});
import org.apache.wicket.Component;
public class JavascriptUtils {
private JavascriptUtils() {
}
public static String getFocusScript(Component component) {
return "document.getElementById('" + component.getMarkupId() + "').focus();";
}
}
然后在任何Ajax方法中,您都可以使用:
target.appendJavascript(JavascriptUtils.getFocusScript(componentToFocus));
对于类似弹出式的modalWindow,我的解决方法是在第一个输入标签上使用"autofocus"属性。一种简单的解决方案是直接将其添加到HTML中。
<input ..... autofocus>
另一种解决方案是将其添加到modalWindow本身:
@Override
public void show(AjaxRequestTarget target) {
super.show(target);
setUpFocus();
}
protected void setUpFocus() {
DeepChildFirstVisitor visitor = new DeepChildFirstVisitor() {
@Override
public void component(Component component, IVisit<Void> iVisit) {
if (isAutofocusable(component)) {
component.add(new AttributeAppender("autofocus", ""));
iVisit.stop();
}
}
@Override
public boolean preCheck(Component component) {
return false;
}
};
this.visitChildren(FormComponent.class, visitor);
}
protected boolean isAutofocusable(Component component) {
if (component instanceof TextArea ||
component instanceof DropDownChoice ||
// component instanceof RadioChoice ||
component instanceof AjaxCheckBox ||
component instanceof AjaxButton ||
component instanceof TextField) {
return true;
}
return false;
}
RadioChoice已被注释掉,因为这个解决方案在那上面不起作用。对于RadioChoice,我建议实现一个FocusedRadioChoice:
public class FocusedRadioChoice<T> extends RadioChoice<T> {
//constructors...
@Override
protected IValueMap getAdditionalAttributes(int index, T choice) {
super.getAdditionalAttributes(0, choice);
AttributeMap am = new AttributeMap();
am.put("autofocus", "");
return am;
}
}
有没有一种方法可以在不使用JavaScript的情况下实现相同的功能?
(我正在实现一个带有反馈面板的表单,只有在关闭JavaScript时才会出现,因此在那里依赖JavaScript是没有意义的...,-)
我只能找到使用JS .focs()的答案...也许Wicket 1.5会提供Component.setFocus()方法...
onSubmit
方法中调用 target.focusComponent(myComponent);
来简单地聚焦于组件。@martin-g的解决方案是唯一一个在我的场景中(模态/弹出)使其正常工作的解决方案。
注意: 我认为在HTML中明确嵌入autofocus只能在页面加载时起作用,而不是在模态加载时起作用,因此任何试图巧妙地在模态的HTML中设置autofocus属性的努力都会失败 - 总是如此。
在这里,我列出了使用Wicket的全部功能(无需JS!)来设置名为“myInput”的输入字段上的焦点的步骤:
在onInitialize中:
// Make sure the field has an ID in markup
myInput.setOutoutMarkupId(true);
public void show(AjaxRequestTarget target)
{
// Make sure you call the super method first!
super.show(target);
target.focusComponent(myInput);
}
这需要您的组件是模态内容类的属性,以便您可以在show方法中访问它。为了避免为输入组件创建类属性,您可以将此解决方案与BlondCode的解决方案混合,通过替换该解决方案的
部分。component.add(new AttributeAppender("autofocus", ""));
使用
target.focusComponent(component);
这个也可以运行!