2015-09-22 126 views
3

我正在嘗試使用Select2 ver4 jQuery插件和使用加載Select2示例頁面的遠程數據執行AJAX調用。現在我嘗試按下輸入鍵下一個元素焦點。如何對select2按enter鍵?

HTML代碼

<table> 
    <tr> 
     <td> 
      <select class="rp"> 
       <option value="1">1</option> 
       <option value="2">2</option> 
      </select> 
     </td> 
     <td> 
      <select class="rp"> 
       <option value="1">1</option> 
       <option value="2">2</option> 
      </select> 
     </td> 
     <td> 
      <select class="js-example-data-array"></select> 
     </td> 
    </tr> 
</table> 

JS代碼

$('select:first').focus(); 

$('input, select, textarea').on('keydown', function(e) { 
    if (e.which == 13) { 
     if (e.ctrlKey) { 
       $(this).closest('form').submit(); 
      } else { 
       var fields = $(this).closest('form').find('input, select, textarea'); 
       var total = fields.length; 
       var index = fields.index(this); 
       fields.eq(index + (e.shiftKey ? (index > 0 ? -1 : 0) : (index < total ? +1 : total))).focus(); 
       return false; 
      } 
     } 
    }); 

var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }]; 
$(".js-example-data-array").select2({ 
    data: data 
}) 

https://jsfiddle.net/ojpcsyxd/

我想按enter鍵下一個元素焦點。但我無法集中select2元素。

回答

1
$(".js-example-data-array").select2('open'); 

這將聚焦select2。

0

我知道這是一箇舊帖子,但對於那些仍在使用Tab鍵的Select2元素的HTML表單中掙扎的人,這可能會有所幫助。雖然這不是一個完美的解決方案,但以下是我們用來模擬包含Select2元素的HTML表單上的普通鍵盤導航的方法。

/** 
* WARNING: untested using Select2's option ['selectOnClose'=>true] 
* 
* This code was written because the Select2 widget does not handle 
* tabbing from one form field to another. The desired behavior is that 
* the user can use [Enter] to select a value from Select2 and [Tab] to move 
* to the next field on the form. 
* 
* The following code moves focus to the next form field when a Select2 'close' 
* event is triggered. If the next form field is a Select2 widget, the widget 
* is opened automatically. 
* 
* Users that click elsewhere on the document will cause the active Select2 
* widget to close. To prevent the code from overriding the user's focus choice 
* a flag is added to each element that the users clicks on. If the flag is 
* active, then the automatic focus script does not happen. 
* 
* To prevent conflicts with multiple Select2 widgets opening at once, a second 
* flag is used to indicate the open status of a Select2 widget. It was 
* necessary to use a flag instead of reading the class '--open' because using the 
* class '--open' as an indicator flag caused timing/bubbling issues. 
* 
* To simulate a Shift+Tab event, a flag is recorded every time the shift key 
* is pressed. 
*/ 
jQuery(document).ready(function($) { 
    var docBody = $(document.body); 
    var shiftPressed = false; 
    var clickedOutside = false; 
    //var keyPressed = 0; 

    docBody.on('keydown', function(e) { 
     var keyCaptured = (e.keyCode ? e.keyCode : e.which); 
     //shiftPressed = keyCaptured == 16 ? true : false; 
     if (keyCaptured == 16) { shiftPressed = true; } 
    }); 
    docBody.on('keyup', function(e) { 
     var keyCaptured = (e.keyCode ? e.keyCode : e.which); 
     //shiftPressed = keyCaptured == 16 ? true : false; 
     if (keyCaptured == 16) { shiftPressed = false; } 
    }); 

    docBody.on('mousedown', function(e){ 
     // remove other focused references 
     clickedOutside = false; 
     // record focus 
     if ($(e.target).is('[class*="select2"]')!=true) { 
      clickedOutside = true; 
     } 
    }); 

    docBody.on('select2:opening', function(e) { 
     // this element has focus, remove other flags 
     clickedOutside = false; 
     // flag this Select2 as open 
     $(e.target).attr('data-s2open', 1); 
    }); 
    docBody.on('select2:closing', function(e) { 
     // remove flag as Select2 is now closed 
     $(e.target).removeAttr('data-s2open'); 
    }); 

    docBody.on('select2:close', function(e) { 
     var elSelect = $(e.target); 
     elSelect.removeAttr('data-s2open'); 
     var currentForm = elSelect.closest('form'); 
     var othersOpen = currentForm.has('[data-s2open]').length; 
     if (othersOpen == 0 && clickedOutside==false) { 
      /* Find all inputs on the current form that would normally not be focus`able: 
      * - includes hidden <select> elements whose parents are visible (Select2) 
      * - EXCLUDES hidden <input>, hidden <button>, and hidden <textarea> elements 
      * - EXCLUDES disabled inputs 
      * - EXCLUDES read-only inputs 
      */ 
      var inputs = currentForm.find(':input:enabled:not([readonly], input:hidden, button:hidden, textarea:hidden)') 
       .not(function() { // do not include inputs with hidden parents 
        return $(this).parent().is(':hidden'); 
       }); 
      var elFocus = null; 
      $.each(inputs, function (index) { 
       var elInput = $(this); 
       if (elInput.attr('id') == elSelect.attr('id')) { 
        if (shiftPressed) { // Shift+Tab 
         elFocus = inputs.eq(index - 1); 
        } else { 
         elFocus = inputs.eq(index + 1); 
        } 
        return false; 
       } 
      }); 
      if (elFocus !== null) { 
       // automatically move focus to the next field on the form 
       var isSelect2 = elFocus.siblings('.select2').length > 0; 
       if (isSelect2) { 
        elFocus.select2('open'); 
       } else { 
        elFocus.focus(); 
       } 
      } 
     } 
    }); 

    /** 
    * Capture event where the user entered a Select2 control using the keyboard. 
    * http://stackoverflow.com/questions/20989458 
    * http://stackoverflow.com/questions/1318076 
    */ 
    docBody.on('focus', '.select2', function(e) { 
     var elSelect = $(this).siblings('select'); 
     var test1 = elSelect.is('[disabled]'); 
     var test2 = elSelect.is('[data-s2open]'); 
     var test3 = $(this).has('.select2-selection--single').length; 
     if (elSelect.is('[disabled]')==false && elSelect.is('[data-s2open]')==false 
      && $(this).has('.select2-selection--single').length>0) { 
      elSelect.attr('data-s2open', 1); 
      elSelect.select2('open'); 
     } 
    }); 

});