Как использовать h:selectOneRadio в h:dataTable для выбора одной строки?

У меня есть список страниц, отображаемых в таблице. Каждая страница имеет свойство homePage, и я хочу, чтобы в датированном файле имелся столбец радиокнопок, которые должны быть связаны с этим свойством, и пользователь может проверить только одно значение. Как я могу получить это значение на стороне сервера?

Я видел несколько примеров, таких как: http://jforum.icesoft.org/JForum/posts/list/14157.page, но я хотел бы знать, какова наилучшая практика в таком случае.

3 ответа

Решение

В соответствии со спецификацией JSF 329 я наконец-то реализовал ее для JSF 2.3. С новым group Теперь вы сможете группировать переключатели в компоненте повторителя.

<h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:selectOneRadio group="foo" value="#{bean.selectedItem}">
            <f:selectItem itemValue="#{item}" />
        </h:selectOneRadio>
    </h:column>
</h:dataTable>

Это будет доступно согласно Мохарре 2.3.0-m07.


До JSF 2.3 это не тривиально со стандартным JSF <h:selectOneRadio>, По сути, переключатели в каждой строке должны быть сгруппированы друг с другом, используя один и тот же вход name так что другие переключатели отключаются всякий раз, когда вы выбираете одну. Но они не сгруппированы, у них есть все свои nameпоэтому другие переключатели никогда не будут отключены.

Библиотеки компонентов, такие как PrimeFaces, решили эту проблему, предоставив специальный атрибут или компонент столбца. Смотрите также этот пример, который использует <p:column selectionMode="single"> создать один столбец выбора. На выбранное значение ссылается selection атрибут <p:dataTable>, Если вы уже используете библиотеку компонентов, и в ней уже есть такой компонент, вам следует использовать ее.

В стандартном JSF <h:dataTable> с <h:selectOneRadio> вам нужно будет ввести обходной путь JavaScript следующим образом, который снимает все остальные переключатели в том же столбце:

<h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:selectOneRadio valueChangeListener="#{bean.setSelectedItem}"
            onclick="dataTableSelectOneRadio(this);">
            <f:selectItem itemValue="null" />
        </h:selectOneRadio>
    </h:column>
    ...
</h:dataTable>

с

public void setSelectedItem(ValueChangeEvent event) {
    FacesContext context = FacesContext.getCurrentInstance();
    selectedItem = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
}

а также

function dataTableSelectOneRadio(radio) {
    var radioId = radio.name.substring(radio.name.lastIndexOf(':'));

    for (var i = 0; i < radio.form.elements.length; i++) {
        var element = radio.form.elements[i];

        if (element.name.substring(element.name.lastIndexOf(':')) == radioId) {
            element.checked = false;
        }
    }

    radio.checked = true;
}

Я исправил для одиночного выбора для радио кнопки в datatable с использованием ниже JavaScript

function uncheckRadioButtons(radioButton) {
var selectedRadioButton;
   if (selectedRadioButton != null) {
      selectedRadioButton.checked = false;
   }

   selectedRadioButton = radioButton;
   selectedRadioButton.checked = true;
}

и в xhtml

 <h:selectOneRadio 
        onclick="uncheckRadioButtons(this);">
        <f:selectItem itemValue="null" />
    </h:selectOneRadio>

Я нашел другое решение, и я хочу поделиться им с вами, это использовать h:selectBooleanCheckboxВместе с функцией одиночного выбора JS BalusC предложил:

            <ace:column id="homePage" headerText="Home Page">
                <h:selectBooleanCheckbox value="#{adpage.homePage}" onclick="dataTableSelectOneRadio(this);"></h:selectBooleanCheckbox>
            </ace:column>

и JS:

function dataTableSelectOneRadio(radio) {
var radioId = radio.name.substring(radio.name.lastIndexOf(':'));

for (var i = 0; i < radio.form.elements.length; i++) {
    var element = radio.form.elements[i];

    if (element.name.substring(element.name.lastIndexOf(':')) == radioId) {
        element.checked = false;
               }
         }

      radio.checked = true;
    }

при этом будет установлен только один флажок и обновлено логическое свойство в отмеченном / непроверенном объекте.

Другие вопросы по тегам