Pregunta

Tengo una tabla generada por un bucle PHP normal. Lo que quiero hacer es crear un formulario en la primera columna de cada fila que esté oculto de manera predeterminada pero que aparezca al hacer clic en un enlace de alternancia en esa fila.

Puedo hacer un div de alternancia normal creando un id de CSS llamado oculto y configurando display: none; . Lamentablemente, no puedo seguir creando divs con id = hidden que se asocian automáticamente con el enlace anterior.

No tengo mucha experiencia con Javascript y CSS, por lo que he tratado de hacer esto parcheando ejemplos, pero estoy vacío. He leído en algunos lugares que no puedes poner divs dentro de una mesa, así que tal vez estoy haciendo todo esto mal.

Aquí hay un ejemplo de lo que hace el código y cómo me gustaría que funcionara, pero por supuesto que no.

<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
    }
?>
¿Fue útil?

Solución

Simplemente use una ID diferente para cada fila:

<?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;
}

Otros consejos

Que sea un espacio en lugar de un DIV, ya que creo que algunos navegadores no admiten divs dentro de los elementos de la tabla. Además, en lugar de referirse a él por ID, pase this.nextSibling () a la palanca, utilizando la navegación DOM para obtener el siguiente hermano (que debería ser SPAN) para mostrar / ocultar.

  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>

EDITAR : Como sugiere @tomhaigh (y como se muestra en el ejemplo), para que esto funcione, debe asegurarse de que no haya texto / espacios en blanco entre el ancla y el div. También podría escribir una función que, dado un elemento DOM, seleccionaría el siguiente elemento DOM sin texto y lo devolvería. Luego pase this a esa función y el resultado a su función de alternar.

Aquí está mi (solución general) recomendada usando jQuery para hacer referencia a eventos relativamente en lugar de mantener identificadores para cada fila y forma. Esto también le permite ocultar fácilmente los formularios de fila no activos, lo cual es una buena idea ya que solo se puede enviar un formulario a la vez.

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's sibblings and hide their forms.
        $(this).siblings().not(this).find('td.rowForm form').hide();

        // now show the current row's 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:

Puede encontrar una demostración funcional de esto aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top