stef
stef

Reputation: 155

Creating a dynamic anchor tag generator function using for loop & array

I am trying to write a function which reads in 16 objects (which contains x amount of links) and generated anchor tags which include these links dynamically. These objects are named linksPage0, linksPage1, linksPage2 etc.

The objects need to be added to an array which then needs to calculate the number of items in each object to determine how many anchors to generate before it then adds the URLs from the correlating object to a div (page container).

For now I have hardcoded a single object to get some progress & so far this works OK:

 var linksPage0 = [
    {"name":"img1", "src":"https://via.placeholder.com/300x300/fdf/000?text=page1"},
    {"name":"img2", "src":"https://via.placeholder.com/300x300/fdf/000?text=page2"},
    {"name":"img3", "src":"https://via.placeholder.com/300x300/fdf/000?text=page3"},
    {"name":"img4", "src":"https://via.placeholder.com/300x300/fdf/000?text=page4"},
    {"name":"img5", "src":"https://via.placeholder.com/300x300/fdf/000?text=page5"},
    {"name":"img8", "src":"https://via.placeholder.com/300x300/fdf/000?text=page8"},
    {"name":"img9", "src":"https://via.placeholder.com/300x300/fdf/000?text=page9"},
    {"name":"img10", "src":"https://via.placeholder.com/300x300/fdf/000?text=page10"},
  ];

  var linksPage1 = [
    {"name":"img1", "src":"https://via.placeholder.com/300x300/fdf/000?text=page1"},
    {"name":"img2", "src":"https://via.placeholder.com/300x300/fdf/000?text=page2"},
    {"name":"img3", "src":"https://via.placeholder.com/300x300/fdf/000?text=page3"},
    {"name":"img4", "src":"https://via.placeholder.com/300x300/fdf/000?text=page4"},
    {"name":"img5", "src":"https://via.placeholder.com/300x300/fdf/000?text=page5"},
    {"name":"img6", "src":"https://via.placeholder.com/300x300/fdf/000?text=page6"},
    {"name":"img7", "src":"https://via.placeholder.com/300x300/fdf/000?text=page7"},
    {"name":"img8", "src":"https://via.placeholder.com/300x300/fdf/000?text=page8"},
    {"name":"img9", "src":"https://via.placeholder.com/300x300/fdf/000?text=page9"},
    {"name":"img10", "src":"https://via.placeholder.com/300x300/fdf/000?text=page10"},
  ];

  var linksPage2 = [
    {"name":"img1", "src":"https://via.placeholder.com/300x300/fdf/000?text=page1"},
    {"name":"img2", "src":"https://via.placeholder.com/300x300/fdf/000?text=page2"},
    {"name":"img3", "src":"https://via.placeholder.com/300x300/fdf/000?text=page3"},
    {"name":"img4", "src":"https://via.placeholder.com/300x300/fdf/000?text=page4"},
    {"name":"img5", "src":"https://via.placeholder.com/300x300/fdf/000?text=page5"},
    {"name":"img6", "src":"https://via.placeholder.com/300x300/fdf/000?text=page6"},
    {"name":"img7", "src":"https://via.placeholder.com/300x300/fdf/000?text=page7"},
    {"name":"img8", "src":"https://via.placeholder.com/300x300/fdf/000?text=page8"},
  ];

var productsCount = [linksPage0.length, linksPage1.length, linksPage2.length];

     var imageContainer = document.getElementsByClassName("card");

      for(var i = 0; i < imageContainer.length; i++){
      imageContainer[i].id  = "pageContainer"+i;
      }

      function generateProductAnchors(){
        var pageContainers = document.getElementById("pageContainer"+i);
        var anchor = document.createElement("a");
        anchor.setAttribute('id', 'product'+i);
        pageContainers[i].appendChild(anchor);
        console.log(cont);
      }

    for(i = 0; i < linksPage0.length; i++){
      generateProductAnchors(i);
    }

