web-dev-qa-db-fra.com

Définir dynamiquement colspan avec jquery

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

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

mais cela n'a pas eu d'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> 
47
Terry Marder

Que diriez-vous

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

J'imagine que ça marche mais je n'ai aucun moyen de tester pour le moment. Utiliser .attr() serait la manière jQuery habituelle de définir les attributs des éléments dans l'ensemble encapsulé.

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

MODIFIER:

Comme mentionné dans les commentaires, il y a un bogue dans la tentative de définition de colspan en utilisant attr () dans IE, mais les opérations suivantes fonctionnent dans IE6 et FireFox 3.0.13.

Démo de travail

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

  1. il existe en tant que propriété sur l'élément (colSpan existe en tant que propriété et vaut par défaut 1 sur <td> HTMLElements dans IE et FireFox)
  2. le document n'est pas xml et
  3. l'attribut n'est ni href, ni src, ni style

l'utilisation de colSpan par opposition à colspan fonctionne 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 solution pour attr() est d'essayer d'utiliser setAttribute() sur l'élément en question, en définissant la valeur sur une chaîne, mais cela provoque des problèmes dans IE (bogue n ° 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, la cellule est supprimée et un compteur incrémenté. La première cellule de la ligne qui n'a pas class="colTime" A un attribut colspan défini sur la valeur du compteur + 1 (pour la plage qu'il occupe).

Après cela, pour chaque ligne, le texte de la cellule avec class="colspans" Est défini sur les valeurs d'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(','));
  });

});

Ceci est juste une démonstration pour montrer que attr() peut être utilisé, mais pour être conscient de son implémentation et des bizarreries entre navigateurs qui l'accompagnent. J'ai également fait quelques hypothèses sur la disposition de votre tableau dans la démo (c'est-à-dire appliquer le colspan à la première cellule "non-Time" de chaque ligne), mais j'espère que vous aurez l'idée.

84
Russ Cam

J'ai adapté le script de Russ Cam (merci Russ Cam!) À mes propres besoins: je devais 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();

    });

  });

});
4
Marcos Buarque

Vous avez dit rowpan dans votre titre, mais j'ai l'impression que vous vouliez dire colspan; excuses si ce qui suit est éteint parce que je me trompe.

Vous devez supprimer complètement l'élément de cellule de tableau vide et modifier l'attribut colspan sur une autre cellule de la ligne pour englober l'espace libéré, par exemple:

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

Notez que le définir via setAttribute (qui serait sinon correct) ne fonctionnera pas correctement sur IE.

Méfiez-vous: IE fait des choses de mise en page de table très étranges lorsque vous vous trompez avec colspans dynamiquement. Si vous pouvez l'éviter, je le ferais.

2
T.J. Crowder

J'ai également constaté que si vous aviez display: none, puis que vous l'avez modifié par programme pour qu'il soit visible, vous devrez peut-être également définir

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

plutôt que display: inline ou display: block sinon la cellule pourrait ne montrer que comme occupant 1 cellule, quelle que soit la taille du colspan.

1
JayCrossler

Réglage colspan="0" n'est pris en charge que dans Firefox.

Dans d'autres navigateurs, nous pouvons le contourner avec:

// Auto calculate table colspan if set to 0
var colCount = 0;
$("td[colspan='0']").each(function(){
    colCount = 0;
    $(this).parents("table").find('tr').eq(0).children().each(function(){
        if ($(this).attr('colspan')){
            colCount += +$(this).attr('colspan');
        } else {
            colCount++;
        }
    });
$(this).attr("colspan", colCount);
});

http://tinker.io/3d642/4

0
John Magnolia

td.setAttribute ('rowpan', x);

0
Joshua