Цикл Фокус на первый элемент формы от последнего элемента и наоборот - PullRequest
2 голосов
/ 27 июля 2010

Я создал форму с плагином формы malsup, в которой он отправляет информацию об изменении входных данных.Я настроил свой сценарий jQuery для индексации выпадающих меню и видимых входов и использую этот индекс, чтобы определить, следует ли при нажатии клавиши табуляции переместить фокус на следующий или первый элемент, а также с помощью клавиш Shift + Tab.Однако вместо перемещения фокуса на первый элемент из последнего элемента на клавиатуре, как я бы этого хотел, он перемещает фокус на второй элемент.Как я могу изменить его, чтобы переключить фокус на фактические первый и последний элементы?Вот прямая ссылка на мою форму: http://www.presspound.org/calculator/ajax/sample.php. Спасибо всем, кто пытается помочь.Вот мой сценарий:

$(document).ready(function() {
var options = {
    target: '#c_main',
    success: setFocus
};
$('#calculator').live('submit', function() {
    $(this).ajaxSubmit(options);
    return false;
});
$(this).focusin(function(event) {
    var shiftDown = false;
    $('input, select').each(function (i) {
        $(this).data('initial', $(this).val());
    });
    $('input, select').keyup(function(event) {
        if (event.keyCode==16) {
            shiftDown = false;
            $('#shiftCatch').val(shiftDown);
        }
    });
    $('input, select').keydown(function(event) {
        if (event.keyCode==16) {
            shiftDown = true;
            $('#shiftCatch').val(shiftDown);
        }
        if (event.keyCode==13) {
            $('#captured').val(event.target.id);
        } else if (event.keyCode==9 && shiftDown==false) {
            return $(event.target).each(function() {
                var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
                var index = fields.index(this);
                var nextEl = fields.eq(index+1).attr('id');
                var firstEl = fields.eq(0).attr('id');
                var focusEl = '#'+firstEl;
                if (index>-1 && (index+1)<fields.length) {
                    $('#captured').val(nextEl);
                } else if(index+1>=fields.length) {
                    if ($(this).val() != $(this).data('initial')) {
                        $('#captured').val(firstEl);
                    } else {
                        event.preventDefault();
                        $(focusEl).focus();
                    }
                }
                return false;
            });
        } else     if (event.keyCode==9 && shiftDown==true) {
            return $(event.target).each(function() {
                var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
                var index = fields.index(this);
                var prevEl = fields.eq(index-1).attr('id');
                var lastEl = fields.eq(fields.length-1).attr('id');
                var focusEl = '#'+lastEl;
                if (index<fields.length && (index-1)>-1) {
                    $('#captured').val(prevEl);
                } else if (index==0) {
                    if ($(this).val() != $(this).data('initial')) {
                        $('#captured').val(lastEl);
                    } else {
                        event.preventDefault();
                        $(focusEl).select();
                    }
                }
                return false;
            });
        }
    });
});

});function setFocus () {with (document.calculator) var recap = document.getElementById (recaptured.value);if (recap! = null) {setTimeout (function () {if (recap.getAttribute ('type') == 'text') {recap.select ();} else {recap.focus ();}}, 100);}}

Edit # 1 : я внес несколько незначительных изменений в код, что немного приблизило меня к предполагаемой функциональности сценария.Однако я внес только одно изменение в код, относящийся к фокусу: я попытался отключить нажатие клавиши табуляции при нажатии на последнем элементе (а также нажатие клавиши shift + tab на первом элементе), пытаясь сосредоточиться наэлемент, который я хочу, не пропуская его, как это было раньше.Это код, который я добавил:

$(this).one('keydown', function (event) {
    return !(event.keyCode==9 && shiftDown==true);
});

Этот вид работ.После загрузки страницы, если пользователь нажимает вкладку на последнем элементе, не внося изменений в его значение, фокус будет установлен на второй элемент.Однако во второй раз пользователь нажимает клавишу табуляции на последнем элементе, не внося изменений в его значение, и каждый последующий раз после этого фокус будет установлен на первый элемент, как мне бы хотелось.

