By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,255 Members | 2,575 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,255 IT Pros & Developers. It's quick & easy.

Hide/Show Rows based on text box input

P: n/a
I have a table with 10 rows, I want all rows except for the first to be
hidden when the page first opens up. If the user puts a value in a
text box in the first row then I want the second row to display. If
they put a value in the text box in the second row then display the
third row etc. etc. etc. to 10 rows. I'm pretty new to javascript, so
I'm not to sure where to start. Any help would be great, thanks a lot.

Apr 17 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a

<ji***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
I have a table with 10 rows, I want all rows except for the first to be
hidden when the page first opens up. If the user puts a value in a
text box in the first row then I want the second row to display. If
they put a value in the text box in the second row then display the
third row etc. etc. etc. to 10 rows. I'm pretty new to javascript, so
I'm not to sure where to start. Any help would be great, thanks a lot.

Try this approach.
Give the first <tr> tag an ID of say, "row1".
Give tthe second <tr> tag -> like this: <tr id="row2"
style="visibility:hidden;"> ...your stuff ... </tr>
Give the third tr tag an id of "row3".
(etc)
set the visibility of all rows you want hidden in the tag.

Then for the text box inside the FIRST row:
<input type='text' name='firstname' id='firstname'
onchange='makeItShow("row2",this)' />

which would call this function: (not tested )
//***********************************
function makeItShow(someRow, theTextBox){
if (theTextBox.value != ""){
var nextRow = document.getElementById(someRow);
nextRow.style.visiblility = "visible";
}else {
nextRow.style.visibility="hidden";
}
}
//**************************************
Each text box would send the id of the next row to the function.
Try variations of this, and you should have a starting point.
HTH
Hal
Apr 18 '06 #2

P: n/a
Hal Rosser said on 18/04/2006 11:19 AM AEST:
<ji***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
I have a table with 10 rows, I want all rows except for the first to be
hidden when the page first opens up. If the user puts a value in a
text box in the first row then I want the second row to display. If
they put a value in the text box in the second row then display the
third row etc. etc. etc. to 10 rows. I'm pretty new to javascript, so
I'm not to sure where to start. Any help would be great, thanks a lot.


Try this approach.
Give the first <tr> tag an ID of say, "row1".
Give tthe second <tr> tag -> like this: <tr id="row2"


I'd not bother with IDs, just use the row index. Get the row index of
the current row, and set the next one visible (if there is one).
e.g.

<title>Show Rows</title>

<style type="text/css">
#fred {visibility: hidden;}
</style>

<table>
<tbody>
<tr>
<td><input onkeypress="showNext(this);">
<tbody id="fred">
<tr>
<td><input onkeypress="showNext(this);">
<tr>
<td><input onkeypress="showNext(this);">
</table>

<script type="text/javascript">
function showNext(el) {
function getTR(el) {
while (el.parentNode && 'tr' != el.nodeName.toLowerCase()){
el = el.parentNode;
}
return ('tr' == el.nodeName.toLowerCase())? el : null;
}
var row = getTR(el);
if (row){
var t = row.parentNode.parentNode;
var nRow = t.rows[row.rowIndex + 1];
if (nRow && nRow.style){
nRow.style.visibility = 'visible';
}
}
}
</script>

Of course the style should be set with script so that the rows are
visible by default.

Another strategy is to also add the onkeypress functions onload, then
each could explicitly set the following row to visible.

Seems to me the logic here could get quite convoluted trying to work out
which rows to show and hide - should a row be hidden if it has no
content? Should subsequent rows be hidden too? How does a user know
how many rows are hidden?

The usual trick is to put a button (or similar element) on the row to
show/hide the next one so the user is in control. It greatly reduces
the complexity of scripting logic.
--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 18 '06 #3

P: n/a
Hal Rosser wrote:
<ji***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
I have a table with 10 rows, I want all rows except for the first to be
hidden when the page first opens up. If the user puts a value in a
text box in the first row then I want the second row to display. If
they put a value in the text box in the second row then display the
third row etc. etc. etc. to 10 rows. I'm pretty new to javascript, so
I'm not to sure where to start. Any help would be great, thanks a lot.


