Aba Aba - 7 months ago 35
Javascript Question

jQuery .next() not returning next element

I'm trying to use jQuery's .next() function to get the next element with

class="inputfield"
but all I'm getting is
[]
.

If you click on the empty cell the input element is displayed (function click_td(td_id)/ open_input(inputObj)).

When exiting the element it disappears leaving the text (function close_input(inputObj)).

By pressing tab I want to move to the next element (function next_cell(inputObj)).

Thanks,
Aba

<script language="javascript" type="text/javascript" src="/_inc/jquery/jquery.js"></script>
<style type="text/css">
.inputfield{
display: none;
}
</style>
<table cellspacing="0" cellpadding="2" border="1" width="50%">
<tr>
<td width="15%">Name</td>
<td width="35%" onclick="click_td(this)" id="1_1"><span id="si1_1" style=""></span><input type="text" onblur="close_input(this);" onkeydown="if (event.keyCode==13) return false;if (event.keyCode==9) return next_cell(this)" size="25" value="" name="name" id="i1_1" class="inputfield"></td>
<td width="15%">E-mail</td>
<td width="35%" onclick="click_td(this)" id="1_2"><span id="si1_2"></span><input type="text" onblur="close_input(this);" onkeydown="if (event.keyCode==13) return false;if (event.keyCode==9) return next_cell(this)" size="25" value="" name="email" id="i1_2" class="inputfield"></td>
</tr>
<tr>
<td>Phone</td>
<td onclick="click_td(this)" id="2_1"><span id="si2_1"></span><input type="text" onblur="close_input(this);" onkeydown="if (event.keyCode==13) return false;if (event.keyCode==9) return next_cell(this)" size="25" value="" name="phone" id="i2_1" class="inputfield"></td>
<td>Type:<br>
</td><td onclick="click_td(this)" id="2_2"><span id="si2_2"></span>
<select onblur="close_input(this);" onkeydown="if (event.keyCode==13) return false;if (event.keyCode==9) return next_cell(this)" name="article_type" id="i2_2" class="inputfield">
<option value=""></option>
<option>Buying Guide</option>
<option>Announcement</option>
<option>Hands-on Review</option>
</select>
</td>
</tr>
</tbody>
</table>

<script LANGUAGE="JavaScript">
<!--
function click_td(td_id){
var inputObj = document.getElementById('i' + td_id.id);
open_input(inputObj)
}

function open_input(inputObj){
var spanObj = document.getElementById('s' + inputObj.id)
inputObj.style.display = 'block';
spanObj.style.display = 'none';
inputObj.focus();
}

function close_input(inputObj){
var spanObj = document.getElementById('s' + inputObj.id)
switch (inputObj.type){
case 'select':
spanObj.innerHTML = inputObj.options[inputObj.selectedIndex].value;
break;
case 'text':
default:
spanObj.innerHTML = inputObj.value;
break;
}
inputObj.style.display = 'none';
spanObj.style.display = '';
}

function next_cell(inputObj){
next_inputObj = $(inputObj).next('.inputfield');
console.log(next_inputObj);
open_input(next_inputObj)
}
</script>

Answer

I've finished work on my fiddle to highlight the problem

http://jsfiddle.net/k77Ya/6/

var next_inputObj = $(inputObj).next('.inputfield');
console.log(next_inputObj.length);

Essentially, it boils down to the .next() operator not being able to find the class you've suggested. This is because the .next() operator will look for the next item with the class "inputField" in the that you're in at that point which, of course, doesn't exist so the .next() operator always returns an empty array.

As an aside, the HTML you posted is missing an opening tag, but that's not the issue here. If you chain together some .parent() operators, you can get the correct level and go from there e.g.

var next_inputObj = $(inputObj).parent().next('.inputfield');

EDIT: It's pretty much there now; you can tab between the two boxes at the top and the two at the bottom. It requires some extra code to navigate to the next when you've reached the last element in the list.

One of the issues was that pressing tab fires a blur event which was affecting the ability to tab between inputs on the page. I'd recommend preventing this functionality by calling the preventDefault() method on the event as below. To implement this, I used the jQuery event handlers as you were replicating code in your inputs - documentation found here: http://api.jquery.com/blur/ and http://api.jquery.com/keydown/

event.preventDefault();

This should now provide a working solution, hope that helps!