2008-11-14 3 views
35

Использование jQuery, что является лучшим способом найти следующий элемент формы на странице, начиная с произвольного элемента? Когда я говорю элемент формы, я имею в виду <input>, <select>, <button> или <textarea>.Лучший способ найти «следующий» элемент ввода формы в jQuery?

В следующих примерах элемент с идентификатором «это» является произвольной начальной точкой, а элемент с идентификатором «следующий» - это тот, который я хочу найти. Тот же ответ должен работать на всех примерах.

Пример 1:

<ul> 
<li><input type="text" /></li> 
<li><input id="this" type="text" /></li> 
</ul> 

<ul> 
<li><input id="next" type="text" /></li> 
</ul> 

<button></button> 

Пример 2:

<ul> 
<li><input id="this" type="text" /></li> 
</ul> 

<button id="next"></button> 

Пример 3:

<input id="this" type="text" /> 
<input id="next" type="text" /> 

Пример 4:

<div> 
    <input id="this" type="text" /> 
    <input type="hidden" /> 
    <div> 
    <table> 
     <tr><td></td><td><input id="next" type="text" /></td></tr> 
    </table> 
    </div> 
    <button></button> 
</div> 

EDIT: два ответа, предоставленные до сих пор, требуют записи порядкового номера ко всем входным элементам на странице. Как я уже упоминал в комментариях к одному из них, это то, что я уже делаю, и я бы предпочел иметь решение только для чтения, поскольку это будет происходить внутри плагина.

ответ

51

престижность,

Что об использовании .index?

например $(':input:eq(' + ($(':input').index(this) + 1) + ')');

+0

Это отлично работает. Благодаря redsquare, bobbytek4 и grault на freenode #jquery за их помощь. – 2008-11-15 02:16:15

+8

Отфильтровать отключенные поля $ (": input: not (: disabled): eq (" + ($ (": input: not (: disabled)"). Index (currentElement) + 1) – Sentient 2011-04-19 18:33:36

+5

Мне нужно было добавить еще set of parens, в противном случае он сделал строку concat по индексу. Закончено с: $ (": input: eq (" + ($ (": input"). index (this) + 1) + ")"); – 2012-05-24 23:16:37

2

Вы можете указать каждому элементу формы идентификатор (или уникальное имя класса), который идентифицировал его как элемент формы, а также дал ему индекс. Например:

<div> 
    <input id="FormElement_0" type="text" /> 
    <input id="FormElement_1" type="text" /> 
<div> 

Затем, если вы хотите, чтобы пройти от первого элемента ко второму вы можете сделать что-то вроде этого:

//I'm assuming "this" is referring to the first input 

//grab the id 
var id = $(this).attr('id'); 

//get the index from the id and increment it 
var index = parseInt(id.split('_')[0], 10); 
index++; 

//grab the element witht that index 
var next = $('#FormElement_' + index); 

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

+0

Спасибо за ответ. Это, к сожалению, именно то, что я пытаюсь избавиться от :). Я перемещаю свой код в плагин, и я бы предпочел, чтобы он был полезен, не выбирая собственный выбор пользователя. Уникальное имя класса интересно, но я предпочел бы более «доступное только для чтения» решение, если это было возможно. – 2008-11-14 16:28:20

+0

Понятно. Я понимаю, что решение, которое я предоставил, было немного «грязным». С точки зрения плагина значительно меньше смысла. – jckeyes 2008-11-14 17:07:22

1

Или вы можете использовать атрибут html 'tabindex', который используется для того, когда пользователь нажимает на форму, он переходит к tabindex = "i" в tabindex = "i + 1". Вы можете использовать jQuery, чтобы получить атрибут очень легко. Сделал бы для хорошего возвращения к пользователям без включенного javascript, также.

+1

Нельзя индексировать индексы пропустить номер? – mpen 2011-02-07 18:34:34

1

я придумал функцию, которая делает работу без явного определения индексов:

function nextInput(form, id) { 
    var aInputs = $('#' + form).find(':input[type!=hidden]'); 
    for (var i in aInputs) { 
     if ($(aInputs[i]).attr('id') == id) { 
      if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') { 
       return aInputs[parseInt(i) + 1]; 
      } 
     } 
    } 
} 

А вот рабочий пример. Теги формы для согласованности. Все, что вам действительно нужно, является общим родителем и даже может использовать тег body как родительский (с небольшой модификацией функции).

Вставить этот код в файл и открыть с помощью Firefox/Firebug, и вы увидите, что он возвращает правильный элемент для всех ваших примеров:

<html> 
    <head> 
    <script src="http://www.google.com/jsapi"></script> 
    <script> 
     function nextInput(form, id) { 
     var aInputs = $('#' + form).find(':input[type!=hidden]'); 
     for (var i in aInputs) { 
      if ($(aInputs[i]).attr('id') == id) { 
      if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') { 
       return aInputs[parseInt(i) + 1]; 
      } 
      } 
     } 
     } 

     google.load("jquery", "1.2.6"); 
     google.setOnLoadCallback(function() { 
     console.log(nextInput('myform1', 'this1')); 
     console.log(nextInput('myform2', 'this2')); 
     console.log(nextInput('myform3', 'this3')); 
     console.log(nextInput('myform4', 'this4')); 
     }); 
    </script> 
    </head> 
    <body> 
    <form id="myform1"> 
     <ul> 
     <li><input type="text" /></li> 
     <li><input id="this1" type="text" /></li> 
     </ul> 
     <ul> 
     <li><input id="next1" type="text" /></li> 
     </ul> 
    </form> 

    <form id="myform2"> 
     <ul> 
     <li><input type="text" /></li> 
     <li><input id="this2" type="text" /></li> 
     </ul> 
     <ul> 
     <li><input id="next2" type="text" /></li> 
     </ul> 
    </form> 

    <form id="myform3"> 
     <input id="this3" type="text" /> 
     <input id="next3" type="text" /> 
    </form> 

    <form id="myform4"> 
     <div> 
     <input id="this4" type="text" /> 
     <input type="hidden" /> 
     <div> 
     <table> 
      <tr><td></td><td><input id="next4" type="text" /></td></tr> 
     </table> 
     </div> 
     <button></button> 
     </div> 
    </form> 
    </body> 
