0

php data variables (img, name, id, etc. are populated from the database as a multidimensional array. using js. to select the smaller thumbnails and change the larger displayed img and info to the selected thumbnail. it's almost working! Img changes but only changes the last info in the array?

<!-----GALLERY_IMAGES----->
<?php
$sql = "SELECT * FROM products WHERE subject LIKE '%$subject%' OR
 alt_name LIKE '%$subject%'";

$total = mysqli_query($conn, $sql);
$array = array();
while ($column = mysqli_fetch_assoc($total)) {
$id = $column['id'];
$name = $column['name'];
$img = $column['img'];
$catagory = $column['catagory'];

$array[] = array(
"id" => $id,
"name" => $name,
"img" => $img,
"designer" => $designer,
"catagory" => $catagory,);

$itemArray .=
'<img src="img_prd/' . $img . '"
input id="prdName"
type="hidden"
value="' . $name . '"
onclick="swapName()"/>';}
?>  

<div class="images">    
<div class="imgs"><?php 
echo($itemArray);
?>
</div>

// JavaScript Document
<!-----REPLACE-img----->
const current = document.querySelector("#current");
const imgs = document.querySelectorAll(".imgs img");
const opacity = 0.6;

imgs[0].style.opacity = opacity;
imgs.forEach(img => img.addEventListener("click", imgClick));
function imgClick(e) {
 imgs.forEach(img => (img.style.opacity = 1));

 current.src = e.target.src;
 current.classList.add("fade-in");

 setTimeout(() => current.classList.remove("fade-in"), 500);
e.target.style.opacity = opacity;`}`

<!-----REPLACE-NAME----->
<script>    
document.querySelectorAll(".imgs img").getElementById("prdName")
.onclick = function() {swapName()};
function swapName(){
document.getElementById('currentProfile')
.setAttribute('value', '<?php echo $name ?>');
</script>
tyson
  • 3
  • 1

1 Answers1

1

TL;DR

You function swap only the last name because you are using <?php echo $name ?> outside of the loop. So the value of $name is the value of the last element in the loop. To solve this you have to take the value with JS from the actual element that is being clicked, and not from the PHP itself.

--SUGGESTION--

You are duplicating the id prdName for every image, so the behaviour of getElementById id unreliable, take a look at this answer to another question.

I suggest you to use a class instead, and a loop, to attach the click event handler to every element.

Also, i suggest you use a more javascript-like approach to the tags, to simplify the functions. With the current code, you are generating this HTML:

<img src="img_prd/something.jpg"
     input id="prdName"
     type="hidden"
     value="something_else"
     onclick="swapName()"
/>

This is not ideal, and also not valid HTML, your tag can't be an image and an input at the same time. If you wish an image you have to remove the input keyword entirely, togheter with the type="hidden", and change value to something like data-name, and you can remove onclick too, because we are attaching the handlers in javascript.

Here's an example of code to explain myself better:

$itemArray .=
'<img src="img_prd/'. $img .'"data-name="'. $name .'"/>';

Will produce this markup

<img src="img_prd/something.jpg" data-name="something_else"/>

That is in my opinion much cleaner and easier to work with.

Then, you can merge the functions imgClick and swapName.

To do so, you have to take the value from the image, maybe using data-* attributes. Inside the event listener function, imgClick in your case, you can use this to refer to the image, and use the data-name attribute to set the name.

Here's your javascript reworked:

<script>
    const current = document.querySelector("#current");
    const imgs = document.querySelectorAll(".imgs img");
    const opacity = 0.6;

    imgs[0].style.opacity = opacity;
    imgs.forEach(img => img.addEventListener("click", imgClick));
    function imgClick(e) {
        imgs.forEach(img => (img.style.opacity = 1));

        current.src = this.src;
        current.classList.add("fade-in");

        setTimeout(() => current.classList.remove("fade-in"), 500);
        this.style.opacity = opacity;
        document
            .getElementById('currentProfile')
            .setAttribute('value', this.getAttribute('data-name'));
    }
</script>
salvatore
  • 511
  • 4
  • 11
  • Hi! Thank you for your response!..I see what you mean about using a class and have changed it. i'm looking into forEach for js. but still confused. Is there a way to use the same forEach "imgclick" for the image and "prdName" – tyson Feb 01 '19 at 04:13
  • I've edited my answer to implement the concept, adapt the code to your needs if needed. – salvatore Feb 01 '19 at 09:25