2014-02-13 33 views
3

我有以下SelectOneRadio:選擇信息在SelectOneRadio正在重置的tabindex算

<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,當我選項卡的「性」部分,並選擇任意的selectItem與空格鍵或鼠標單擊,當我再次按Tab鍵時,焦點轉到tabindex = 1的元素,而不是下一個。 我該如何解決這個問題?

我正在使用primefaces 4.0

謝謝!

+0

你可以顯示你的代碼,你有設置組件tabindex 1到4 – ZEE

+1

在這裏也是這樣:http://www.primefaces.org/showcase/ui/selectOneRadio.jsf –

回答

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. 增加的情況下,爲keyCode.SPACEkeydown綁定和
  2. 增加和額外.focus()當選擇收音機上選擇功能。

我希望能幫到你。

+0

感謝您的答案!我會等待有人想出一個更簡單的黑客,否則我會標記你的答案是正確的! – PMBG

+0

它適用於Primefaces 4,但不適用於5 – PMBG