1

i Have created a site, wahts uses the HTML TEMPLATES. I can create the site and everything is showing correctly. But how can I update the values inside the template after creating?

HTML Part

...
<div class="row block-column align-items-center justify-content-center"></div>
<template id="DEVICE_TEMPLATE">
    <div class="col-2 col-xl-2"  align="center">
      <a class="tDeviceHref " >
        <img class="tDeviceImg" src="" height="50px" width="50px" title="">
      </a>
    </div>
    <div class="col-10 col-xl-4 "">
      <div class="devicePicture" align="center">
        <a class="tDeviceLabel  text-left" >Name</a>
      </div>
      <div class="progress" style="height: 25px;">
        <div id="opwnwblp1" style="width: 100%;" class="bg-secondary progress-bar progress-bar-animated progress-bar-striped">
          <div class="tDeviceVerbrauch "></div>
        </div>
      </div>
    </div>
</template>
...

This ist the JS part:

function createGui(devices){
  const templ = document.querySelector("#DEVICE_TEMPLATE")
  for (var i = 0; i < allDeviceGroups.length; i++) {
    // ...
    const clone = templ.content.cloneNode(true);
    clone.querySelector(".tDeviceImg").src = groupDevice["DEVICE"]["img"]["imgRunning"];
    document.querySelector(".block-column").append(clone);
    // ...
  }
}

The above code is only a part of the hole one with more settings to the template, but not relevant for my question.

If i reload the function createGui, the the gui will append again and again aso. I like to refresh only the values of the parts, like chnage the img for

   clone.querySelector(".tDeviceImg").src = groupDevice["DEVICE"]["img"]["imgRunning"];
Sven Kavon
  • 11
  • 3
  • Please show how you call this with suitable input data variables ( such as `allDeviceGroups` & `groupDevice` ) etc – Professor Abronsius Nov 26 '22 at 08:42
  • Is this realy relevant? If you see this: clone.querySelector(".tDeviceLabel").innerHTML = groupDevice["DEVICE"]["deviceName"]; you can exchange it with clone.querySelector(".tDeviceLabel").innerHTML = "whatever i will set here" So the question is not *what* to set, but how to update the value. – Sven Kavon Nov 26 '22 at 08:52
  • You need to clear everything before recreating, like for example with `temp1.innerHTML = ''` before your for loop – Lk77 Nov 26 '22 at 10:20

1 Answers1

0

As there was no means by which to run the code posted ( lacking key variables ) but perhaps you can see from this how to use the Template and update it's content?

const devices = {
  vintage: {
    src: 'https://www.funkidslive.com/wp-content/uploads/2021/12/ENIAC-changing_a_tube-1024x846.jpg',
    text: 'Vintage #1',
    online: false
  },
  gamer: {
    src: 'https://www.pcspecialist.co.uk/images/landing/seo/desktop-pc-lineup.jpg',
    text: 'Gamer #1',
    online: true
  },
  mainframe: {
    src: 'https://www.allaboutcircuits.com/uploads/articles/IBM_z16_.jpg',
    text: 'Mainframe #1',
    online: false
  },
  datacenter: {
    src: 'https://www.channelfutures.com/files/2016/11/server-room-mainframe-piece-scanrailthinkstock_0-707x432.jpg',
    text: 'datacenter #1',
    online: false
  }
};

const newdevices = {
  vintage: {
    src: 'https://media.cybernews.com/images/featured/2021/02/qw2ja4h83fz41.jpg',
    text: 'Vintage #2',
    online: true
  },
  gamer: {
    src: 'https://www.reviewgeek.com/p/uploads/2020/12/19a62eff.jpg',
    text: 'Gamer #2',
    online: false
  },
  mainframe: {
    src: 'https://blog.microfocus.com/wp-content/uploads/2014/02/Mainframe5011.png',
    text: 'Mainframe #2',
    online: true
  },
  datacenter: {
    src: 'https://www.dotmagazine.online/_Resources/Persistent/5/1/1/d/511dfa5ac97aed4f85bbb537bbef549e47121828/iStock-684619976%20DAta%20Center%20Models-1006x628.jpg',
    text: 'Datacenter #2',
    online: true
  }
}

let ref = {};