Try this approach.
Give the first <tr> tag an ID of say, "row1".
Give tthe second <tr> tag -> like this: <tr id="row2"
style="visibility:hidden;"> ...your stuff ... </tr>


Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.
Apr 18 '06 #4

P: n/a

"Tony" <to****@dslextreme.WHATISTHIS.com> wrote in message
news:12*************@corp.supernews.com...
Hal Rosser wrote:
<ji***********@gmail.com> wrote in message
news:11**********************@i39g2000cwa.googlegr oups.com...
I have a table with 10 rows, I want all rows except for the first to be
hidden when the page first opens up. If the user puts a value in a
text box in the first row then I want the second row to display. If
they put a value in the text box in the second row then display the
third row etc. etc. etc. to 10 rows. I'm pretty new to javascript, so
I'm not to sure where to start. Any help would be great, thanks a lot.


Try this approach.
Give the first <tr> tag an ID of say, "row1".
Give tthe second <tr> tag -> like this: <tr id="row2"
style="visibility:hidden;"> ...your stuff ... </tr>


Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.


I agree - so another solution may be to use display = none or inline.
Someone emailed me with that suggestion, and it sounds good too.
Apr 18 '06 #5

P: n/a
Hal Rosser wrote:
"Tony" <to****@dslextreme.WHATISTHIS.com> wrote in message
news:12*************@corp.supernews.com...
Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.


I agree - so another solution may be to use display = none or inline.
Someone emailed me with that suggestion, and it sounds good too.


Be sure to test that - I've found some glitches when changing the
display value at times - such as one case in Firefox when it didn't
collapase the row when I changed it to display:none

This particular glitch may have been context-related - I'm just sharing
so that you can watch out for it.
Apr 18 '06 #6

P: n/a
JRS: In article <B5*****************@bignews7.bellsouth.net>, dated
Mon, 17 Apr 2006 21:19:33 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :
function makeItShow(someRow, theTextBox){
if (theTextBox.value != ""){
var nextRow = document.getElementById(someRow);
nextRow.style.visiblility = "visible";
}else {
nextRow.style.visibility="hidden";
}
}


It's generally a bad idea to duplicate code, even quite small parts,
unnecessarily - it introduces more room for error - for example, only
one attempt at spelling "visibility" is needed.

This

function makeItShow(someRow, theTextBox){ // set NextRow vis'y
document.getElementById(someRow).style.visibility =
theTextBox.value != "" ? "visible" : "hidden" }

expresses what I think you meant to express, clarifies that the
visibility of one thing is set independently of its previous state, and
leaves no room for not setting NextRow in the "hide" case.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 19 '06 #7

P: n/a

"Dr John Stockton" <jr*@merlyn.demon.co.uk> wrote in message
news:z7**************@merlyn.demon.co.uk...
JRS: In article <B5*****************@bignews7.bellsouth.net>, dated
Mon, 17 Apr 2006 21:19:33 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :
function makeItShow(someRow, theTextBox){
if (theTextBox.value != ""){
var nextRow = document.getElementById(someRow);
nextRow.style.visiblility = "visible";
}else {
nextRow.style.visibility="hidden";
}
}


It's generally a bad idea to duplicate code, even quite small parts,
unnecessarily - it introduces more room for error - for example, only
one attempt at spelling "visibility" is needed.

This

function makeItShow(someRow, theTextBox){ // set NextRow vis'y
document.getElementById(someRow).style.visibility =
theTextBox.value != "" ? "visible" : "hidden" }

expresses what I think you meant to express, clarifies that the
visibility of one thing is set independently of its previous state, and
leaves no room for not setting NextRow in the "hide" case.