Edit # 2 : я заменил код в Edit # 1 на код с использованием event.preventDefault (), который работает лучше.Если пользователь нажимает клавишу Shift + Tab в первом элементе, фокус переходит к последнему элементу, как и должно быть.Однако, если пользователь продолжает удерживать клавишу Shift и снова нажимает клавишу Tab, фокус будет возвращен к первому элементу.И если пользователь продолжает удерживать клавишу Shift все еще и нажимает на вкладку, фокус вернется к последнему элементу.Фокус будет смещаться вперед и назад между первым и последним элементом, пока пользователь не поднимет клавишу Shift.Эта проблема не возникает при нажатии только вкладки.Вот новый фрагмент кода:

event.preventDefault();
$(focusEl).focus();

Ответы [ 2 ]

1 голос
/ 30 июля 2010

Вот решение, к которому я не смог бы прийти без помощи Симена. Еще раз спасибо, Симен.

$(document).ready(function() {
    var options = {
        target: '#c_main',
        success: setFocus
    };
    $('#calculator').live('submit', function() {
        $(this).ajaxSubmit(options);
        return false;
    });
    $(this).focusin(function(event) {
        $('#calculator :input:visible').each(function (i) {
            $(this).data('initial', $(this).val());
        });
        return $(event.target).each(function() {
            $('#c_main :input:visible').live(($.browser.opera ? 'keypress' : 'keydown'), function(event){
                var elements = $("#calculator :input:visible");
                var n = elements.length;
                var currentIndex = elements.index(this);
                if (event.keyCode == 13) { //if enter
                    var focusElement = elements.eq(currentIndex).attr('id');
                    $('#captured').val(focusElement);
                } else if (event.keyCode == 9) { //if tab
                    var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
                    var el = elements.eq(newIndex);
                    var focusElement = el.attr('id');
                    if ($(this).val() != $(this).data('initial')) {
                        $('#captured').val(focusElement);
                    } else if ((currentIndex==0 && event.shiftKey) || (currentIndex==n-1 && !event.shiftKey)) { 
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            $.browser.msie ? "" : $(window).scrollTop(5000);
                            el.select().delay(800);
                        } else {
                            $.browser.msie ? "" : $(window).scrollTop(-5000);
                            el.focus().delay(800);
                        }
                    } else if (el.is('select')) {
                        event.preventDefault();
                        if (el.attr('type')=='text') {
                            el.select();
                        } else {
                            el.focus();
                        }
                    }
                }
            });
        });
    });
});

function setFocus() {
    with (document.calculator)
    var recap = document.getElementById(recaptured.value);
    if (recap!=null) {
        setTimeout(function() {
            if (recap.getAttribute('type')=='text') {
                recap.select();
            } else {
                recap.focus();
            }
        }, 1     );
    }
}

Я разместил свои файлы, доступные для скачивания, по моей прямой ссылке: http://www.presspound.org/calculator/ajax/sample.php

1 голос
/ 29 июля 2010

У вас много кода, я не получил полного обзора, поэтому я не знаю, пропустил ли я какую-то функциональность, которую вы хотели интегрировать, но для табуляции / смещения-табуляции через элементы формы это должно сработать :

var elements = $("#container :input:visible");
var n = elements.length;
elements
.keydown(function(event){
    if (event.keyCode == 9) { //if tab
        var currentIndex = elements.index(this);
        var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
        var el = elements.eq(newIndex);
        if (el.attr("type") == "text")
            elements.eq(newIndex).select();
        else
            elements.eq(newIndex).focus();
        event.preventDefault();
    }
});

elements будет объектом jQuery, содержащим все поля ввода, в моем примере это все поля ввода внутри div #container Вот демоверсия: http://jsfiddle.net/rA3L9/

...