My problem is now making the loop statement dynamic so that it can read in all link objects (linksPage0.length, linksPage1.length, linksPage2.length) which will count the number of items in the object, generate the correct number of anchors and add them to the imageContainers.

Would this be done with a multidimensional array?

Any help would be appreciated.

Upvotes: 1

Views: 668

Answers (2)

Cat
Cat

Reputation: 4246

You're right, you want a 2-dimensional array. To make it, you can just add your arrays of links to an outer array. Then loop through the outer array (once per group of links), and during each outer loop, run an inner loop that handles each link for that group.

var linksPage0 = [
  {"name":"img1", "src":"https://via.placeholder.com/300x300/fdf/000?text=page1"},
  {"name":"img2", "src":"https://via.placeholder.com/300x300/fdf/000?text=page2"}
];

var linksPage1 = [
  {"name":"img3", "src":"https://via.placeholder.com/300x300/fdf/000?text=page3"},
  {"name":"img4", "src":"https://via.placeholder.com/300x300/fdf/000?text=page4"}
];

var linksPage2 = [
  {"name":"img5", "src":"https://via.placeholder.com/300x300/fdf/000?text=page5"},
  {"name":"img6", "src":"https://via.placeholder.com/300x300/fdf/000?text=page6"}
];

// Collects all links into a 2-dimensional array (and selects cards)
var linksGroups = [linksPage0, linksPage1, linksPage2];
var imageContainers = document.getElementsByClassName("card");

// Loops through outer array
for(let i = 0; i < linksGroups.length; i++){
  let links = linksGroups[i];
  // Assumes there are enough cards to hold all the linksGroups
  //  (Alternatively, you could create the card divs as you go to avoid assuming)
  let container = imageContainers[i];
  container.setAttribute("id","card" + i)

  // Loops through each inner array
  for(j = 0; j < links.length; j++){
    var anchor = document.createElement("a");
    anchor.innerHTML = links[j].name;
    anchor.setAttribute("href", links[j].src);
    container.appendChild(anchor);
    // (Adds line break for demo purposes)
    container.appendChild(document.createElement("br"));
  }
}
.card{ width: 80px; margin: 10px; padding: 5px; border: 1px solid gray}
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>

Upvotes: 1

Andy
Andy

Reputation: 63550

Since you have n objects all containing the basically the same information you can dynamically produce all the elements you need just by specifying the number of links in each page. It means you can remove all that boilerplate, and you don't need to specify the number of containers up front because they're generated too based on the length of the linksPerPage array.

const linksPerPage = [10, 10, 8];

// A separate function that creates and returns a
// new container element.
function createContainer(index) {
  const container = document.createElement('div');
  container.classList.add('container');
  container.dataset.id = index;
  return container;
}

// We pass in the number of links on the page,
// create an anchor element for each, and push it in
// to an array of anchors for tha page.
// Finally we return the anchors array
function createAnchors(links) {
  const anchors = [];
  for (let link = 1; link <= links; link++) {
    const anchor = document.createElement('a');
    anchor.href = `https://via.placeholder.com/300x300/fdf/000?text=page${link}`;
    anchor.textContent = link;
    anchors.push(anchor);
  }
  return anchors;
}

// Pass in the array containing the number of links per page
// Iterate over the array with `map` and for each container,
// create the anchors and then append them all to the container
// Finally return the container
// You will be left with an array of containers that you can then
// append to the document body (or another element of your choosing)
function generateLinksContainers(linksPerPage) {
  return linksPerPage.map((pages, index) => {
    const container = createContainer(index);
    const anchors = createAnchors(pages);
    anchors.forEach(anchor => container.appendChild(anchor));
    return container;
  });
}

// Iterate over the generated containers and add each to the document
// body
generateLinksContainers(linksPerPage).forEach(container => {
  document.body.appendChild(container);
});
.container { padding: 0.2em }
a { padding: 0.2em; }

Upvotes: 1

Related Questions