-1

I am making a catalog for my javascript classes but I have an error. I insert files into my HTML document using innerHTML and I load the data from an array in my JS file, everything loads perfectly but to add an aesthetic effect I wanted that when you click the "see more" button a modal with the information is displayed of my product, when I click on an image of the thumbnail it should be displayed in the main image but that only happens in the first element of my array, if I open another modal nothing happens and the change is reflected in the first modal.

for example this is the image of my modal, the default image is of the first image and if I click another image it replaces the main image

my problem is that when i open another modal and try to change the image nothing happens but the change is reflected in my modal 1.

i am using this code but apparently it doesn't work

function cambiarimagen(smallimg)
{
  var fullimg=document.getElementById("img-grande");
  fullimg.src = smallimg.src;
}

If it doesn't display just clic in the button "Mujer", in small screens it doesn't show three pictures only in big screens

HTML

let filt_mas = document.getElementById("filt_mas");
let filt_fem = document.getElementById("filt_fem");
let filt_inf = document.getElementById("filt_inf");
let filt_cat = document.getElementById("filt_cat");

let btnazul = document.getElementById("btnazul");
let btnblanco = document.getElementById("btnblanco");
let btnnegro = document.getElementById("btnnegro");

let filt_mas2 = document.getElementById("filt_mas2");
let filt_fem2 = document.getElementById("filt_fem2");
let filt_inf2 = document.getElementById("filt_inf2");
let filt_Scat2 = document.getElementById("filt_cat2");

let min = document.getElementById("min");
let max = document.getElementById("max");
let filt_precio= document.getElementById("filt_precio");


function showProducts(prods) {

  const mainProds = document.getElementById("main__prods");
  mainProds.innerHTML = prods.map(prod => `
    
                    <!-- productos-->
                    <div class="col" style="margin-bottom: 1rem;">
                        <div class="card card_producto card__team h-100">
                            <div style="text-align: center;" class="img_producto">
                                <img src="${prod.imagen1}"
                                    style="width: auto; height: 150px; margin-top: 1rem;"
                                    class="img-fluid rounded" alt="${prod.nombre}">
                            </div>
                            <div class="card-body">
                                <div class="title__card">
                                    <span>${prod.nombre}</span>
                                </div>
                                <div class="subtitle__card">
                                    <span>${prod.origen}</span>
                                </div>
                                <p class="card-text" style="text-align: justify;">${prod.id} ... </p>
                            </div>
                            
                            <div style="text-align:center; margin: 0 auto 1.5rem auto;">
                            <button type="button" id="btn-producto" class="btn btn-warning btn-producto" data-bs-toggle="modal" data-bs-target="#exampleModal${prod.id}">
                            Ver más 
                            <svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="currentColor" class="bi bi-caret-down-fill" viewBox="0 0 16 16">
                                <path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/>
                            </svg>
                            </button>

                            </div>
                            <div class="modal fade" id="exampleModal${prod.id}" tabindex="-1" aria-labelledby="exampleModalLabel"
                            aria-hidden="true">

                            <div class="container-fluid">
                            <div class="modal-dialog modal-xl">
                            <div class="modal-content" id="modal-contenido">
                                <div class="modal-header">
                                    <h6 class="modal-title"><strong>${prod.nombre}</strong></h6>
                                    <button type="button" class="btn-close" data-bs-dismiss="modal"
                                    aria-label="Close"></button>
                                </div>
                                <div class="modal-body">
                                <div class="container-fluid text-center" id="singleprod">
                                <div class="row" style="width: 100%;">
                                  <div class="col my-auto" style="width: 30%;" id="col1">
                                    <ul class="list-group" id=miniaturas>
                                        <li id="imagen1" class="list-group-item" style="width: 70%;"><img src="${prod.imagen1}" onclick="cambiarimagen(this)" class="rounded mx-auto d-block img-pequena" alt="..."></li>
                                        <li id="imagen2" class="list-group-item" style="width: 70%"><img src="${prod.imagen2}"  onclick="cambiarimagen(this)" class="rounded mx-auto d-block img-pequena" alt="..."></li>
                                        <li id="imagen3" class="list-group-item" style="width: 70%"><img src="${prod.imagen3}" onclick="cambiarimagen(this)" class="rounded mx-auto d-block img-pequena" alt="..." ></li>
                            
                                      </ul>
                                  </div>
                                  <div class="col" style="width: 50%;align-items: center;" id="main-image${prod.id}">
                                    <img src="${prod.imagen1}"  id="img-grande" class="rounded mx-auto d-block" alt="..." " style=" max-width: 95%; max-height: 95%;">
                                  </div>
                                  <div class="col" style="width: 40%;">
                                    <!--Nombre del producto-->
                                    <h5 id="nombre_producto">Precio: $ ${prod.precio}</h5>
                                    <div class="container text-center">
                                        
                                      </div>
                                    
                                    <!--Talla-->
                                    <div class="container text-center">
                                        <div class="row">
                                          <div class="col">

                                          <fieldset id="tallas">
                                          <h4 id="titulo-tallas">Tallas</h4>
                                          <div class="form-check form-check-inline formtallas talla-conjunto">
                                            <input id="tCh" class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1">
                                            <label class="form-check-label label-tallas" for="inlineRadio1">C</label>
                                          </div>
                                          <div class="form-check form-check-inline formtallas talla-conjunto">
                                            <input id="tM" class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2">
                                            <label class="form-check-label label-tallas" for="inlineRadio2">M</label>
                                          </div>
                                          <div class="form-check form-check-inline formtallas talla-conjunto">
                                            <input id="tG" class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3">
                                            <label class="form-check-label label-tallas" for="inlineRadio3">G</label>
                                          </div>
                                          <div class="form-check form-check-inline formtallas talla-conjunto">
                                            <input id="tXg" class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio4" value="option4">
                                            <label class="form-check-label label-tallas" for="inlineRadio4">X</label>
                                          </div>
                                      <fieldset>
                                            
                                          </div>
                                        </div>
                                      </div>
              
                            
                                      <!--Descripcion-->
                                      <div class="descripciones-modal mt-5">
                                        <p class="codigo">Descripción</p>
                                        <p id="desc-prod">${prod.descripcion}</p>
                                        <ul id="lista-desc">
                                        
                                        
                                            <li>${prod.materiales}</li>
                                            <li>${prod.sugerencia}</li>
                                            <li>${prod.adicional}</li>
                                            
                                        </ul>
                                      </div>
                                      <!--Botones-->
                                    <div class="btn-group" role="group" aria-label="Basic example">
                                        <button type="button" class="btn btnmodal btn-success" id="comprar">Comprar</button>
                                        <button type="button" class="btn btnmodal btn-warning" id="carrito">Carrito</button>
                                    </div>
                            
                                    
                            
                                  </div>
                                </div>
                              </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn btnmodal btn-outline-danger"
                                        data-bs-dismiss="modal" id="cerrar">Cerrar</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            </div>
                            </div>

                            
    `
  ).join('');

}


