如何在h:datatable jsf2.0中对单选按钮进行分组

时间:2011-08-22 11:14:27

标签: jsf-2 myfaces

我在JSF2中的h:datatable中有一列单选按钮,但我找不到对它们进行分组的方法。意味着所有这些都可以在单选按钮的整点指向的同时被选择,以便在任何给定时间只能选择一个。我相信会有标准的方法。

我正在使用myfaces。如果确实需要,可以使用richfaces。

任何人都可以帮忙解决这个问题。

2 个答案:

答案 0 :(得分:5)

<h:selectOneRadio>中使用标准JSF <h:dataTable>组件时,您需要将一个JavaScript镜头带入游戏中,当选中一个时,取消选中同一列中的所有其他单选按钮。

<h:column>
    <h:selectOneRadio onclick="uncheckOthers(this);">
</h:column>

function uncheckOthers(radio) {
    var name = radio.name.substring(radio.name.lastIndexOf(':'));
    var elements = radio.form.elements;
    for (var i = 0; i < elements.length; i++) {
        if (elements[i].name.substring(elements[i].name.lastIndexOf(':')) == name) {
            elements[i].checked = false;
        }
    }
    radio.checked = true;
}

答案 1 :(得分:0)

首先,在HTML或JSP中这么简单的东西在JSF中很难做到,这是荒谬的。这些添加的层应该让生活更轻松,而不是更难。但在我看来,他们只是让生活更艰难。我曾经喜欢他们。现在我是一名Java Luddite,现在主张采用更简单的方法,包括减少“新酷炫'技术'的方式”,更多的是“简单的工作方式而不必整整一周都在努力”过去只需要5分钟的东西“。无论如何,我已经尝试了过去3个工作日来使JSF中的简单功能工作,导致其他单选按钮取消选择并保持用户选择的按钮不变。我尝试了几种方法,包括一个自定义标记库(“overkill”,定义)和一些混合和匹配的东西,只产生了很多堆栈跟踪。我终于回到Javascript并接受了创建一个可靠的通用解决方案的可能性。我在别处读过类似的抱怨。好的,我的抱怨会结束了。这就是我为杀死我特定的JSF-radio-button龙而做的事情:

在.xhtml页面上:

<ui:composition template="../template.xhtml"
   ...
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
   ...
>

<a4j:loadScript src="/resources/scripts/custom.js" />
...
<ui:param name="pageBean" value="#{recordsBean}" />
...

<h:dataTable id="tblMine" 
   value="#{pageBean.records}" 
   var="item" 
   border="1" celpadding="0" cellspacing="0" 
   style="font-size=10px;text-align: center;"
>

<h:column> 
<f:facet name="header">
<h:panelGroup><h:panelGrid cellspacing="0" cellpadding="0" border="0" 
     id="rowSelect" columns="1" width="100%"><h:outputText 
        value="Select" /></h:panelGrid></h:panelGroup>
</f:facet>

<h:selectOneRadio id="userselectedrecord"
       onclick="javascript:clearOtherRadioButtons(event);" >
  <f:selectItem itemValue="#{item.recordid}" 
      itemLabel="" /> <!-- I set itemLabel to "" because in my case,
                           I don't want any text next to the radio btns -->
</h:selectOneRadio>
</h:column>
...
... and the rest of the page ...

在custom.js文件中,我有:

function clearOtherRadioButtons(evnt)
{
 // Have to try 'currentTarget', then 'srcElement'.  Issue is Firefox
 // supports 'currentTarget' but IE does not.  IE supports 'srcElement'.
 var btn = (evnt.currentTarget) ? evnt.currentTarget : evnt.srcElement;
 var matchindexlocn = btn.id.indexOf('userselectedrecord');
 var btnidstarttxt = btn.id.substring(0, 
            matchindexlocn + 18 ); // 'userselectedrecord' length = 18
 var elementid = '';
 var i = 0;
 var ele = null;
 var allElements = document.getElementsByTagName('*');

 for(i = 0; i < allElements.length; i++)
 {
     elementid = allElements[i].id;
     if ( (elementid.indexOf(btnidstarttxt) == -1) && 
          (elementid.indexOf('_') > -1) )
     {
       try
       {
        ele = document.getElementById(elementid);
        ele.checked = false;
        } catch (e) {}
     }
  }
} // function clearOtherRadioButtons(evnt)

就是这样。通过一些解释重新说明Javascript中的if():

elementid.indexOf(btnidstarttxt) == -1

- &GT;这会将元素缩小到 not 开头的元素,这些元素与添加了JSF的对象ID文本相关联,该文本与与传入事件关联的按钮组相关联。我们想要取消选择事件传递给函数的按钮组中的按钮。

elementid.indexOf('_') > -1

- &GT;由于JSF将下划线添加到按钮元素ID,因此这将元素进一步缩小到仅实际按钮。

设置checked = false的代码在try..catch块中的原因是为了防止逻辑上的任何假设出现问题并且不处理环境。如果您了解环境并且可以控制元素ID,那么您应该没问题。但是,例如,在某些事情发生变化的情况下,例如,应用程序的主机服务器安装了一些新版本的JSF库,它会覆盖你的应用程序的类加载策略(在工作环境中,我们知道这些事情可能超出我们的控制范围)现在以不同的方式分配这些元素ID,应用程序不会突然出现令人讨厌的Javascript错误,或者更糟糕的是,单选按钮选择停止工作。最糟糕的是我猜可能会同时选择多个无线电btns并且用户可以提交它们。我想一个好的预防措施是添加更多的Javascript代码来验证用户只提交了一个选项,或验证用户的提交服务器端。

看,管理单选按钮状态的方法太多了。