51 votes

Définir le colspan dynamiquement avec jQuery

J'ai une structure de tableau simple comme celle-ci. Ce que j'aimerais faire, c'est fusionner dynamiquement certaines colonnes en fonction d'une condition dans la structure du tableau. <td> par exemple, si td1 et td3 sont vides, fusionner les cellules et faire <td class="col1" colspan="3">1Meeting</td> J'ai essayé de jouer avec jQuery en utilisant :

 $(".tblSimpleAgenda  td:contains('')").hide();

mais cela n'a eu aucun effet.

Quelle serait la meilleure façon d'utiliser jQuery pour y parvenir ?

<table  class="tblSimpleAgenda" cellpadding="5" cellspacing="0">
 <tbody>
 <th align="left">Time</th>
 <th align="left">Room 1</th>
 <th align="left">Room 2</th>
 <th align="left">Room 3</th> 

        <tr valign="top">
            <td class="colTime">09:00 – 10:00</td>
            <td class="col1"></td>
            <td class="col2">Meeting 2</td>
            <td class="col3"></td>
        </tr>

        <tr valign="top">
            <td class="colTime">10:00 – 10:45</td>
            <td class="col1">Meeting 1</td>
            <td class="col2">Meeting 2</td>
            <td class="col3">Meeting 3</td> 
        </tr>

        <tr valign="top">
            <td class="colTime">11:00 – 11:45</td>
            <td class="col1">Meeting 1</td>
            <td class="col2">Meeting 2</td>
            <td class="col3">Meeting 3</td> 
        </tr>
</tbody>
</table>

90voto

Russ Cam Points 58168

Et si

$([your selector]).attr('colspan',3);

J'imagine que cela devrait fonctionner mais je n'ai aucun moyen de le tester pour le moment. Utilisation de .attr() serait la méthode habituelle de jQuery pour définir les attributs des éléments dans l'ensemble enveloppé.

Comme cela a été mentionné dans une autre réponse, pour que cela fonctionne, il faudrait supprimer du DOM les éléments td qui ne contiennent pas de texte. Il peut être plus facile de faire tout cela côté serveur.

EDIT :

Comme il a été mentionné dans les commentaires, il y a un bogue dans la tentative de définir colspan en utilisant attr() dans IE, mais ce qui suit fonctionne dans IE6 et FireFox 3.0.13.

Démonstration de travail

remarquez l'utilisation de l'attribut colSpan et non colspan - le premier fonctionne à la fois dans IE et Firefox, mais le second ne fonctionne pas dans IE. En regardant la source de jQuery 1.3.2, il semblerait que attr() tente de définir l'attribut comme une propriété de l'élément si

  1. il existe comme une propriété sur l'élément ( colSpan existe en tant que propriété et a la valeur par défaut de 1 dans le cas de <td> HTMLElements dans IE et FireFox)
  2. le document n'est pas xml et
  3. l'attribut n'est aucun de href, src ou style

en utilisant colSpan à l'opposé de colspan travaille avec attr() car la première est une propriété définie sur l'élément alors que la seconde ne l'est pas.

la chute pour attr() est d'essayer d'utiliser setAttribute() sur l'élément en question, en fixant la valeur à une chaîne de caractères, mais cela pose des problèmes dans IE (bug #1070 dans jQuery)

// convert the value to a string (all browsers do this but IE) see #1070
elem.setAttribute( name, "" + value ); 

Dans la démo, pour chaque ligne, le texte de chaque cellule est évalué. Si le texte est une chaîne vide, alors la cellule est supprimée et un compteur est incrémenté. La première cellule de la rangée qui n'a pas de class="colTime" a un attribut colspan défini à la valeur du compteur + 1 (pour l'intervalle qu'il occupe lui-même).

Après cela, pour chaque ligne, le texte dans la cellule avec class="colspans" est défini comme la valeur de l'attribut colspan de chaque cellule de la ligne, de gauche à droite.

HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<title>Sandbox</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="screen">
body { background-color: #000; font: 16px Helvetica, Arial; color: #fff; }
td { text-align: center; }
</style>
</head>
<body>
<table  class="tblSimpleAgenda" cellpadding="5" cellspacing="0">
 <tbody>
        <tr>
            <th align="left">Time</th>
            <th align="left">Room 1</th>
            <th align="left">Room 2</th>
            <th align="left">Room 3</th> 
            <th align="left">Colspans (L -> R)</th>
        </tr>
        <tr valign="top">
            <td class="colTime">09:00 – 10:00</td>
            <td class="col1"></td>
            <td class="col2">Meeting 2</td>
            <td class="col3"></td>
            <td class="colspans">holder</td>
        </tr>

        <tr valign="top">
            <td class="colTime">10:00 – 10:45</td>
            <td class="col1">Meeting 1</td>
            <td class="col2">Meeting 2</td>
            <td class="col3">Meeting 3</td>    
             <td class="colspans">holder</td> 
        </tr>

        <tr valign="top">
            <td class="colTime">11:00 – 11:45</td>
            <td class="col1">Meeting 1</td>
            <td class="col2">Meeting 2</td>
            <td class="col3">Meeting 3</td>
            <td class="colspans">holder</td>     
        </tr>

        <tr valign="top">
            <td class="colTime">11:00 – 11:45</td>
            <td class="col1">Meeting 1</td>
            <td class="col2">Meeting 2</td>
            <td class="col3"></td>
            <td class="colspans">holder</td>     
        </tr>
</tbody>
</table>

</body>
</html>

Code jQuery

$(function() {

  $('table.tblSimpleAgenda tr').each(function() {
    var tr = this;
    var counter = 0;

    $('td', tr).each(function(index, value) {
      var td = $(this);

      if (td.text() == "") {
        counter++;
        td.remove();
      }
    });

    if (counter !== 0) {
      $('td:not(.colTime):first', tr)
        .attr('colSpan', '' + parseInt(counter + 1,10) + '');
    }
  });

  $('td.colspans').each(function(){
    var td = $(this);
    var colspans = [];

    td.siblings().each(function() {
      colspans.push(($(this).attr('colSpan')) == null ? 1 : $(this).attr('colSpan'));
    });

    td.text(colspans.join(','));
  });

});

C'est juste une démonstration pour montrer que attr() peut être utilisé, mais il faut être conscient de sa mise en œuvre et des bizarreries liées aux navigateurs qui l'accompagnent. J'ai également fait quelques suppositions sur la mise en page de votre tableau dans la démo (c'est-à-dire appliquer le colspan à la première cellule "non-Heure" de chaque ligne), mais j'espère que vous avez compris l'idée.

0 votes

Non, jQuery#attr est finalement évalué comme HTMLElement#setAttribute, ce qui ne fonctionne pas pour colspan sous IE. Il l'ignore complètement.

0 votes

Merci Russ, avec un peu de modification j'ai réussi à le faire fonctionner, malheureusement quelques conditions supplémentaires ont été ajoutées donc maintenant j'utilise un mélange de asp.net côté serveur et de jquery pour gérer le problème.

0 votes

@Terry - pas de problème ! Je pense que personnellement, cela pourrait probablement être mieux géré du côté serveur en utilisant les classes "Table" telles que TableCell, TableRow et en construisant la table à rendre dans le HTML de cette façon. En utilisant une boucle et une liste<TableCell>, il serait facile de définir l'attribut colspan sur les TableCells qui en ont besoin.

4voto

Marcos Buarque Points 1222

J'ai adapté le script de Russ Cam (merci, Russ Cam !) à mes propres besoins : J'avais besoin de fusionner toutes les colonnes qui avaient la même valeur, pas seulement les cellules vides.

Cela pourrait être utile à quelqu'un d'autre... Voici ce que j'ai trouvé :

jQuery(document).ready(function() {

   jQuery('table.tblSimpleAgenda tr').each(function() {
    var tr = this;
    var counter = 0;
    var strLookupText = '';

    jQuery('td', tr).each(function(index, value) {
      var td = jQuery(this);

      if ((td.text() == strLookupText) || (td.text() == "")) {
        counter++;
        td.prev().attr('colSpan', '' + parseInt(counter + 1,10) + '').css({textAlign : 'center'});
        td.remove();
      }
      else {
        counter = 0;
      }

      // Sets the strLookupText variable to hold the current value. The next time in the loop the system will check the current value against the previous value.
      strLookupText = td.text();

    });

  });

});

2voto

T.J. Crowder Points 285826

Vous devez supprimer entièrement l'élément vide de la cellule du tableau et modifier l'attribut colspan d'une autre cellule de la ligne pour qu'il englobe l'espace libéré, par exemple :

refToCellToRemove.remove();
refTocellToExpand.colspan = 4;

Notez que la définition de cet attribut via setAttribute (qui serait autrement correcte) ne fonctionnera pas correctement sous IE.

Attention : IE fait des choses très étranges en matière de mise en page des tableaux lorsque vous modifiez les espaces entre les colonnes de manière dynamique. Si vous pouvez l'éviter, je le ferais.

0 votes

Il peut fonctionner correctement dans IE en utilisant la fonction attr() de jQuery, comme indiqué dans ma réponse.

1voto

JayCrossler Points 568

J'ai également constaté que si vous aviez display:none, puis que vous l'avez modifié par programme pour qu'il soit visible, vous pouvez aussi avoir à définir

$tr.css({display:'table-row'});

plutôt que display:inline ou display:block, sinon la cellule pourrait n'occuper qu'une seule cellule, quelle que soit la taille du colspan.

0voto

Joshua Points 1114

Td.setAttribute('rowspan',x) ;

1 votes

IE l'ignore complètement si vous faites cela, ce qui serait autrement correct. Vous devez définir colspan comme une propriété, par exemple, theCell.colspan = 4 ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X