Tratando de buclear sobre las filas de bootstrap, para añadir 3 col-4's en cada uno usando DOM

Así que básicamente estoy sacando de una API Studio Ghibli y produciendo datos en tarjetas de arranque de la información que me da. Esa parte funciona, pero quiero que se alinean en filas de 3 col-md-4.

Aquí está mi bucle:

for (let col in row) {
      let newRow = document.createElement("div");
      newRow.setAttribute("class", "row");
      container.appendChild(newRow);
      for (col = 0; col <= 3; col++) {
        newCol[col].appendChild(card.appendChild(cardBody));
        cardBody.appendChild(cardTitle);
        cardBody.appendChild(cardSubtitle);
        cardBody.appendChild(cardText);
      }
    }

Básicamente tengo un bucle sin fin que crea miles de "rows", pero sin mis "cols" dentro/data. Y para cualquier aclaración aquí es el resto del archivo:

const row = document.querySelector(".row");
const container = document.querySelector(".container");
// const col = document.getElementById("col-md-4");

fetch("https://ghibliapi.herokuapp.com/films")
  .then((res) => res.json())
  .then(function (data) {
    console.log(data);
    displayResults(data);
  })
  .catch((err) => console.log(err));

function displayResults(data) {
  for (results of data) {
    // new col
    let newCol = document.createElement("div");
    newCol.setAttribute("class", "col-md-4");

    // card
    let card = document.createElement("div");
    card.setAttribute("class", "card");
    card.style.width = "18rem";

    // card body
    let cardBody = document.createElement("div");
    cardBody.setAttribute("class", "card-body");

    // card title
    let cardTitle = document.createElement("h5");
    cardTitle.setAttribute("class", "card-title");
    cardTitle.innerHTML = results.title;

    // card subtitle
    let cardSubtitle = document.createElement("h6");
    cardSubtitle.setAttribute("class", "card-subtitle mb-2");
    cardSubtitle.innerHTML = "-" + results.director;

    // card text
    let cardText = document.createElement("p");
    cardText.setAttribute("class", "card-text");
    cardText.innerHTML = results.description;

Y HTML es bastante simple:

 

EDIT: Dejé todo el código de importación de placa de caldera HTML/bootstrap.

Pregunta hecha hace 3 años, 4 meses, 28 días - Por geekglitcher


3 Respuestas:

  • Echa un vistazo a este enfoque que hace uso de una cadena literal en lugar de crear elementos dinámicamente.

    HTML:

    JS:

     const row = document.querySelector(".row");
     const container = document.querySelector(".container");
    
        fetch("https://ghibliapi.herokuapp.com/films")
          .then((res) => res.json())
          .then(function (data) {
            displayResults(data);
          })
          .catch((err) => console.log(err));
    
        function displayResults(data) {
          const cardSelector = document.getElementById("card-selector");
          data.forEach((result) => {
            let card = `
                      
    ${result.title}

    Some quick example text to build on the card title and make up the bulk of the card's content.

    Go somewhere
    `; let containerDiv = document.createElement("div"); //create the col div containerDiv.setAttribute("class", "col-sm-6 col-md-4"); //Add the bootstrap col class as needed containerDiv.innerHTML = card; cardSelector.appendChild(containerDiv); }); }

    const row = document.querySelector(".row");
     const container = document.querySelector(".container");
    
        fetch("https://ghibliapi.herokuapp.com/films")
          .then((res) => res.json())
          .then(function (data) {
            displayResults(data);
          })
          .catch((err) => console.log(err));
    
        function displayResults(data) {
          const cardSelector = document.getElementById("card-selector");
          data.forEach((result) => {
            let card = `
                      
    ${result.title}

    Some quick example text to build on the card title and make up the bulk of the card's content.

    Go somewhere
    `; let containerDiv = document.createElement("div"); //create the col div containerDiv.setAttribute("class", "col-sm-6 col-md-4"); //Add the bootstrap col class as needed containerDiv.innerHTML = card; cardSelector.appendChild(containerDiv); }); }
    [email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    
    

    Respondida el Dec 18, 2020 a las 02:51 - por syntaxsculptor

    Votos positivos: 0 | Votos negativos: 0

  • El error en tu código se debe a que estás utilizando mal el bucle. En la sección donde intentas crear las columnas en cada fila, estás sobrescribiendo la variable col y también no estás añadiendo las nuevas columnas al nuevo row creado.

    Para corregir esto, puedes hacer lo siguiente:

    javascript
    const row = document.querySelector(".row");
    const container = document.querySelector(".container");
    
    fetch("https://ghibliapi.herokuapp.com/films")
      .then((res) => res.json())
      .then(function (data) {
        console.log(data);
        displayResults(data);
      })
      .catch((err) => console.log(err));
    
    function displayResults(data) {
      let newRow = null;
    
      data.forEach((result, index) => {
        if (index % 3 === 0) {
          // Crea una nueva fila cada vez que se completan 3 columnas
          newRow = document.createElement("div");
          newRow.setAttribute("class", "row");
          container.appendChild(newRow);
        }
    
        // new col
        let newCol = document.createElement("div");
        newCol.setAttribute("class", "col-md-4");
    
        // card
        let card = document.createElement("div");
        card.setAttribute("class", "card");
        card.style.width = "18rem";
    
        // card body
        let cardBody = document.createElement("div");
        cardBody.setAttribute("class", "card-body");
    
        // card title
        let cardTitle = document.createElement("h5");
        cardTitle.setAttribute("class", "card-title");
        cardTitle.innerHTML = result.title;
    
        // card subtitle
        let cardSubtitle = document.createElement("h6");
        cardSubtitle.setAttribute("class", "card-subtitle mb-2");
        cardSubtitle.innerHTML = "-" + result.director;
    
        // card text
        let cardText = document.createElement("p");
        cardText.setAttribute("class", "card-text");
        cardText.innerHTML = result.description;
    
        newCol.appendChild(card);
        card.appendChild(cardBody);
        cardBody.appendChild(cardTitle);
        cardBody.appendChild(cardSubtitle);
        cardBody.appendChild(cardText);
    
        newRow.appendChild(newCol);
      });
    }
    

    Con estos cambios, se crearán nuevas filas cada vez que se completen 3 columnas, y se añadirán las nuevas columnas al row correspondiente. Esto debería ayudar a que tu código funcione correctamente y muestre las tarjetas en filas de 3 columnas cada una.

    Respondida el Dec 19, 2020 a las 02:51 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que dentro del bucle anidado:

    
    for (col = 0; col <= 3; col++) {
        newCol[col].appendChild(card.appendChild(cardBody));
        cardBody.appendChild(cardTitle);
        cardBody.appendChild(cardSubtitle);
        cardBody.appendChild(cardText);
    }
    

    Estás iterando sobre un rango de 0 a 3, pero solo tienes una instancia de newCol. Esto significa que estás intentando acceder a elementos que no existen en newCol.

    Para crear tres columnas para cada fila, debes crear una nueva instancia de newCol dentro del bucle externo:

    
    for (let row in data) {
        let newRow = document.createElement("div");
        newRow.setAttribute("class", "row");
        container.appendChild(newRow);
    
        // Crea tres nuevas columnas para cada fila
        for (let i = 0; i < 3; i++) {
            let newCol = document.createElement("div");
            newCol.setAttribute("class", "col-md-4");
            newRow.appendChild(newCol);
    
            // Añade el card y su contenido a la columna
            newCol.appendChild(card.appendChild(cardBody));
            cardBody.appendChild(cardTitle);
            cardBody.appendChild(cardSubtitle);
            cardBody.appendChild(cardText);
        }
    }
    

    Esto creará un nuevo conjunto de columnas para cada fila, lo que te permitirá alinear las tarjetas en filas de 3.

    Respondida el Dec 19, 2020 a las 02:53 - por Gemini

    Votos positivos: 0 | Votos negativos: 0