I'm trying to replace the old img.src with the value (new img.src) from input fields with Arrays.

The problem I'm stuck at is: the value in the arrays is replaced with the new value but the img.src inside HTML content does not change, so the img stay the same.

function changegallery() {
  var newimgURL = Array.from(document.querySelectorAll('#menuitems > input')).map(imgdata => imgdata.value);
  console.log('newimgURL', newimgURL);
  var oldimgURL = Array.from(document.querySelectorAll('#gallery > a > img')).map(imgdata => imgdata.src);
  var changeimgURL = oldimgURL.splice(0, oldimgURL.length, ...newimgURL);
  console.log('IMG', oldimgURL);
};
<form id="menuitems">
  <input type="url" id="changeimg1" placeholder="URL 1" />
  <input type="url" id="changeimg2" placeholder="URL 2" />
  <input type="url" id="changeimg3" placeholder="URL 3" />
  <input type="url" id="changeimg4" placeholder="URL 4" />
  <Button onClick={changegallery()}>button</Button>
</form>

<div id="gallery">
  <a> <img id="img1" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img2" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img3" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img4" src="https://via.placeholder.com/150"> </a>
</div>

fiddle: https://jsfiddle.net/cn1L4y7j/

2 Answers

0
Daniel Beck On Best Solutions

When you create a second array containing the original image src attributes and then modify that array to contain the new values -- these don't stay as references to the original DOM attributes, it's just an array of strings, so modifying it won't affect the page. Instead you need to explicitly insert those new values into the DOM.

function changegallery() {

  // read the new URLs
  var newimgURL = Array.from(document.querySelectorAll('#menuitems > input')).map(imgdata => imgdata.value); // note imgdata.value, not the whole image

  // Insert them into the DOM
  Array.from(document.querySelectorAll('#gallery img')).map((img, i) => {
    if (newimgURL[i]) { // don't replace with empty strings
      img.setAttribute("src", newimgURL[i])
    }
  })

};
<div id="menuitems">
  <!-- I've included some sample values for demo -->
  <input type="url" id="changeimg1" placeholder="URL 1" value="http://placehold.it/100x100"/>
  <input type="url" id="changeimg2" placeholder="URL 2" value="http://placehold.it/101x101"/>
  <input type="url" id="changeimg3" placeholder="URL 3" />
  <input type="url" id="changeimg4" placeholder="URL 4" />
  <Button onClick="changegallery()">button</Button>
</div>

<div id="gallery">
  <a> <img id="img1" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img2" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img3" src="https://via.placeholder.com/150"> </a>
  <a> <img id="img4" src="https://via.placeholder.com/150"> </a>
</div>

0
Andu Andrici On

The code below reflects our discussion in the comments to your post:

Recommendations :

  • Would be a nice idea to use some **classes** (in the example, added the imageInput and image classes) to more easily group the desired elements and target them within the DOM (not required, but a good practice and improvement).
  • The naming convention of choice should be either camelCaseNaames or underscore_names, not simple alllowercasenamesthatarehardtoread.
<form id="menuItems">
    <input class="imageInput" type="url" id="changeimg1" placeholder="URL 1" />
    <input class="imageInput" type="url" id="changeimg2" placeholder="URL 2" />
    <input class="imageInput" type="url" id="changeimg3" placeholder="URL 3" />
    <input class="imageInput" type="url" id="changeimg4" placeholder="URL 4" />
    <button onClick="changegallery()">button</button>
</form>

<div id="gallery">
    <a> <img id="img1" class="image" src="https://via.placeholder.com/150"> </a>
    <a> <img id="img2" class="image" src="https://via.placeholder.com/150"> </a>
    <a> <img id="img3" class="image" src="https://via.placeholder.com/150"> </a>
    <a> <img id="img4" class="image" src="https://via.placeholder.com/150"> </a>
</div>

The function could be re-written like this:

function changegallery() {
    var newImgURLs = Array.from(document.getElementsByClassName('imageInput')).map(input => input.value);

    var images = Array.from(document.getElementsByClassName('image'));
    images.map(function(img, i){
        img.src = newImgURLs[i] || null;
    });
};

The IDs serve no purpose with the current implementation. If you want for [changeimg1] to specifically change [img1]'s src value, then yes, they are good. If you want for the gallery to simply 'create a new set of images' based on this input, while discarding any unfilled inputs, they are useless.

And if the inputs do not affect the individual images (if only 3 images are added, only 3 images are shown in the gallery, as per discussed in the comments), you should simply re-create the gallery when uploading a new set of images:

function changegallery() {
    var gallery = document.getElementsById('gallery');
    gallery.innerHTML = '';

    Array.from(document.getElementsByClassName('imageInput')).map(function(input, i) {
        if (input.value != '') {
            gallery.innerHTML += '<a> <img id="img'+i+'" class="image" src="'+input.value+'"> </a> '
        }
    });
};