filt_cat.addEventListener("click", function (event) {
  showProducts(prod1);

});

filt_mas.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "mas"));

});

filt_fem.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "fem"));
});

filt_inf.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "inf"));
});


btnazul.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.color == "azul"));

});

btnblanco.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.color == "blanco"));
});

btnnegro.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.color == "negro"));
});


filt_precio.addEventListener("click", function (event) {
  if (min.value.length == 0 && max.value.length.keyup() == 0){
    return showProducts(prod1);
  }else{
  showProducts(prod1.filter(prod => (prod.precio >= min.value && prod.precio <= max.value)));
  }
});



filt_cat2.addEventListener("click", function (event) {
  showProducts(prod1);

});

filt_mas2.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "mas"));

});

filt_fem2.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "fem"));
});

filt_inf2.addEventListener("click", function (event) {
  showProducts(prod1.filter(prod => prod.publico == "inf"));
});

function cambiarimagen(smallimg)
    {
      var fullimg=document.getElementById("img-grande");
      fullimg.src = smallimg.src;
    }

    

  




prod1 = [

  {
    id:1,
    nombre:"Rebozo azul",
    publico:"fem",
    precio:400,
    origen:"Náhuatl",
    color:"azul",
    cantidad:"100",
    talla:"1",
    materiales:"algodón",
    sugerencia:"perfecta para un dia frio",
    adicional:"elaboración artesanal",
    tipo:"rebozo",
    imagen1:"https://m.media-amazon.com/images/I/61e-Nkwzc6L._AC_SX679_.jpg",
    imagen2:"https://m.media-amazon.com/images/I/61lHGF+9xXL._AC_SX679_.jpg",
    imagen3:"https://m.media-amazon.com/images/I/719vUwUbcSL._AC_SX679_.jpg"
  },
  {
    id: 3,
    nombre:"Rebozo negro",
    publico:"fem",
    precio:400,
    origen:"Náhuatl",
    color:"negro",
    cantidad:"100",
    talla:"1",
    materiales:"algodón",
    sugerencia:"perfecta para un dia frio",
    adicional:"elaboración artesanal",
    tipo:"rebozo",
    imagen1:"https://m.media-amazon.com/images/I/61D0JjRRbSL._AC_SX679_.jpg",
    imagen2:"https://m.media-amazon.com/images/I/61TqoNQBEDL._AC_SX679_.jpg",
    imagen3:"https://m.media-amazon.com/images/I/71AK74ZLSML._AC_SX679_.jpg"
  },


  {
    id: 4,
    nombre:"Vestido azul sin mangas",
    publico:"fem",
    precio: 1500,
    origen:"Otomi",
    color:"azul",
    cantidad:"40",
    talla:"2",
    materiales:"algodón",
    sugerencia:"lavar",
    adicional:"elegante vestido para fiestas",
    tipo:"vestido",
    imagen1:"https://m.media-amazon.com/images/I/61Jqnlbt3+L._AC_SX679_.jpg",
    imagen2:"https://m.media-amazon.com/images/I/81t58MzR0gL._AC_SX679_.jpg",
    imagen3:"https://m.media-amazon.com/images/I/81GGTYmp-kL._AC_SX679_.jpg"
  }
  
  ];
