0

I want a user to input their top ten favourite movies, each in a separate text input field. As they type in a box, a 'onkeyup' event triggers a JS function, which makes what they are typing reappear directly below where they are typing.

Do I have to write out ten different JS onkeyup functions for each box, or is there a relatively straightforward way that a single function can do the job, via the means of variables or somesuch?

Maybe this make things clearer:

HTML

<form id="movie1">
<h3>Your favourite movie</h3><br><br>
Type the name of your favourite movie: <input type="text" name="name" maxlength="50" onkeyup="inputMovieOne()">
<p>Your favourite movie:<span id=movie1goeshere></span><span></p>
</form>

<form id="movie2">
<h3>Your second favourite movie</h3><br><br>
Type the name of your second favourite movie: <input type="text" name="name" maxlength="50" onkeyup="inputMovieTwo()">
<p>Your second favourite movie:<span id=movie2goeshere></span><span></p>
</form>

...and so on eight more times...

JS

<script>
function inputMovieOne() {

  var x = document.getElementById("movie1").elements.namedItem("name").value;

  document.getElementById("movie1goeshere").innerHTML =  x;
}

function inputMovieTwo() {

  var x = document.getElementById("movie2").elements.namedItem("name").value;

  document.getElementById("movie2goeshere").innerHTML =  x;
}
</script>

...and so on eight more times...
Stephen
  • 47
  • 6

1 Answers1

0

You should consider avoiding inline handlers - they have way too many problems to be worth using in a modern codebase. Instead, select the input box and add a keyup listener to each using addEventListener. On keyup, navigate to the <span> on the next element by referencing the input.nextElementSibling.children[0], and change its text:

for (const input of document.querySelectorAll('input')) {
  input.addEventListener('keyup', () => {
    input.nextElementSibling.children[0].textContent = input.value;
  });
}
<form >
<h3>Your favourite movie</h3><br><br>
Type the name of your favourite movie: <input type="text" name="name" maxlength="50" >
<p>Your favourite movie:<span ></span><span></p>
</form>

<form >
<h3>Your second favourite movie</h3><br><br>
Type the name of your second favourite movie: <input type="text" name="name" maxlength="50" >
<p>Your second favourite movie:<span ></span><span></p>
</form>

Note that unless you're explicitly inserting HTML markup, you should not use innerHTML - innerHTML is slower and more unsafe than assigning to the textContent of an element. Best to set textContent by default, and only use innerHTML when you have HTML markup that you know is safe.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • That works amazingly, thank you! I learned about 4 separate things from your reply (nextElementSibling, children, inline handlers, and .textContent). But a new problem occurred, in the way that all whitespace is reduced to a single space. So for example, lets say the person types ' Dirty Dancing ', it will reappear as ' Dirty Dancing '. Do you know, is there a straightforward fix for this, so that all the whitespace reappears? – Stephen May 16 '20 at 21:19
  • Multiple white spaces in HTML get condensed into a single one. I guess if you need to accept multiple whitespaces, you can use a regular expression to replace all spaces in the input value with ` ` and then set the `.innerHTML` - but since you have to use `innerHTML`, you'll also want to escape tag delimiters and replace `<`s as well. – CertainPerformance May 16 '20 at 23:21