Toggle the display of data within a table cell

I have a table that is generated by a regular PHP loop. What I want to do is create a form in the first column of each row, which is hidden by default but appears when you click the toggle link on that row.

I can make a normal div accessible div by creating a CSS id called hidden and setting display: none;

. Unfortunately, I cannot keep creating divs id=hidden

that are automatically linked to the previous link.

I'm pretty inexperienced with both Javascript and CSS, so I basically tried to do this by copying the examples, but I came up empty. I've read in some places that you can't put a div inside a table, so maybe I'll get it all wrong.

Here's an example of what the code does and how I want it to work, but of course it doesn't.

<script language="JavaScript" type="text/javascript">
    function toggle(id) {
        var state = document.getElementById(id).style.display;
            if (state == 'block') {
                document.getElementById(id).style.display = 'none';
            } else {
                document.getElementById(id).style.display = 'block';
            }
        }
</script>


<?php

while($array = mysql_fetch_array($sql))
    {
?>
<tr>
    <td>
<?php
        echo $array['some_data'];
?>
        <a href="#" onclick="toggle('hidden');">Toggle</a>
        <div id="hidden"><?php echo $array['hidden_thing']; ?></div>
    </td>
    <td>
        <?php echo $array['some_other_data']; ?>
    </td>
</tr>
<?php
    }
?>

      

+1


source to share


3 answers


Just use a different identifier for each line:



<?php
$count = 0;
while($array = mysql_fetch_array($sql)) {
  $id = 'hidden' . $count++;
  $data = $array['some_data'];
  $hidden = $array['hidden_thing'];
  $other_data = $array['other_data'];
  echo <<<END
<tr>
  <td>$data <a href="#" onclick="toggle('$id');>Toggle</a>
    <div id="$id">$hidden_thing</div>
  </td>
  <td>$other_data</td>
</tr>

END;
}

      

+3


source


Make it a span instead of a DIV as I think some browsers don't support divs inside table elements. Also, instead of referencing it by ID, navigate this.nextSibling()

to the radio button using DOM navigation to show / hide the next sibling (which should be SPAN).

  function toggle(ctl) {
      var state = ctl.style.display;
      if (state == 'block') {
          document.getElementById(id).style.display = 'none';
      } else {
          document.getElementById(id).style.display = 'block';
      }
  }


  <a href="#" onclick="toggle(this.nextSibling);">Toggle
  </a><div><?php echo $array['hidden_thing']; ?></div>

      



EDIT . As @tomhaigh suggests (and as shown in the example), for this you need to make sure there is no text / space between the anchor and the div. You can also write a function that, given a DOM element, will select the next non-text DOM element and return it. Then pass this

that function and the result to your switch function.

+2


source


Here's my recommended (generic solution) using jQuery to match events relative to rather than preserving ids for each row and form. It also makes it easy to hide inactive row forms, which is a good idea since only one form can be submitted at a time.

HTML:

<table id="tableForms" class="table">
  <tr>
    <td class="rowForm"><form><span>form1 content</span></form></td>
    <td class="showRowForm">click on row to show its form</td>
    </tr>
  <tr>
    <td class="rowForm"><form><span>form2 content</span></form></td>
    <td class="showRowForm">click on row to show its form</td>
    </tr>
  <tr>
    <td class="rowForm"><form><span>form3 content</span></form></td>
    <td class="showRowForm">click on row to show its form</td>
    </tr>
</table>

      

JavaScript:

<script type="text/javascript" src="/assets/js/jquery.min.js"></script>
<script type="text/javascript">
//as soon as the DOM is ready, run this function to manipulate it
$(function() {
    // get all tr elements in the table 'tableForms' and bind a 
    // function to their click event
    $('#tableForms').find('tr').bind('click',function(e){
        // get all of this row sibblings and hide their forms.
        $(this).siblings().not(this).find('td.rowForm form').hide();

        // now show the current row form
        $(this).find('td.rowForm form').show();
    }).
    // now that the click event is bound, hide all of the forms in this table
    find('td.rowForm form').hide();
});
</script>

      

Demo:

A working demo of this can be found here.

+1


source







All Articles