/* ======== GENERAL ========= */

* {
    font-family: 'Plus Jakarta Sans', sans-serif;
    font-size: 62.5%;
}

html {
    height: 100%;
    box-sizing: border-box;
}

body {
    background-color: #faebd7;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    color: #353028;
}



h1 {
    padding: 2rem 0 2rem 0;
    font-weight: 600;
    text-align: center;
    font-size: 2.5rem;
}

h2 {
    padding: 2rem 0 1rem 0;
    font-weight: 600;
    text-align: center;
    font-size: 2.3rem;
}

p {
    font-size: 1.6rem;
    letter-spacing: .05rem;
    word-spacing: .5rem;
}

/* ======= NAVBAR ======== */
header {
    width: auto;
}

.nav-item {
    font-size: 2rem;
    padding-right: 4rem;
}

.navbar-brand {
    padding: 1rem 6rem 1rem 2rem;
}

.custom-navbar {
    background-color: #3a8761;
}

.nav-link {
    color: white;
    padding-left: 1rem;
}

.nav-link:hover {
    color: #5C5346;
}

.nav--icon {
    font-size: 2.5rem;
}

.especial {
    display: none;
}

.dropdown-menu,
.dropdown-item {
    background-color: #c3c3c3;
    font-size: 1.6rem;
    color: #353028;
}

.wrapper {
    flex: 1;
}


/* ============= PRODUCTOS ================== */

.img_producto:hover {
    cursor: pointer;
}

.card_producto:hover{
    /* transform: translateY(-1rem); */
    transition: .3s;
    box-shadow: 2px 2px 3px 3px rgba(0, 0, 0, 0.3);
}

.container-products {
    width: 100%;
}

.catalogo-navbar {
    position: fixed;
    display: block;
    margin-left: auto;
    margin-right: auto;
    padding-top: 0;
}

.catalogo-navbar ul {
    padding: 0;
}

.catalogo-navbar ul li {
    padding-bottom: 2rem;
}

.filtro-catalogo {
    text-align: center;
    background-color: transparent;
    border-color: transparent;
}

#filt_cat {
    padding-bottom: 5rem;
}

.contenedor-navbar-catalogo {
    border-right: solid #353028;
    margin: 90px 0 10px 0;
    padding-top: 2.4%;
}

.filtro-catalogo {
    font-size: 2.5rem;
    text-decoration: none;
    color: #353028;
    font-weight: bold;
    list-style-type: none;
}

.filtro-catalogo:hover {
    cursor: pointer;
    font-size: 2.8rem;
    transition: .5s;
    text-shadow: 2px 0px .5px#CBA328;
}

.btn-producto {
    font-size: 1.3rem;
    width: 9rem;
    margin: auto;
}

#filtro-superior {
    width: 100%;

}

#filtro-superior button {
    background-color: transparent;
    border: transparent;
    color: #353028;
    font-weight: bold;
}

#filt_cat2 {
    background-color: transparent;
    border: transparent;
    color: #353028;
    font-weight: bold;
    text-align: center;
    width: 100%;

}

