What is the best way to assign a unique ID to every element in this situation?

Here is the given code:

var words = ['ac', 'bd', 'bf', 'uy', 'ca'];

document.getElementById("wordTable").innerHTML = arr2tbl(2);

function arr2tbl(ncols) {
  return words.reduce((a, c, i) => {
    if (i % ncols == 0) a.push([]);
    a.at(-1).push(c);
    return a;
  }, []).map(r => "<tr>" + r.map(c => `<td>${c}</td>`).join("") + "</tr>").join("\n");
}
<table id="wordTable"></table>

The above code generates this table:

<table>
<tr>
<td>ac</td> <td>bd</td>
</tr>
<tr>
<td>bf</td> <td>uy</td>
</tr>
<tr>
<td>ca</td><td></td>
</tr>
</table>

I need to assign an id for each word so I can style them dynamically. The desired formatting should look like this:

<table>
<tr>
<td id="1">ac</td>  <td id="2">bd</td>
</tr>
<tr>
<td id="3">bf</td>  <td id="4">uy</td>
</tr>
<tr>
<td id="5">ca</td><td></td>
</tr>
</table>

To enable flexible styling with a function like this:

function formatWord(wordID){
  document.getElementById(wordID).style.color = "red";
}

Users can randomly call formatWord(2); formatWord(5);...

If assigning ids to "td" elements is not possible, it doesn't matter as long as we can apply dynamic styles to the words in the table.

How can I add an id to each element in this scenario?

Answer №1

Here's a simpler way to generate a table using JavaScript instead of innerHTML

arr2tbl( 
  ['ac', 'bd', 'bf', 'uy', 'ca'], 
  document.querySelector(`#wordTable`), 
  2 );

document.querySelector(`pre`).textContent = 
  document.querySelector(`#wordTable`).outerHTML;

function arr2tbl(words, forTable, ncols) {
  let currentRow = document.createElement(`tr`);
  forTable.append(currentRow);
  
  words.forEach( (word, i) => {
     if (i > 0 && i % ncols === 0) {
        forTable.append(currentRow.cloneNode());
     }
     
     forTable.querySelector(`tr:last-child`).append(
      Object.assign( document.createElement(`td`), 
      { id: i + 1, textContent: word } ) );
  });
}
<table id="wordTable"></table>
<h3>The table html</h3>
<pre></pre>

Answer №2

When we use the reduce function, it is possible to pass the index value into the array.

var words=['ac', 'bd', 'bf','uy','ca'];

let result = arrToTable(2)
console.log(result)
document.getElementById("wordTable").innerHTML=result;

function arrToTable(ncols){
 return words.reduce((a,c,i)=>{
 if(i%ncols==0)a.push([]);
   a.at(-1).push([c,i+1]);
   return a;
  },[]).map(r=>"<tr>"+r.map(c=>`<td id="${c[1]}">${c[0]}</td>`).join("")+"</tr>").join("\n");
}
<table id="wordTable"></table>

Answer №3

If you want to share the position of a word, you can do it by passing the index like this:

let words = ['one', 'two', 'three', 'four', 'five'];

document.getElementById('wordTable').innerHTML = createTable(2);

function createTable(ncols){
 return words.reduce((a,c,i)=>{
 if(i%ncols==0)a.push([]);
   a.at(-1).push([c, (i + 1)]);
   return a;
  },[]).map(r=>"<tr>"+r.map(c=>`<td id="${c[1]}">${c[0]}</td>`).join("")+"</tr>").join("\n");
}
<table id="wordTable" border="1"></table>

Answer №4

If you want to simplify the process, consider creating a variable called index and incrementing it during your chosen iteration.

var words = ['ac', 'bd', 'bf', 'uy', 'ca'];

        document.getElementById("wordTable").innerHTML = createTable(2);

        function createTable(columns) {
            var index = 1;
            return words.reduce((acc, current, i) => {
                if (i % columns === 0) acc.push([]);
                acc.at(-1).push(current);
                return acc;
            }, []).map(row => "<tr>" + row.map(col => `<td id=${index++}>${col}</td>`).join("") + "</tr>").join("\n");
        }
<table id="wordTable"></table>

Best of luck with your code!

Answer №5

I find this much easier to digest.

Personally, I wouldn't opt for numeric IDs but rather something along the lines of

const idx = `row-${rowStartIndex}-cell${cellIndex}`;

const words = ['ac', 'bd', 'bf', 'uy', 'ca'];

const arr2tbl = (ncols) => {
  // Determine the number of rows required
  const nrows = Math.ceil(words.length / ncols);

  // Generate an array of rows using Array.from function argument
  return Array.from({ length: nrows }, (_, rowIndex) => {
    // Calculate start index of current row in original array
    const rowStartIndex = rowIndex * ncols;

    // For each row, create an array of cell strings
    const cells = words.slice(rowStartIndex, rowStartIndex + ncols)
      .map((word, cellIndex) => {
        // Calculate word's index in original array for ID
        const idx = (rowStartIndex + cellIndex)+1; // one based
        // const idx = `row-${rowStartIndex}-cell${cellIndex}`;
        return `<td id="${idx}">${word}</td>`;
      })
      .join(''); // Combine cell strings into a row

    return `<tr>${cells}</tr>`; // Enclose row cells in <tr> tags
  }).join('\n');
};
document.getElementById("wordTable").innerHTML = arr2tbl(2);
<table>
  <tbody id="wordTable"></tbody>
</table>

Answer №6

An easy way to improve your code is by first mapping the cells before generating the rows as shown in the example below:

var words = ['ac', 'bd', 'bf', 'uy', 'ca'];

document.getElementById("wordTable").innerHTML = arr2tbl(2);

