Question

J'ai une table générée par une boucle PHP normale. Ce que je veux faire, c'est créer un formulaire dans la première colonne de chaque ligne qui est masqué par défaut, mais qui apparaît lorsque vous cliquez sur un lien bascule dans cette ligne.

Je peux créer une division normale pouvant être basculée en créant un identifiant CSS appelé masqué et en définissant display: none; . Malheureusement, je ne peux pas continuer à créer des divs avec id = hidden qui sont automatiquement associés au lien précédent.

Je suis assez inexpérimenté avec les langages Javascript et CSS, donc j’ai surtout essayé de le faire en corrigeant des exemples, mais j’arrive vide. J'ai lu à certains endroits que vous ne pouvez pas mettre de divs à l'intérieur d'une table, alors peut-être que je m'y prends mal.

Voici un exemple de ce que fait le code et de la façon dont je souhaite qu'il fonctionne, mais ce n'est pas le cas.

<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
    }
?>
Était-ce utile?

La solution

Utilisez simplement un identifiant différent pour chaque ligne:

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

Autres conseils

Faites-en une étendue au lieu d’une DIV, car je pense que certains navigateurs ne supportent pas les div à l’intérieur des éléments de table. De plus, au lieu de s'y référer par ID, transmettez this.nextSibling () à la bascule, en utilisant la navigation DOM pour obtenir le prochain frère (qui devrait être le SPAN) à afficher / masquer.

  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>

MODIFIER : comme @tomhaigh le suggère (et comme le montre l'exemple), pour que cela fonctionne, vous devez vous assurer qu'il n'y a pas de texte / espace blanc entre l'ancre et le div. Vous pouvez également écrire une fonction qui, à partir d'un élément DOM, sélectionnerait le prochain élément DOM non textuel et le renverrait. Puis passez this à cette fonction et le résultat à votre fonction de basculement.

Voici la solution recommandée (solution générale) utilisant jQuery pour référencer les événements de manière relative au lieu de conserver des identifiants pour chaque ligne et formulaire. Cela vous permet également de masquer facilement les formulaires non actifs, ce qui est une bonne idée car un seul formulaire peut être soumis à la fois.

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>

Démo:

Vous pouvez en trouver une démonstration pratique ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top