#filt_cat2,
#filt_mas2,
#filt_fem2,
#filt_inf2 {
    font-size: 2.6rem;
    display: none;
}

/* modal */
[class*="col-1 green"] {
    background-color: rgb(227, 204, 204);
    width: 10px;
    height: 10px;
    border-color: black;

    border-width: thin;
}

[class*="col-1 red"] {
    background-color: black;
    width: 10px;
    height: 10px;
    border-color: black;

    border-width: thin;
}

[class*="col-1 blue"] {
    background-color: blue;
    width: 10px;
    height: 10px;
    border-color: black;

    border-width: thin;
}

.descripciones-modal {
    font-size: 4rem;
}

.modal-title {
    font-size: 5rem;
}

.dropdown-toggle,
.codigo,
#menutallas li {
    font-size: 2rem;
}

.form-check,
.btnmodal,
#nombre_producto {
    font-size: 2rem;
}

.imagen-principal {
    width: 300px;
    height: 450px;
}

.descripciones-modal>ul {
    /* list-style: none; */
    text-align: left;
    padding: 1.5rem;
}

/* modal */


/* ============= MEDIAS ================== */


    /* modal */

    #imagen-principal {
        display: none;
    }

    .modal-title,
    .codigo {
        display: none;
    }

    .banner_registro,
    .banner_registro img {
        height: .5rem;
        width: .5rem;
        visibility: hidden;
    }

    footer {
        padding: 20px;
    }

    #tallas{
        width: 60%;
        font-size: 12px;
    }

    #desc-prod{
        text-align: justify;
        font-size: 10px;
    }

    #min, #max, #filt_precio{
        display: none;
        visibility: hidden;
    }

    #carrito,#comprar,#cerrar{
        font-size: 12px;
    }


    #inlineRadio1,#inlineRadio2,#inlineRadio3,#inlineRadio4 {
        width: 9px;
        height: 9px;
        border: 0;
    }
    
    #titulo-tallas{
        display: none;
        visibility: hidden;
    }

    #img-grande{
        width: 300px;
        height: 700px;
    }

    #main_image img{
        height: 70%;
        width: 70%;
        margin-top: 15px;
        margin-bottom: 15px;
    }

    #lista-desc{
        visibility: hidden;
        display: none;
    }
    
    
}



   
.img-pequena{
    opacity: 0.6;

}

.img-pequena:hover{
    opacity: 1;

}

#miniaturas li img{
    width: 35%;
    height: 30.5%;
    margin-top: 15px;
    margin-bottom: 15px;
    margin-left: 33px;
    cursor:pointer;
    display: block;
    opacity: .7;
}

#img-grande{
    width: 70%;
    height: 70%;
}

#miniaturas img:hover{
    opacity: 1;
}

#main_image img{
    height: 100%;
    width: 100%;
    margin-top: 15px;
    margin-bottom: 15px;
}

input[type='radio'] {
    background-color: green;
    width: 20px;
}

#tallas{
    width: 20%;
}

#desc-prod{
    text-align: justify;
    font-size: 1.2rem;
}

#lista-desc li{
    list-style-type: none;
    font-size: 1.2rem;
}

#img-grande{
    margin-top: 5rem;
    margin-right: 60rem;
}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Productos</title>
  <!-- iconos bootstrap -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
  <!-- css bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
  <!-- fonts google-->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700&display=swap"
    rel="stylesheet">
  <!-- css interno -->
  <link rel="stylesheet" href="./css/main.css">
  <!-- Logo -->
  <link rel="shortcut icon" href="./src/img/logos/kotomitl3.png" type="image/x-icon">
