2

i have a select with a couple of options and I want to change the content of a div using innerHTML.replace every change in the select using JS only, My problem is that the content changes only at once per refresh and than it does not work anymore until i am not refresh the page.

(I am using FF, tried with Chrome too)..

Thank in advance !!

HTML CODE:

function func() {
  let mystudents = [{
      Name: "AAA",
      Year: 2,
      Age: 25,
      Exceptional: true
    },
    {
      Name: "BBB",
      Year: 2,
      Age: 25,
      Exceptional: false
    },
    {
      Name: "CCC",
      Year: 2,
      Age: 27,
      Exceptional: false
    },
    {
      Name: "DDD",
      Year: 2,
      Age: 26,
      Exceptional: true
    }
  ];

  let template1 = document.getElementById('first-item-template');
  let selected = mystudents[document.getElementById('student-list').value];
  template1.innerHTML = template1.innerHTML.replace('[Name]', selected.Name)
    .replace('[Year]', selected.Year)
    .replace('[Age]', selected.Age)
    .replace('[Exceptional]', selected.Exceptional);
}
<form>
  <label for="student-list">Choose a class:</label>
  <select name="student-list" id="student-list" oninput="func();">
    <option value="0"> Class1 </option>
    <option value="1"> Class2 </option>
    <option value="2"> Class3 </option>
    <option value="3"> Class4 </option>
  </select>
  <br><br>
</form>

<div id="first-item-template">
  <li>
    <span>[Name]</span><br>
    <label>Year: </label><span>[Year]</span><br>
    <label>Age: </label><span>[Age]</span><br>
    <label>Exceptional: </label><span>[Exceptional]</span><br>
  </li>
</div>
Always Helping
  • 14,316
  • 4
  • 13
  • 29
ValeriF21
  • 454
  • 1
  • 3
  • 14

2 Answers2

3

As mentioned in @SomoKRoceS answer, once you make the initial change, you won't find a match after that. But, instead of a replace method, just update the elements directly.

Some items to be aware of:

See additional comments inline:

<!-- If you aren't actually submitting data anywhere,
     you don't need the form element, nor do you need
     your form fields to have a name attribute. -->

   <label for="student-list">Choose a class:</label>
   <select id="student-list">
     <option value=""> --- Select --- </option>     
     <option value="0"> Class1 </option>
     <option value="1"> Class2 </option>
     <option value="2"> Class3 </option>
     <option value="3"> Class4 </option>
  </select>

  <div id="first-item-template">
    <!-- You can't have an <li> unless it's a child of an <ol> or <ul> -->
    <ul>
      <li>
        <span class="name">[Name]</span><br>
          <label>Year: </label><span class="year">[Year]</span><br>
          <label>Age: </label><span class="age">[Age]</span><br>
          <label>Exceptional: </label><span class="exceptional">[Exceptional] 
        </span>
        <br>
      </li>
    </ul>
 </div>

<script>
  // Just declare these once, not every time the function runs
  let mystudents = [
      { Name:"AAA", Year: 2, Age: 25, Exceptional: true},
      { Name:"BBB", Year: 2, Age: 25, Exceptional: false},
      { Name:"CCC", Year: 2, Age: 27, Exceptional: false},
      { Name:"DDD", Year: 2, Age: 26, Exceptional: true}];

   let template1 = document.getElementById('first-item-template');
   let name = template1.querySelector("span.name");
   let year = template1.querySelector("span.year");
   let age = template1.querySelector("span.age");
   let exceptional = template1.querySelector("span.exceptional");
   let studentList = document.getElementById('student-list');

   // Do your event binding in JavaScript, not HTML. And use the
   // "change" event here rather than "input".
   document.getElementById("student-list").addEventListener("change", func);

   function func() {
     let selected = mystudents[studentList.value];
     
     // Update the individual elements directly, not with a replace method.
     // Don't use .innerHTML when the strings don't contain any HTML, 
     // use .textContent instead.
     name.textContent = selected.Name;
     year.textContent = selected.Year;
     age.textContent = selected.Age;
     exceptional.textContent = selected.Exceptional;     
  }

</script>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
2

That is because after you changed it once, there are no longer strings corresponding to [Name] [Year] [Exceptional] and [Age] (The new value inside those labels are the previous selected value).

Replace function is searching for the string you give and replace it with the new string. But after the first replace, you will not find the initial strings.

If you want to change the content of the spans, you'll need to give each of them an id and change the id. Like that:

 <form>
   <label for="student-list">Choose a class:</label>
     <select name="student-list" id="student-list" oninput="func();">
       <option value="0"> Class1 </option>
       <option value="1"> Class2 </option>
       <option value="2"> Class3 </option>
       <option value="3"> Class4 </option>
    </select>
 <br><br>
 </form>

  <div id="first-item-template">
    <li>
      <span id="namespan" >[Name]</span><br>
      <label>Year: </label><span id="yearspan" >[Year]</span><br>
      <label>Age: </label><span id="agespan" >[Age]</span><br>
      <label>Exceptional: </label><span id="exceptionalspan" >[Exceptional]</span><br>
    </li>
 </div>

Then, in the function:

<script>
  function func() {
     let mystudents = [
      { Name:"AAA", Year: 2, Age: 25, Exceptional: true},
      { Name:"BBB", Year: 2, Age: 25, Exceptional: false},
      { Name:"CCC", Year: 2, Age: 27, Exceptional: false},
      { Name:"DDD", Year: 2, Age: 26, Exceptional: true}];


     let selected = mystudents[document.getElementById('student-list').value];
     document.getElementById('namespan').innerHTML = selected.Name;
     document.getElementById('yearspan').innerHTML = selected.Year;
     document.getElementById('agespan').innerHTML = selected.Age;
     document.getElementById('exceptionalspan').innerHTML = selected.Exceptional;

}

</script>
SomoKRoceS
  • 2,934
  • 2
  • 19
  • 30