... title ... ... title ... ... title ...

How to get the classes of a table header (th) specified in the colgroup

119 Views Asked by At

With this table,

    <table >
    <colgroup>
        <col class="classname1">
        ...
    </colgroup>

    <thead>
        <tr>
            <th class="classname2" scope="col">title</th>
            ...
        </tr>
    </thead>
    <tbody>

I can get the class name specified explicitly on the table header (th) by calling

th = document.querySelector...
th.classList // contains classname2 but not classname1

Given th, I want to obtain all classnames that apply. How can I get the class names specified in the corresponding colgroup?

3

There are 3 best solutions below

0
Peter Seliger On BEST ANSWER

An approach was to retrieve ...

  • within a first step the column specific class-names (as array of class-name arrays) while also taking a col-elements span-property into account.

  • and within a final step, while iterating the direct child-elements of a specific table-row, to create the array of each child-element's effective class-names array by merging the current element's class-names with the class-names of its related col-element (this time taking into account a child-element's colSpan-property).

function getColumnSpecificClassNames(elmTable) {
  return [
    ...elmTable
      .querySelectorAll('colgroup > col')
  ]
  .reduce((result, { span, classList }) => {

    while (span--) {
      result
        .push([...classList]);
    }
    return result;

  }, []);
}
function getRowChildrenEffectiveClassNames(elmTr) {
  const columnClassLists = getColumnSpecificClassNames(
    elmTr.closest('table')
  );
  return [
    ...elmTr.children
  ]
  .reduce(({ result, colCount = 0 }, { colSpan, classList }) => {

    result
      .push([...columnClassLists[colCount], ...classList]);

    return { result, colCount: colCount + colSpan };

  }, { result: [] }).result;
}

console.log(
  'column specifc class names ...',
  getColumnSpecificClassNames(
    document.querySelector('table')
  ),
)
console.log(
  'row children effective class names ...',
  getRowChildrenEffectiveClassNames(
    document.querySelector('table > tbody > tr')
  ),
)
.batman {
  background-color: #d7d9f2;
}
.flash {
  background-color: #ffe8d4;
}

caption {
  padding: 8px;
  caption-side: bottom;
}
table {
  width: 49%;
  border-collapse: collapse;
  border: 2px solid rgb(100, 100, 100);
  letter-spacing: 1px;
  font-family: sans-serif;
  font-size: 0.7rem;
}
td,
th {
  border: 1px solid rgb(100, 100, 100);
  padding: 10px 10px;
}
td {
  text-align: center;
}
.as-console-wrapper {
    left: auto!important;
    min-height: 100%;
    width: 50%;
}
<table>
  <caption>
    <p>Superheros and sidekicks<P>
    <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup">
      https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup
    </a>
  </caption>
  <colgroup>
    <col />
    <col span="2" class="batman" />
    <col span="2" class="flash" />
  </colgroup>
  <tr>
    <td> </td>
    <th scope="col">Batman</th>
    <th scope="col" class="robin">Robin</th>
    <th scope="col">The Flash</th>
    <th scope="col" class="kid-flash">Kid Flash</th>
  </tr>
  <tr>
    <th scope="row">Skill</th>
    <td>Smarts</td>
    <td>Dex, acrobat</td>
    <td>Super speed</td>
    <td>Super speed</td>
  </tr>
</table>

0
B Meirelles On

You can assign an 'id' to the colgroup you want, then use:

const colGroup = document.getElementById("yourId")

const yourClasses = colGroup.classList.

It will return an array with all the element classes.

0
0stone0 On

If I understand you correctly you can search for the index of your targeted <th> inside it's parent <tr>. Then loop over each <col> and keep track of the (number + span). If that exceeds the index found before, you have the correct <col>

const th = document.querySelector('.special_th');
const th_row_index = Array.from(th.parentNode.children).indexOf(th)
const all_col = [ ...document.querySelectorAll('colgroup > col') ];

let n = 0;
console.log('Searching for matching <col> that belonges to the <th> on index', th_row_index)
for (let c = 0; c < th_row_index; c++) {
    n += all_col[c].span;
    if (th_row_index <= n) {
        console.log('Found matching <col> with the following class:', all_col[c].className);
        break;
    }  
}
table, th, td {
  border: 1px solid black;
}

.special_th {
  color: purple;
}
<table>
  <colgroup>
    <col class="special_col_1" span="2" style="background-color:red">
    <col class="special_col_2" style="background-color:yellow">
  </colgroup>
  <tr>
    <th>ISBN</th>
    <th class="special_th">Title</th>
    <th>Price</th>
  </tr>
  <tr>
    <td>3476896</td>
    <td>My first HTML</td>
    <td>$53</td>
  </tr>
  <tr>
    <td>5869207</td>
    <td>My first CSS</td>
    <td>$49</td>
  </tr>
</table>