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

There seems to be an issue with the function code error when calling it within the

When I attempt to run my code in this way, I encounter a compile time error stating that the expression statement is not an assignment or call... (within the else statement). What am I missing here to get it to work? I've made numerous attempts to ad ...

Watching for changes to an element's visibility within the viewport and automatically scrolling it

I'm having trouble making the input scroll to .here when its value matches "1". Even though I tried using a button with a handle-click function and it worked. Please lend me a hand with this issue. <template> <button @click="scrollToV ...

Nested pages in the NextJS router do not properly highlight the active menu item

I am currently working with NextJS and facing an issue with setting active menu items using the router. While the 'top level' pages behave as expected, any page under a top level page does not get set as active. router.pathname == "/profile& ...

Troubleshooting AJAX issues in Firefox with window.location.assign function

Here is my AJAX POST request that sends serialized form data to the server: // Handle form submission. $('#evaluationform').on('submit', function(e){ e.preventDefault(); ajaxObject = { url: $("#evaluationform").attr("a ...

What repercussions come from failing to implement an event handler for 'data' events in post requests?

If you take a look at the response provided by Casey Chu (posted on Nov30'10) in this particular question: How do you extract POST data in Node.js? You'll find that he is handling 'data' events to assemble the request body. The code sn ...

All images must be arranged to fit seamlessly side by side regardless of the screen size

I'm currently experimenting with creating a website dedicated to my favorite TV shows. Upon entering the site, you are greeted with the main page that includes 7 images. Each image is linked to a specific webpage providing information about the corre ...

Having a problem with the xmlhttprequest, not confident if it is being called correctly

I encountered a problem with the code I have where a user selects a sales center and it should trigger a currency change. Both selections are dropdowns, but when I choose a sales center, I receive an error saying ReferenceError: makeRequest is not define ...

The second function in Vue.js was unable to initialize the data field within data() due to a missing call for assistance

I have very little experience working with vue js. There are two functions that I am using: loadComponentsOfUser() and loadUserId(). The loadComponentsOfUser() function depends on the userID field being loaded by the loadUserId() function. data() { retu ...

What is the best way to retrieve the output of MongoDB's collection.aggregate() within a NodeJS callback function?

In my database, I have a users collection with the following data: { "_id" : ObjectId("5b29ba37cd0b1726068731c3"), "name" : "Gym Dog", "profilePicUrl" : "https://i.imgur.com/mPStaKV.png", "totalProgress" : { "goal" : 300, "progress ...

Why is it that when implementing React JS, the function setState is not updating the values on the chart when a Button is

Currently, my webpage is built using React JS and includes a JavaScript chart. I am trying to make the data in the chart dynamically change based on a value entered into a text box. When a button is clicked, the graph should update with the new results. Ho ...

Height of Hover Background Color in WordPress Menu

Greetings! Welcome to my website I'm in the process of modifying the hover color for the top menu, and I've managed to change it successfully. However, I would like the hover effect to cover the entire height of the menu, as right now it's ...

`Arranging Widget Boxes in a Vertical Layout`

I am currently displaying each record with two boxes for Afternoon and Night horizontally: https://i.stack.imgur.com/JMKug.png This is the code structure I am using to achieve this layout: <div id="record_box"> <div class="row" style="paddi ...

Form validation using jQuery and AJAX

I've implemented validation in my ResetPassword function and it seems to be working fine. However, I'm facing an issue where the ResetPassword function stops working once the validation is added. Can someone guide me on how to resolve this issue? ...

The JavaScript function for converting a date to a local string in the format of DD MMM YYYY is causing an error message in the browser console stating that it is not a valid function

I am encountering an issue with formatting a date string. The date is currently in the format 2021-03-31T00:00:00, and I need it to be displayed as 31 Mar 2021. In my TypeScript code, I attempted to use the following function: const formattedDate = i.Susp ...

Is there a way to customize Angular's number filter?

I'm trying to achieve a consistent number format with Angular's number filter, regardless of the localization selected. After inspecting the Angular source code on GitHub, I found the implementation of the filter to be like this: function number ...

My AJAX requests do not include any custom headers being sent

I'm facing an issue with making an AJAX request from my client to my NodeJS/ExpressJS backend. After firing the request, my backend successfully receives it but fails to recognize the custom headers provided. For example: $.ajax({ type: " ...

Utilizing jQuery to target a select element's two specific children

I am trying to target the parent element by matching two specific children elements. Here is my code: $('span:contains("11:00am"), span.name:contains("Tom")').parents("a").css("background-color","rgb(255, 255, 255)"); <script src="https://c ...

Ensure that the <TabPanel> content occupies the entire width and height of its parent container

Currently, I am working with React and material-ui. Specifically, I am utilizing an appbar with tabs and my goal is to have the content of each tab expand to full width and height when selected. If you'd like to see an example, check out this sandbox ...

Adjusting the visible options in ngOptions causes a disruption in the selected value of the dropdown menu

I have successfully implemented a feature that allows users to convert temperature values displayed in a drop-down menu to either Celsius or Fahrenheit. For this functionality, I am using a select input with ng-options as shown below: <select ng-model ...

store events in a MySQL database using a servlet callback and display them on a full calendar

Hey there! I recently started using the full-calendar jQuery plugin and successfully integrated it into a JSP page. The events on the calendar are loaded from a MySQL database by calling a servlet that generates a JSON array of retrieved elements. Now, I& ...