Hiro
Hiro

Reputation: 67

How to focus select2 pressing enter key?

I am attempting to do an AJAX call with the Select2 ver4 jquery plugin and Using Loading remote data of Select2 sample page. Now I try to pressing enter key next element focus.

HTML CODE

<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 CODE

$('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/

I want to focus next element by pressing enter key. But I can't focus select2 element.

Upvotes: 3

Views: 4293

Answers (2)

zDaniels
zDaniels

Reputation: 600

I know this is an old post, but for those who are still struggling with using the Tab key on an HTML form with Select2 elements this might be helpful. While it's not a perfect solution, the following is what we are using to simulate normal keyboard navigation on an HTML form that contains a Select2 element(s).

/**
 * 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');
        }
    });

});

Upvotes: 0

Ron
Ron

Reputation: 4095

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

This will focus the select2.

Upvotes: 2

Related Questions