function createGui(device) {
  const templ = document.querySelector("#DEVICE_TEMPLATE").content.cloneNode(true);
  const src = devices.hasOwnProperty(device) ? devices[device].src : false;
  if (!src) return;

  // add a new wrapper div for the template and assign some sort of identifier
  // in this case a dataset atteibute.
  let div = document.createElement('div');
      div.dataset.device = device;

  // do whatever to the contents within the template you need
  let img = templ.querySelector('img.tDeviceImg');
      img.src = src;
      img.title = devices[device].text;
      img.alt = device;
      img.dataset.device = device;
  templ.querySelector('a.tDeviceLabel').innerHTML = devices[device].text;
  templ.querySelector('i.online').textContent = devices[device].online ? 'Online' : 'Offline'

  div.append(templ);

  // store a reference to the added template
  ref[device] = div;

  // add the template to the DOM within it's new container
  document.querySelector(".block-column").appendChild(div);
}








//load all the images calling a new template for each
Object.keys(devices).forEach(device => {
  createGui(device)
});





// Change all the images at some point...
// this is just to illustrate the identification and manipulation of the template contents
// after the initial pageload. There are other ways to do this of course.

setTimeout(() => {
  Object.keys(ref).some((device, index) => {
    // find the original HTMl based on the ref
    let oTmpl = ref[device];

    setTimeout(() => {
      // modify contents of template
      let img = oTmpl.querySelector('img.tDeviceImg');
          img.src = newdevices[device].src;
          img.title = newdevices[device].text;
          
      oTmpl.querySelector('a.tDeviceLabel').innerHTML = newdevices[device].text;
      oTmpl.querySelector('i.online').textContent = newdevices[device].online ? 'Online' : 'Offline'
    }, 1000 * index);
  });

}, 5000);
<div class="row block-column align-items-center justify-content-center"></div>

<template id="DEVICE_TEMPLATE">
  <div class="col-2 col-xl-2"  align="center">
    <a class="tDeviceHref">
    <img class="tDeviceImg" height="50px" width="50px" />
    </a>
  </div>

  <i class='online'></i><!-- online status of IOT device -->

  <div class="col-10 col-xl-4">
    <div class="devicePicture" align="center">
    <a class="tDeviceLabel  text-left" >Name</a>
    </div>
    <div class="progress" style="height: 25px;">
    <div id="opwnwblp1" style="width: 100%;" class="bg-secondary progress-bar progress-bar-animated progress-bar-striped">
      <div class="tDeviceVerbrauch"></div>
    </div>
    </div>
  </div>
</template>

update If you maintain a reference ( in a global variable for instance ) to the template when it is used you can call upon that variable when you need to update the content that has been added to the DOM already.

Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • Maybe I does not ask correct. But my question is not how i set the images *at creating* but how i *change* the images after they was successfull created. If i understand your code, than I cannot run Object.keys(images).forEach(device=>createGui(device)) twice or more, because the second call (and all calls after) will *not* update the first generated images, but create new ones - thats the problem in *my* code above. – Sven Kavon Nov 26 '22 at 09:10
  • OK, it was unclear or I misunderstood. Once the template has been used and content added to the DOM you then will have to query the DOM itself to perform further manipulations of the image – Professor Abronsius Nov 26 '22 at 09:32
  • But how i can do that without "ID"'s of the elements itself? I dont know then, what to update with which value? The "class" names are even. – Sven Kavon Nov 26 '22 at 09:34
  • Under what conditions are these to be updated? Is there any client interaction (ie: a click event ) that causes the update or other? – Professor Abronsius Nov 26 '22 at 09:38
  • No, this is a status page of IOT things like mesurement of power consume of devices or anything else. In most time, the img will not updated, but the values like "is online" or "use n watts of power". This infos will be read from json file, what will be created every 5 seconds at cli. I can add an ID to every element, whats for update, but it is a lot of code to parse this then again and set the values. My wish was, that the "template" mechanism can handle that however. – Sven Kavon Nov 26 '22 at 09:48
  • You could store a reference to the added template in a global variable and use that later to query the DOM. I found this was easier when I wrapped the template contents within a new DIV created in the `createGui` function – Professor Abronsius Nov 26 '22 at 11:05
  • I try now to add all relevant elements an id to update it later in code. Thank you for your support und tipps. – Sven Kavon Nov 26 '22 at 11:18