I started to "play a John" with a 1-liner (or so) - but the intention was to
make it clear and understandable to the OP, - or someone reading the posting
as a pseudo-tutorial - and now, with your condensed version - and the
advantages thereof - they can start off understanding - then work on
improving their code from the bottom -drudging-inefficient code like mine to
the clearly more compact and efficient and easier-to-maintain code like
yours. :-)
Oh - is it true that too much documentation is bad because of the
additional server load ?
Apr 21 '06 #8

P: n/a
On 2006-04-19 00:27:30 +0200, Tony <to****@dslextreme.WHATISTHIS.com> said:
Hal Rosser wrote:
"Tony" <to****@dslextreme.WHATISTHIS.com> wrote in message
news:12*************@corp.supernews.com...
Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.
I agree - so another solution may be to use display = none or inline.
Someone emailed me with that suggestion, and it sounds good too.


yep - just don't forget the normal display for a tr is neither block
nor inline, it's table-row.

you could also write your rows like this, with no ids for each tr nor
inline event handlers (which are ugly anyway) :

<tbody id="whatever">
<tr>
<td>...<input type="text"></td>
</tr>
<tr>
<td>...<input type="text"></td>
</tr>
...etc...
</tbody>

that way, a client with JavaScript disabled (I shiver to think that
some people forsake the wonderful language that is JavaScript !) will
display all the 10 rows (so you can proudly say your page is
accessible).
Besides, and more importantly (from the coder's point of view) the HTML
code is simpler.

then in a script :

// define the function to assign as an event handler
function showNext(event)
{
this.parentNode.parentNode.nextSibling.style.displ ay
= this.value ? "table-row" : "none"
return true
}

myBody = document.getElementById("whatever")

// the loop starts at i=1
for(i=1; myBody.rows[i]; i++)
{
// initially hide all rows but the first
myBody.rows[i].style.display='none'

// set the event handler for all rows's inputs but the last
myBody.rows[i-1].getElementsByTagName("input")[0].onkeypress = showNext
// assuming there is only one input in the rows
// otherwise it's easy to adapt the code
}

you can even use this loop to implement nextSibling if it's not
supported by the browser. Just add this :

if(! myBody.rows[i-1].nextSibling)
myBody.rows[i-1].nextSibling=myBody.rows[i]

Be sure to test that - I've found some glitches when changing the
display value at times - such as one case in Firefox when it didn't
collapase the row when I changed it to display:none

This particular glitch may have been context-related - I'm just sharing
so that you can watch out for it.


I also have problems with Firefox and display:none on table rows. In
the application I'm developing, I dynamically hide rows from a table
and then make them reappear, setting their style.display to 'none' or
'table-row'. Firefox behaves correctly when hiding rows, but does not
redraw them when their style.display returns to normal. The user has to
scroll the table (the tbody in my app has overflow:scroll) to make
Firefox redraw missing rows.

Completely removing the rows from the table (with removeChild) and
appending them back works fine, but it's a lot more hassle. I haven't
had time to test it yet, but I suspect you could use style to
hide/display rows, and then force Firefox to redraw the tbody by
quickly adding then removing a row (preferably as the first row of the
table so it pushes all the other rows down - a browser just can't do
that and *not* redraw).
--
David Junger

Apr 21 '06 #9

P: n/a
Touffy said on 21/04/2006 2:10 PM AEST:
On 2006-04-19 00:27:30 +0200, Tony <to****@dslextreme.WHATISTHIS.com> said:
Hal Rosser wrote:
"Tony" <to****@dslextreme.WHATISTHIS.com> wrote in message
news:12*************@corp.supernews.com...

Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.
I agree - so another solution may be to use display = none or inline.
Someone emailed me with that suggestion, and it sounds good too.


yep - just don't forget the normal display for a tr is neither block nor
inline, it's table-row.

you could also write your rows like this, with no ids for each tr nor
inline event handlers (which are ugly anyway) :

<tbody id="whatever">
<tr>
<td>...<input type="text"></td>
</tr>
<tr>
<td>...<input type="text"></td>
</tr>
...etc...
</tbody>

that way, a client with JavaScript disabled (I shiver to think that some
people forsake the wonderful language that is JavaScript !) will display
all the 10 rows (so you can proudly say your page is accessible).
Besides, and more importantly (from the coder's point of view) the HTML
code is simpler.

then in a script :

// define the function to assign as an event handler
function showNext(event)
{
this.parentNode.parentNode.nextSibling.style.displ ay


That presumes that you know exactly how many nodes are in the relevant
part of the tree. Note that IE and other browsers differ on #text nodes
inserted between table rows (depending on the markup) so the use such
relationships will likely break in one browser or the other.

It is much better to put the onclick on the row, get the rowIndex
property, then show or hide the appropriate row based on its rowIndex
property.

It also avoids the differences between IE and W3C event models.

= this.value ? "table-row" : "none"
That will screw-up on browsers that don't understand table-row
(including the one used by the majority of web users). Use:

... = (row.style.display == 'none')? '': 'none';

return true
}

myBody = document.getElementById("whatever")

// the loop starts at i=1
for(i=1; myBody.rows[i]; i++)
{
// initially hide all rows but the first
myBody.rows[i].style.display='none'

// set the event handler for all rows's inputs but the last
myBody.rows[i-1].getElementsByTagName("input")[0].onkeypress = showNext
So when i is 1, you will set the handler on the 0th row, which you
didn't want to do. If you want to avoid the last, use:

for(var i=1, n=myBody.rows.length-1; i<n; i++)
Incidentally, for the rows collection you should be using a table
object, there is no separate interface for the tbody object, though
there is a tbodies collection.

// assuming there is only one input in the rows
// otherwise it's easy to adapt the code
}

you can even use this loop to implement nextSibling if it's not
supported by the browser. Just add this :

if(! myBody.rows[i-1].nextSibling)
That may refer to a #text node or the same row as myBody.rows[i].
myBody.rows[i-1].nextSibling=myBody.rows[i]
A 'next sibling' could be better as:

var nextRow = myBody.rows[i+1];
if (nextRow){
// there was a next row
}

or if 'currentRow' refers to some row of the table:

var nextRow = table.rows[currentRow.rowIndex + 1];
if (nextRow){
...


Be sure to test that - I've found some glitches when changing the
display value at times - such as one case in Firefox when it didn't
collapase the row when I changed it to display:none

This particular glitch may have been context-related - I'm just
sharing so that you can watch out for it.

I also have problems with Firefox and display:none on table rows. In the
application I'm developing, I dynamically hide rows from a table and
then make them reappear, setting their style.display to 'none' or
'table-row'. Firefox behaves correctly when hiding rows, but does not
redraw them when their style.display returns to normal. The user has to
scroll the table (the tbody in my app has overflow:scroll) to make
Firefox redraw missing rows.

Completely removing the rows from the table (with removeChild) and
appending them back works fine, but it's a lot more hassle. I haven't
had time to test it yet, but I suspect you could use style to
hide/display rows, and then force Firefox to redraw the tbody by quickly
adding then removing a row (preferably as the first row of the table so
it pushes all the other rows down - a browser just can't do that and
*not* redraw).


--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 21 '06 #10

P: n/a
On 2006-04-21 09:47:41 +0200, RobG <rg***@iinet.net.au> said:
Touffy said on 21/04/2006 2:10 PM AEST:
you could also write your rows like this, with no ids for each tr nor
inline event handlers (which are ugly anyway) :

<tbody id="whatever">
<tr>
<td>...<input type="text"></td>
</tr>
<tr>
<td>...<input type="text"></td>
</tr>
...etc...
</tbody>

that way, a client with JavaScript disabled (I shiver to think that
some people forsake the wonderful language that is JavaScript !) will
display all the 10 rows (so you can proudly say your page is
accessible).
Besides, and more importantly (from the coder's point of view) the HTML
code is simpler.

then in a script :

// define the function to assign as an event handler
function showNext(event)
{
this.parentNode.parentNode.nextSibling.style.displ ay
That presumes that you know exactly how many nodes are in the relevant
part of the tree.


Indeed. I do presume the tree looks like this :
<tbody>
<tr>
<td>
<input>

and in case it isn't, the developer will only need to add another
..parentNode in the expression. That doesn't seem overly inconvenient.
Note that IE and other browsers differ on #text nodes inserted between
table rows (depending on the markup) so the use such relationships will
likely break in one browser or the other.
Pesky empty text nodes show up in the childNodes collection, I'm aware
of that. Are you sure they also pollute the rows collection, which is
supposed to hold only the table rows (hence its name) ?
I can't test in IE right now, but Firefox and Safari don't count text
nodes as rows.
It is much better to put the onclick on the row
I suppose you meant onkeypress ?
, get the rowIndex property, then show or hide the appropriate row
based on its rowIndex property.
Yet you still have to access the text input inside the row to see if
you must actually hide the next row. If you can do that, stepping back
to the row shouldn't be an issue. It's actually much easier to move
back in the tree, than forward.
It also avoids the differences between IE and W3C event models.
I did write out the implicit "event" argument passed to event handlers
in the W3C model, but I don't use it. It's a way to tell that the
function is an event handler.
I haven't tested anything in IE in months... doesn't "this" also refer
to the event handler's owner (the target of the event) in IE ?
= this.value ? "table-row" : "none"


That will screw-up on browsers that don't understand table-row
(including the one used by the majority of web users). Use:

... = (row.style.display == 'none')? '': 'none';

return true
}

myBody = document.getElementById("whatever")

// the loop starts at i=1
for(i=1; myBody.rows[i]; i++)
{
// initially hide all rows but the first
myBody.rows[i].style.display='none'
// set the event handler for all rows's inputs but the last
myBody.rows[i-1].getElementsByTagName("input")[0].onkeypress = showNext


So when i is 1, you will set the handler on the 0th row, which you
didn't want to do.


But I did ! the first row is always displayed, but it does need an
event handler to display the second row when some text is entered in
the input it contains.
Incidentally, for the rows collection you should be using a table
object, there is no separate interface for the tbody object, though
there is a tbodies collection.
What do you mean by "there is no separate interface" ? that I'm not
supposed to assign style such as overflow:scroll to a tbody ? the W3C
spec actually implies that scrolling tbodies with always-visible thead
and tfoot may be a good idea and that browsers may implement it as
default behavior.
// assuming there is only one input in the rows
// otherwise it's easy to adapt the code
}

you can even use this loop to implement nextSibling if it's not
supported by the browser. Just add this :
if(! myBody.rows[i-1].nextSibling)


That may refer to a #text node or the same row as myBody.rows[i].


unless the rows collection includes text nodes, it may not.
myBody.rows[i-1].nextSibling=myBody.rows[i]


A 'next sibling' could be better as:

var nextRow = myBody.rows[i+1];
if (nextRow){
// there was a next row
}


look again at my for() statement. It says :

for(i=1; myBody.rows[i]; i++)

so if the block is executed, then we already know that there IS a
row[i] and a row[i-1] (since it starts at i=1).
--
David Junger

Apr 21 '06 #11

P: n/a
Touffy wrote:
On 2006-04-19 00:27:30 +0200, Tony <to****@dslextreme.WHATISTHIS.com> said:
Hal Rosser wrote:
"Tony" <to****@dslextreme.WHATISTHIS.com> wrote in message
news:12*************@corp.supernews.com...

Be aware that visibility:hidden will still display the SPACE for the
row, just not the contents. That's fine if that's what the OP wants to
achieve.
I agree - so another solution may be to use display = none or inline.
Someone emailed me with that suggestion, and it sounds good too.

yep - just don't forget the normal display for a tr is neither block nor
inline, it's table-row.


Good point. When you change the display to make the item visible, it's
probably best to use something like: element.style.display = '';

That way it assumes its default display setting.
Apr 21 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.