Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

What method should I use to execute same code over and over again when a event is triggered?

I've created a program that:

  1. Asks a user a question
  2. Returns values related to their answer
  3. Creates another input box below returned values (prompt)

This currently works. However, I want now like to loop this code so that every time a user inputs something, it provides an answer and creates a new input box (repeating the process).

Any help would be greatly appreciated, thanks in advance.

const promptInput = document.getElementById('promptInput'); // 1st Input box
const commandResult = document.getElementsByClassName('result1'); // 1st returned values

promptInput.addEventListener('keyup', function(event){
    event.preventDefault(); // Event listener for input submission


    if(event.keyCode === 13) {  // If user presses enter
        let inputValue = promptInput.value; // Records value entered

// Returns related result to user entered value
    if(inputValue === "0"){
       $(promptInput).attr('readonly', true);
       $(commandResult).html('Skills: .............');

    } else if (inputValue === "1") {

       $(promptInput).attr('readonly', true);
       $(commandResult).html('Qualifications:............');

    } else if(inputValue === "2") {

       $(promptInput).attr('readonly', true);
       $(commandResult).html('About.........');

    } else if(inputValue === "3"){

       $(promptInput).attr('readonly', true);
       $(commandResult).html('Projects:.............');

    } else if(inputValue === "4"){

       $(promptInput).attr('readonly', true);
       $(commandResult).html('Contact details:..........');

    } else {
// If entered value not recognised return command not found
       $(promptInput).attr('readonly', true);
       $(commandResult).html(inputValue + ': command not found, please try again');
    }

// Create new input box and focus on it

        $('.new-prompt').html("<p> <span class=\"arrow\"> $ </span> <input class=\'prompt\' id=\"promptInput2\"></input> </p>");
        $('#promptInput2').focus();
    }
})

2 Answers

Steven Parker
Steven Parker
231,186 Points

You didn't show your HTML, but I'd guess you have an element that you overwrite with the new code. But it doesn't have a listener to be able to respond to input. So you might want to use a delegated handler attached to a common parent that would respond to newly-added elements. Since you are already using jQuery, you may want to use the "on" method with the optional "selector" argument to set this up.

Then, inside the handler, use DOM traversal based on the event object instead of specific element references This allows the handier to act on the element that triggers the event.

And lastly, it's not clear without the HTML if your intention is to replace each input as it is used, or add the others on. If the latter, you could use teh jQuery "append" method to extend the page.

Thanks for your help Steven. I have changed my code to use both the "on" and "append" methods now. The code now operates as before, however, the "on" method doesn't work on the newly added input boxes with the class "prompt".

I have attached the HTML for the document below. It is to create a replica terminal, so it prompts the user for a answer, that answer then returns a result below, and then provides a new input box below that for anymore user input. This process is meant to repeat over and over again but at the moment it simply works once. Creating 1 new input which doesn't trigger the event again.

Thanks in advance.

<div class="terminal">
<div class=fakeMenu>
  <div class="fakeButtons fakeClose"></div>
  <div class="fakeButtons fakeMinimize"></div>
  <div class="fakeButtons fakeZoom"></div>
</div>
<div class="fakeScreen">
  <p id="info-line">  </p>
    <div class="css-typing">

  <p class="typing line1">
        $ cd jordanwood/portfolio
      </p>
      <p class="typing line2">
        Passionate web developer with experience creating efficent websites
      </p>
      <p class="typing line3">
         using modern HTML, CSS and JavaScript.
      </p>
      <p class="typing line4">
        [?] What more would you like to know? Enter 0 for skills, 1 for
      </p>
      <p class="typing line5">
        qualifications, 2 for about, 3 for projects and 4 for contact details.
      </p>
       <p id="testing">
          <span class="arrow">$</span>
          <input class="prompt"></input>
       </p>
        <div class="result-container">

        </div>

        </div>
    </div>
</div>
</div>

Updated JavaScript:

const promptInput = $('.prompt');
const results = $('.result-container');

function stopInput(){
     $(promptInput).attr('readonly', true);
}

$('.prompt').on("keydown", function(event){
    if(event.which === 13){
        var inputValue = $(promptInput).val();

    if(inputValue === "0"){
        stopInput();
        $(results).append('<p class="result">Skills: HTML, CSS, JavaScript, jQuery, and PHP.</p>')
    }
    else if(inputValue === "1"){
            stopInput();
            $(results).append('<p class="result">Qualifications: Bachelor\'s Degree, Business Information Systems [2.1], Cardiff University. Extended Diploma in IT [Distinction*], Coleg Gwent.</p>');
    }
    else if(inputValue ==="2"){
        stopInput();
        $(results).append('<p class="result">About</p>');
    }
    else if(inputValue === "3"){
        stopInput();
        $(results).append('<p class="result">Projects</p>');
    }
    else if(inputValue === "4"){
        stopInput();
        $(results).append('<p class="result">Contact details</p>');
    }
    else {
        stopInput();
        $(results).append('<p class="result">' + inputValue + ': command not found, please try again</p>');
    }
     $(results).append('<span class="arrow"> $ </span> <input class="prompt"></input>');
     $('.prompt').last().focus();
    }
})
Steven Parker
Steven Parker
231,186 Points

To create a delegated handler you need to use the form of "on" that has the optional "selector" argument, and attach it to a common parent.

Then, inside the handler, use references based on the event object to access the correct input.

$(".css-typing").on("keydown", ".prompt", function(event) {  // delegated handier (3 arguments)
  if (event.which === 13) {
    var inputValue = $(event.target).val();  // use event.target for the current input

It worked, thank you!!