</head>


  <!-- ================= CONTENIDO ============== -->
  <main class="wrapper">
    <section class="container mb-5">
      <button type="button" class="btn btn-outline-primary" id="filt_cat2">Catálogo</button>
      <div class="container-fluid text-center container-products">
        <div class="btn-group" role="group"  id="filtro-superior">
          <button type="button" class="btn btn-outline-primary" id="filt_mas2">Hombre</button>
          <button type="button" class="btn btn-outline-primary" id="filt_fem2">Mujer</button>
          <button type="button" class="btn btn-outline-primary" id="filt_inf2">Infante</button>
        </div>  
      </div>
    
    <div class="container-fluid text-center container-products" id="productos-grande">


      <div class="row">
        <div class="col-md-2 contenedor-navbar-catalogo d-flex justify-content-center align-items-top" id="barra-catalogo">
          <div class="catalogo-navbar">

            <!-- <div class="form-outline" style="width: 15rem;"> -->
              <!-- <input  style="width: 15rem; height:2rem; font-size: 1.6rem;" type="text" placeholder="Busqueda" id="filtro_nombre"/> -->
              <!-- <input  type="number" id="min" class="form-control" placeholder="min" />
              <input  type="number" id="max" class="form-control" placeholder="max"/>
              <br>
              <br>
              <button  style="width: 12rem; height: 2rem;" id="filt_precio">filtrar</button>

               -->

            <!-- </div>
            <br>
            <br> -->

            <!-- <div class="btn-group" role="group" id="filtro-color">
              <button type="button" class="btn btn-light" id="btnblanco"></button>
              <button type="button" class="btn btn-primary" id="btnazul"></button>
              <button type="button" class="btn btn-dark" id="btnnegro"></button>
            </div> -->
            <ul style="list-style-type: none">
              <li><button href="" class="filtro-catalogo" id="filt_mas">Hombre</button></li>
              <li><button href="" class="filtro-catalogo" id="filt_fem">Mujer</button></li>
              <li><button href="" class="filtro-catalogo" id="filt_inf">Infantes</button></li>
            </ul>


           
          </div>
        </div>
        <div class="col-md-10">
          <!-- boton -->
          <button href="" class="filtro-catalogo" id="filt_cat">Catálogo</button>
          <!-- boton -->

          <div class="container text-center" style="padding-bottom: 5rem;">
            <div class="row">
              <div class="col">
                <!-- contenedor colores -->
                <div class="container text-center">
                  <div class="row">
                    <div class="col">
                      <button type="button" style="width: 3rem; height: 2rem;" class="btn btn-light" id="btnblanco"></button>
                      <button type="button" style="width: 3rem; height: 2rem;" class="btn btn-primary" id="btnazul"></button>
                      <button type="button" style="width: 3rem; height: 2rem;" class="btn btn-dark" id="btnnegro"></button>
                    </div>
                  </div>
                </div>
              <!-- contenedor colores -->
              </div>
              <div class="col">
                <!-- max min -->
                <div class="container text-center">
                  <div class="row">
                    <div class="col" style="width: 2rem;">
                      <input  style="width: 8rem; height: 2rem;" type="number" id="min" class="form-control" placeholder="min"/>
                    </div>
                    <div class="col" style="width: 2rem;"> 
                      <input  style="width: 8rem; height: 2rem;" type="number" id="max" class="form-control" placeholder="max"/>
                      <br>
                    </div>
                    <div class="col" style="width: 2rem;">
                      <button  style="width: 7rem; height: 2rem; font-size: 1rem;" id="filt_precio">filtrar</button>
                    </div>
                  </div>
                </div>
                <!-- max min -->
              </div>
              <div class="col">
              <!-- busqueda -->         
              <div class="container text-center">
                <div class="row">
                  <div class="col">
                    <input  style="width: 15rem; height:2rem; font-size: 1.6rem;" type="text" placeholder="Busqueda" id="filtro_nombre"/>
                  </div>
                </div>
              </div>
              <!-- busqueda -->
              </div>
            </div>
          </div>



          
          <!-- catalogo -->
          <div id="main__prods" class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-xl-4 g-6">
            
          </div>
          <!-- catalogo -->
        </div>
      </div>
    </div>
    </section>
  </main>
  <!-- ================= FOOTER ============== -->
  <footer id="footer"></footer>

  <!-- ================= JS ============== -->
  <!--Bootstrap-->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
    crossorigin="anonymous"></script>



  <!-- Productos -->
  <script src="./js/productos4.js"></script>


</body>

</html>
  • 4
    Without seeing the markup, I'd say you've reused element ids. Ids must be unique within the document. – Teemu Aug 29 '23 at 07:44
  • 1
    A proper [mre] of your issue belongs directly into your question; please do not just dump the whole thing on some external platform like github. – CBroe Aug 29 '23 at 07:47
  • i already upload a demo of the website – ROBERTO RIVAS MONZON Aug 29 '23 at 08:10
  • I'm afraid you've to rethink the entire logic. Take a look at [event delegation](https://stackoverflow.com/q/1687296/1169519) and how to [clone elements](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode). Then write the markup of the "product card" template to the page once, clone the template, and replace markers in attributes and content using DOM methods (not string methods), and append clones to the page one by one. – Teemu Aug 30 '23 at 09:24

0 Answers0