function arr2tbl(ncols) {
  return words
    .map((word, index) => `<td id="${index + 1}">${word}</td>`)
    .reduce((a, c, i) => {
      if (i % ncols == 0) a.push([]);
      a.at(-1).push(c);
      return a;
    }, [])
    .map((row) => "<tr>" + row.join("") + "</tr>").join("\n");
}
<table id="wordTable"></table>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered: Failure to locate module 'socket.io' while attempting to execute a basic server JavaScript file

Below is my server.js file that I am attempting to run using node server.js: var app = require('express')(); var http = require('http').createServer(app); var io = require('socket-io')(http); //also tried socket.io instead of ...

In Angular, the ng-click directive that assigns the value of tab to $index does not seem to be functioning properly

I encountered an issue within my app <li ng-repeat="name in tabs track by $index" ng-class="{selected: tab==$index}" ng-click="tab = $index">{{name}}</li> After clicking on each item, the selected class remains enabled and switching to anothe ...

Is it feasible to verify for vacant dates with a single click?

Is there a way to determine if a date value is empty, and if it is, display a popup indicating so? After some research, I stumbled upon a similar issue where the date value was always filled with a default "mm/dd/yyyy" value. The solution provided involv ...

Can certain parts of an MP4 file be accessed remotely through a network connection?

With modern MP4 players, you have the ability to skip to any part of a video without needing to download the entire file. Take a look at this example video: You can navigate to any point in the video before it finishes downloading. I am curious if there ...

Tips for identifying when a change has been made to a SCSS file or any of its partial files

Looking to incorporate sass into a Ruby script but want to compile only when necessary. The typical method for compiling involves using the following code: require "sass" Sass::Engine.new(File.read(scss), options).render By utilizing appropriate hash val ...

navigate to a new page in vue with node.js

As I continue to expand my knowledge in JavaScript, Vue, and Node.js, I encountered a specific issue that I need help with. My goal is to redirect the Vue page after logging in using Node.js. Below you'll find the code snippets for my Vue setup and sc ...

Unable to save data retrieved using jQuery JSONP

My current project involves fetching photo data from Flickr using a jQuery AJAX call with JSONP. However, instead of immediately using the data, I want to store it for future use. In some cases, users will be able to perform different queries on the pre-fe ...

What could be causing npm to fail to launch?

Whenever I execute node app.js, my server functions perfectly. However, when attempting to utilize nodemon for running the server, it fails to start. The error displayed by npm start is as follows: npm ERR! code ELIFECYCLE npm ERR! errno 9009 npm ERR! < ...

Halt the adhesion of the Bootstrap column when it hits the div section

I have a simple bootstrap row containing two columns: <div class="row"> <div class="col-xs-7"> <p>Walking together</p> </div> <div class="col-xs-5" id="stay"> <p>Joyful journey</p> </div ...

Tips on relocating the input position to the top

Currently, I have a text input that is centered horizontally when typing text. However, I want it to be positioned at the top instead. See the following code: height: 143px; width: 782px; font-family: 'Roboto Mono'; background: #FFFFFF; border ...

What is the most efficient method for implementing uniform rounded corners in HTML/CSS across different web browsers?

Is there a simple way to achieve cross-browser compatibility without a lot of tedious work? I'm looking for a solution that works effortlessly on IE7+, FF2+, and Chrome, without resorting to using tables which may be outdated. Is there a middle ground ...

Using jQuery to insert a div class with PHP referenced

My variable stores a color name. Here is an example: <?php $myvar = blueColour; ?> I want to apply this value to the body of an html page using jQuery: <script type="text/javascript"> jQuery(body).addClass("<?php echo $myvar; ?>"); < ...

Illuminate the rows in a table generated from a parsed text file using PHP

I am facing an issue with my PHP logic for selecting and highlighting rows in a table based on dropdown selection. I have a group of text files that are parsed into a table, and I need to highlight rows that match selections from 5 dropdowns created from t ...

Javascript timer that counts down using cookies for storage

Seeking assistance - I am in search of a solution to create a javascript countdown timer that utilizes cookies. I need the timer to remain consistent even when the user refreshes the page, until a specific time has elapsed. This is for an online examinat ...

Utilize map() and concat() in JavaScript for more streamlined code - a tidier approach

Is there a way to optimize the code below by combining map() and concat() for efficiency? const firstColumnData = data.map((item: any) => { return item.firstColumn; }); const secondColumnData = data.map((item: any) => { return item.secondColumn; } ...

Using jQuery to retrieve the text content of child elements

Struggling to extract the text of child elements using jQuery. I've been at this for a couple of days and can't seem to make it work. If anyone could spare a moment to review, I would greatly appreciate it! SCRIPT: function generateRemoveSect ...

How to handle a Vue element click event through programming

In my Vue instance, I am looking to have a response triggered by a click on an uploaded thumbnail. Utilizing the Vue package called FineUploader Vue with the template layout as outlined in the documentation (refer to end of question). After uploading an i ...

Increase visibility, decrease visibility by utilizing ng-hide/ng-show and functions

As I implement the show more/show less feature, I am uncertain if achieving a smooth effect is feasible. However, I believe it's worth reaching out to this community for some creative ideas on how to make it possible. I have a list of dynamic links w ...

"Transmit the document by utilizing the file ID in the form of

When sending a file from my server, I can easily define the path and it goes through successfully. However, with the node-telegram-bot-api, there is an option to send a document that is already hosted on telegram servers by providing the file_id in the doc ...

What is the purpose of having several script tags following the creation of NextJS?

After running next build and next start, my application is still generating many JS files instead of a single entry point. I'm unsure if I missed a step as the documentation suggests this should be all that's required. https://i.stack.imgur.com/7 ...