</html> 
2

Вы можете сделать это, чтобы взять полный список элементов формы вы ищете:

var yourFormFields = $("yourForm").find('button,input,textarea,select'); 

Тогда, должно быть легко найти следующий элемент:

var index = yourFormFields.index(this); // the index of your current element in the list. if the current element is not in the list, index = -1 

if (index > -1 && (index + 1) < yourFormFields.length) { 

        var nextElement = yourFormFields.eq(index + 1); 

        } 
0

Вы можете использовать плагин поля jQuery, который позволяет это сделать.

13

redsquare абсолютно прав, а также отличное решение, которое я также использовал в одном из моих проектов.

Я просто хотел указать, что ему не хватает скобок, так как текущее решение объединяет индекс с 1, вместо того, чтобы добавлять их вместе.

Так скорректированное решение будет выглядеть следующим образом:

$(":input:eq(" + ($(":input").index(this) + 1) + ")"); 

Sorry о двойной пост, но я не мог найти способ прокомментировать свой пост ...

9

Это решение не требует индексы, а также хорошо играет с tabindex - другими словами, он дает вам точный элемент, который браузер даст вам на вкладке каждый раз, без дополнительной работы.

function nextOnTabIndex(element) { 
     var fields = $($('form') 
        .find('a[href], button, input, select, textarea') 
        .filter(':visible').filter('a, :enabled') 
        .toArray() 
        .sort(function(a, b) { 
         return ((a.tabIndex > 0) ? a.tabIndex : 1000) - ((b.tabIndex > 0) ? b.tabIndex : 1000); 
        })); 


     return fields.eq((fields.index(element) + 1) % fields.length); 
    } 

Он работает, захватывая все tabbable поля в форме (как разрешено http://www.w3.org/TR/html5/editing.html#focus-management), а затем сортировки полей на основе (http://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute) для работы на следующий элемент на вкладку с. Как только он имеет это, он смотрит, где переданное в поле находится в этом массиве, и возвращает следующий элемент.

несколько вещей, чтобы отметить:

  • JQuery, кажется, поддерживает сортировки() объекта JQuery, но я не могу найти это явно в документации, следовательно, вызывая ToArray(), а затем rewrapping массив в объекте jQuery.
  • Есть другие поля, которые согласны с вкладкой, но я их оставил, поскольку они не являются стандартными поля формы.

Код я использовал, чтобы проверить это (с помощью JQuery 1.7):

<script> 
    $(function() { 
    $('a[href], button, input, select, textarea').click(function() { 
     console.log(nextOnTabIndex($(this)).attr('name')); 
    }) 
    }); 
</script> 

<form> 
    <input type='text' name='a'/> 
    <input type='text' name='b' tabindex='1' /> 
    <a>Hello</a> 
    <input type='text' name='c'/> 
    <textarea name='d' tabindex='2'></textarea> 
    <input id='submit' type='submit' name='e' tabindex='1' /> 
</form> 
0
var elementSelector = "input:visible,textarea:visible"; 
var nextSibling = $(elementSelector)[$(elementSelector).index() + 1]; 
//$(nextSibling).focus(); possible action 

Я просто думаю, что выше решение проще, или вы можете просто добавить все это в одной строке, если вы хочу :-)

var nextSibling = $("input:visible,textarea:visible")[$("input:visible,textarea:visible").index() + 1]; 
5

После попытки каждого кода, который я смог найти (и возникают проблемы между браузерами), я нашел один, который работает в лучших браузерах. Не удалось использовать предыдущие подпрограммы из-за некоторых странных проблем.

$(document.body).keydown(function(event) { 
    if(event.keyCode == 13) { 
     $(":input")[$(":input").index(document.activeElement) + 1].focus(); 
     return false; 
    } 
}); 

Надеюсь, это поможет кому-то еще. Наслаждаться.

0

Это хорошо работало для меня, и это правильно перепрыгивает через скрытые входы:

input_el.nextAll('input:visible:first').focus(); 
0

Все решения, используя индекс (или nextAll) будет работать только, когда все формы входы являются братьями и сестрами, например, в том же блоке <div>. Следующее обходит это, создавая массив идентификаторов всех видимых, нечитанных входов на странице и выбирает первый после текущего элемента управления, обертывая раунд, если текущий элемент управления является последним на странице.

ids = $(":input:visible:not([readonly])").map(function() { return this.id }); 
nextId = ids[($.inArray($(this).attr("id"), ids) + 1) % ids.length]; 
$("#" + nextId).focus(); 

Использование функции карты делает ее более кратким, чем решения, включающие итераторы.

Смежные вопросы