selectOneRadio中的selectItem重置tabindex计数

时间:2014-02-13 01:00:55

标签: jsf jsf-2 primefaces

我有以下SelectOneRadio:

<p:selectOneRadio id="sex" tabindex="3" value="#{signUp.gender}" required="true">  
    <f:selectItem itemLabel="Male" itemValue="M"  />
    <f:selectItem itemLabel="Female" itemValue="F" />
</p:selectOneRadio>

虽然我表单中下一个元素的tabindex为4,但当我选中“sex”组件时,选择任意一个带有空格键或鼠标单击的selectItem,当我再次按Tab键时,重点是tabindex = 1的元素,而不是下一个元素。 我该如何解决这个问题?

我正在使用primefaces 4.0

谢谢!

1 个答案:

答案 0 :(得分:2)

我能够使用Primfaces showcase重现错误,并且我还找到了一个关于仍然打开的空格键选择的bug

作为解决方法,您可以覆盖Primefaces默认的SelectOneRadio小部件并进行必要的更改。为了测试这种方法,我创建了一个名为 customradio.js 的文件,其中包含以下内容:

PrimeFaces.widget.SelectOneRadio = PrimeFaces.widget.BaseWidget.extend({
    init: function(cfg) {
        this._super(cfg);

        //custom layout
        if (this.cfg.custom) {
            this.inputs = $('input:radio[name="' + this.id + '"]:not(:disabled)');
            this.outputs = this.inputs.parent().next('.ui-radiobutton-box:not(.ui-state-disabled)');
            this.labels = $();
            this.icons = this.outputs.find('.ui-radiobutton-icon');

            //labels
            for (var i = 0; i < this.outputs.length; i++) {
                this.labels = this.labels.add('label[for="' + this.outputs.eq(i).parent().attr('id') + '"]');
            }
        }
        //regular layout
        else {
            this.outputs = this.jq.find('.ui-radiobutton-box:not(.ui-state-disabled)');
            this.inputs = this.jq.find(':radio:not(:disabled)');
            this.labels = this.jq.find('label:not(.ui-state-disabled)');
            this.icons = this.jq.find('.ui-radiobutton-icon');
        }

        this.checkedRadio = this.outputs.filter('.ui-state-active');

        this.bindEvents();

        //pfs metadata
        this.inputs.data(PrimeFaces.CLIENT_ID_DATA, this.id);
    },
    bindEvents: function() {
        var $this = this;

        this.outputs.on('mouseover.selectOneRadio', function() {
            $(this).addClass('ui-state-hover');
        })
                .on('mouseout.selectOneRadio', function() {
                    $(this).removeClass('ui-state-hover');
                })
                .on('click.selectOneRadio', function() {
                    var radio = $(this),
                            input = radio.prev().children(':radio');

                    if (!radio.hasClass('ui-state-active')) {
                        $this.unselect($this.checkedRadio);
                        $this.select(radio);
                        input.trigger('click');
                        input.trigger('change');
                    }
                    else {
                        input.trigger('click');
                    }
                });

        this.labels.on('click.selectOneRadio', function(e) {
            var target = $(PrimeFaces.escapeClientId($(this).attr('for'))),
                    radio = null;

            //checks if target is input or not(custom labels)
            if (target.is(':input'))
                radio = target.parent().next();
            else
                radio = target.children('.ui-radiobutton-box'); //custom layout

            radio.trigger('click.selectOneRadio');

            console.log("click.selectOneRadio");

            e.preventDefault();
        });

        this.inputs.on('focus.selectOneRadio', function() {
            var input = $(this),
                    radio = input.parent().next();

            if (input.prop('checked')) {
                radio.removeClass('ui-state-active');
            }

            radio.addClass('ui-state-focus');
        })
                .on('blur.selectOneRadio', function() {
                    var input = $(this),
                            radio = input.parent().next();

                    if (input.prop('checked')) {
                        radio.addClass('ui-state-active');
                    }

                    radio.removeClass('ui-state-focus');
                })
                .on('keydown.selectOneRadio', function(e) {
                    var input = $(this),
                            currentRadio = input.parent().next(),
                            index = $this.inputs.index(input),
                            size = $this.inputs.length,
                            keyCode = $.ui.keyCode,
                            key = e.which;

                    switch (key) {
                        case keyCode.UP:
                        case keyCode.LEFT:
                            var prevRadioInput = (index === 0) ? $this.inputs.eq((size - 1)) : $this.inputs.eq(--index),
                                    prevRadio = prevRadioInput.parent().next();

                            input.blur();
                            $this.unselect(currentRadio);
                            $this.select(prevRadio);
                            prevRadioInput.trigger('focus').trigger('change');
                            e.preventDefault();
                            break;

                        case keyCode.DOWN:
                        case keyCode.RIGHT:
                            var nextRadioInput = (index === (size - 1)) ? $this.inputs.eq(0) : $this.inputs.eq(++index),
                                    nextRadio = nextRadioInput.parent().next();
                            input.blur();
                            $this.unselect(currentRadio);
                            $this.select(nextRadio);
                            nextRadioInput.trigger('focus').trigger('change');
                            e.preventDefault();
                            break;
                        case keyCode.SPACE:
                            if (!currentRadio.hasClass('ui-state-active')) {
                                $this.unselect($this.checkedRadio);
                                $this.select(currentRadio);
                                input.trigger('change');
                            }
                            break;
                    }
                });

        if (this.cfg.behaviors) {
            PrimeFaces.attachBehaviors(this.inputs, this.cfg.behaviors);
        }
    },
    unselect: function(radio) {
        radio.prev().children(':radio').prop('checked', false);
        radio.removeClass('ui-state-active').children('.ui-radiobutton-icon').removeClass('ui-icon ui-icon-bullet');
    },
    select: function(radio) {
        this.checkedRadio = radio;
        radio.addClass('ui-state-active').children('.ui-radiobutton-icon').addClass('ui-icon ui-icon-bullet');
        radio.prev().children(':radio').prop('checked', true).focus();
    }
});

主要变化是:

  1. keydown 绑定上添加了 keyCode.SPACE 的案例
  2. 选择功能选择广播时添加了 .focus()
  3. 我希望能帮助你。