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

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

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


person Mahmoud Saleh    schedule 10.06.2012    source источник


Ответы (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>

Он будет доступен в Mojarra 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;
}
person BalusC    schedule 10.06.2012
comment
когда я использую <f:ajax execute="@this" render="@form" /> внутри h:selectOneRadio, так что valueChangeListener работает, переключатель выбирается, а затем снимается, есть идеи? я хочу, чтобы выбранное радио оставалось выбранным, а старое выбранное не было выбрано - person Mahmoud Saleh; 10.06.2012
comment
Здесь нет необходимости в <f:ajax>. - person BalusC; 10.06.2012
comment
valueChangeListener не запускается, когда я нажимаю любой переключатель. - person Mahmoud Saleh; 10.06.2012
comment
не могли бы вы также взглянуть на этот подход? проверить, когда значение истинно"> stackoverflow.com/questions/10970248/ - person Mahmoud Saleh; 10.06.2012
comment
Это также не намерение. Он запускается только тогда, когда вы отправляете форму обычным способом с помощью командной кнопки. Или вы хотите отправить форму сразу после выбора переключателя? Вы не просили об этом. Таким образом, весь обходной путь JavaScript не нужен, и ответ должен быть изменен. - person BalusC; 10.06.2012
comment
я попробовал это сейчас, и это работает очень хорошо, и я могу поймать объект и сохранить его в базе данных, но все еще есть одна проблема: я хочу установить выбранный объект программно в preRender, как это сделать? - person Mahmoud Saleh; 11.06.2012
comment
Я попробовал решение JS, но, похоже, JS здесь не поможет, так как в этой таблице данных может быть разбиение на страницы, есть идеи? - person Mahmoud Saleh; 11.06.2012
comment
@BalusC Этот код действительно полезен, однако я не очень хорошо разбираюсь в JSF ... не могли бы вы объяснить value=#{bean.items} var=item. что содержит значение и переменная - person Twaha Mehmood; 12.02.2016

я нашел другое решение, и я хочу поделиться им с вами, это использовать 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;
    }

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

person Mahmoud Saleh    schedule 11.06.2012
comment
Однако флажки более запутаны с точки зрения пользовательского интерфейса, когда используются как одиночный выбор, поскольку они обычно указывают на множественный выбор. Вы не должны использовать это для одиночного выбора. Если ваша единственная цель — сохранить выбранное/проверенное значение, просто используйте атрибут value и правильное значение <f:selectItem>. Здесь уже дан ответ о том, как правильно использовать <h:selectBooleanCheckbox>: p/2524832#2524832" title="как использовать jsfs hselectbooleancheckbox с hdatatable для создания одного объекта p">stackoverflow.com/questions/2524514/ - person BalusC; 11.06.2012

переменная selectedRadioButton должна быть объявлена ​​вне функции.

var selectedRadioButton;

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

   selectedRadioButton = radioButton;
   selectedRadioButton.checked = true;
}

и в хтмл

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