【问题标题】:How to unselect checkbox in chrome browser如何在chrome浏览器中取消选中复选框
【发布时间】:2012-09-17 12:04:15
【问题描述】:

在我的检票口应用程序中,我有 3 个复选框:

        add(new CheckBox("1").setOutputMarkupId(true));
        add(new CheckBox("2").setOutputMarkupId(true));
        add(new CheckBox("3").setOutputMarkupId(true));

表单还包含取消选择复选框的行为

        add(new AjaxEventBehavior("onclick") {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onEvent(AjaxRequestTarget target) {

                List<Component> components = new ArrayList<Component>();

                if (target.getLastFocusedElementId() != null) {
                    if (target.getLastFocusedElementId().equals("1")) {
                        components.add(get("2"));
                        components.add(get("3"));
                    } else if (target.getLastFocusedElementId().equals("2")) {
                        components.add(get("1"));
                    } else if (target.getLastFocusedElementId().equals("3")) {
                        components.add(get("1"));
                    }
                    for (Component component : components) {
                        component.setDefaultModelObject(null);
                        target.add(component);
                    }
                }
            }
        });

这在 mozilla 浏览器上运行良好,但在 chrome 中这不起作用。我怎样才能改进在 chrome 上工作呢?


更新

问题出在:

target.getLastFocusedElementId() 

在 mozilla 中返回我想要的,但在 chrome 中它总是返回 null 但我不知道 wh


更新 2

谷歌浏览器在焦点元素中有错误:

http://code.google.com/p/chromium/issues/detail?id=1383&can=1&q=window.focus%20type%3aBug&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner

所以我需要以其他方式这样做

【问题讨论】:

  • 根据AjaxRequestTargetsource code,看起来getLastFocusedElementId() 依赖于请求中Wicket-FocusedElementId 标头的值。你检查标题了吗?
  • ID 必须以字母开头。
  • 在不太了解您想要实现的目标的情况下,我发现您发布的代码中有一些奇怪的地方。仅仅为了取消选中某些复选框而触发 Ajax 请求可能有点矫枉过正,为什么不直接在客户端对这种行为进行编码呢?另外,您真的需要检查哪个复选框最后聚焦吗?行为附加到哪个组件?如果您对您要实现的目标提供更多背景信息,那么对您的帮助会更容易。
  • 好的上下文:我有 2 个复选框处于关闭状态。它们不能一起检查,因此当客户端检查时,应取消检查,反之亦然。
  • 我会完全在客户端实现这个,在提交时为那些没有启用 JS 的用户进行服务器端验证。如果你真的想在服务器端做,为什么不为每个复选框附加不同的行为呢?

标签: java google-chrome wicket


【解决方案1】:

客户端解决方案(Javascript)

您可以通过在客户端对该行为进行编码来节省 Ajax 调用并获得响应能力。在最简单的场景中,如果您可以给这些复选框一个固定的“id”属性,您可以使用Component.setMarkupId() 来强制检查的id 值(确保它在DOM 中是唯一的):

Java

add(new CheckBox("1").setOutputMarkupId(true).setMarkupId("check1");
add(new CheckBox("2").setOutputMarkupId(true).setMarkupId("check2");
add(new CheckBox("3").setOutputMarkupId(true).setMarkupId("check3");

HTML

<input type="checkbox" wicket:id="1" onclick="uncheck(this,1)"/>
<input type="checkbox" wicket:id="2" onclick="uncheck(this,2)"/>
<input type="checkbox" wicket:id="3" onclick="uncheck(this,3)"/>

Javascript

function uncheck(comp, idx){
   if (comp.checked) { 
       if (idx == 1){
           document.getElementById("check2").checked = false;
           document.getElementById("check3").checked = false;
       }
       else if (idx == 2 || idx == 3){
           document.getElementById("check1").checked = false;             
       } 
   }
}     ​

仅 Java 解决方案 (Ajax)

如果您真的想在服务器端执行此操作,那么在服务器端也传播值是有意义的(而不是依赖于上次关注的组件),例如 AjaxFormComponentUpdatingBehavior

        final CheckBox c1 = new CheckBox("on");
        final CheckBox c2 = new CheckBox("off");
        c1.setOutputMarkupId(true);
        c2.setOutputMarkupId(true);

        c1.add(new AjaxFormComponentUpdatingBehavior("onclick") {

            private static final long serialVersionUID = 1L;

            protected void onUpdate(final AjaxRequestTarget target) {
                if (Boolean.TRUE.equals(c1.getModelObject())) {
                    c2.setModelObject(Boolean.FALSE);
                    target.add(c2);
                }
            }
        });

        c2.add(new AjaxFormComponentUpdatingBehavior("onclick") {

            private static final long serialVersionUID = 1L;

            protected void onUpdate(final AjaxRequestTarget target) {
                if (Boolean.TRUE.equals(c2.getModelObject())) {
                    c1.setModelObject(Boolean.FALSE);
                    target.add(c1);
                }
            }
        });

        add(c1);
        add(c2);

如果此约束对数据模型的完整性很重要,您还应该在FormValidator 中实现它,这样无效输入就永远不会到达FormModels。没有启用 JS 或只是摆弄 DOM 的用户可以绕过它(如果使用 Ajax 行为,同样适用)。

【讨论】:

  • 嗯很好的例子。我不使用它,因为我不知道 js。我只知道java和wicket
  • 添加了一个关于如何使用 Ajax 的示例(不涉及 JS 编码)。但是,我会选择客户端解决方案;在页面中包含 JS 函数非常简单,您甚至可以从 Wicket 中完成(参见 HeaderContributors)
  • 很好的例子,但我试了一下,它也不起作用!!。首先,您的代码未编译,并且您使用的是不推荐使用的方法,例如 target.addComponent(c1);。其次,当我更正您的代码时,也无法在 chrome 上运行
  • 为什么不能在 Chrome 上运行?您是否尝试过调试 Ajax 行为,或查看 ajax 调试控制台?另外,我发布的代码只是一个建议,除了明显的编译错误外,它必须根据您的特定需求进行定制(例如,我们不知道您的 @ 的模型对象是什么987654332@s 是)。
  • 因为 Chrome 很烂 :) 而且我没有时间尝试调试它以及我在下面发布的方式我有自己的解决方案可以工作
【解决方案2】:

好的,当我将此行为添加到复选框时,我修复了带有焦点的 chrome 错误:

public class DefaultFocusBehavior extends AjaxEventBehavior {

public DefaultFocusBehavior(String event) {
    super(event);
}

private static final long serialVersionUID = 1;

private Component component;

@Override
protected void onEvent(AjaxRequestTarget target) {
    target.appendJavaScript(("document.getElementById('" + component.getMarkupId() + "').blur();"
            + "document.getElementById('" + component.getMarkupId() + "').focus();"));

}

protected void onBind() {
    this.component = getComponent();
    component.setOutputMarkupId(true);
}

}

所以现在我的代码也可以在 chrome 上运行

【讨论】:

    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 2015-08-02
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多