0

I'm making a loading screen for a game. The user will write a password, and a link to the level is given. I would like to remove the submit button and have the function activated by pressing "enter" on the keyboard, but I am unsure how to implement it into my code.

I found this code which I imagine will work: Jquery: how to trigger click event on pressing enter key

I've tried many times using the code in that answer to make "enter" activate the submit button, but I can't get it to work. I'm pretty new to javascript and altering code like this is still confusing to me. How can I make the submit button respond to "enter" in this situation? Below is the code I am using, the JSFiddle should show its purpose clearly. If you type "level one" "level two" or "level three" you will get "correct" as a response. Anything else you will get "incorrect"

$(document).ready(function() {
  $("#buttonsubmit").click(function() {
    $(".all").hide("fast");
    if ($('#passwordinput').val().toLocaleLowerCase() == "level one") {
      $("#levelone").show("fast");
    } else if ($('#passwordinput').val().toLocaleLowerCase() == "level two") {
      $("#leveltwo").show("fast");
 } else if ($('#passwordinput').val().toLocaleLowerCase() == "level three") {
      $("#levelthree").show("fast");
    } else {
      $("#incorrect").show("500");
    }
  });
  $("#passwordinput").change(function() {
    $("#incorrect").hide("500");
  });
});
.loadmenu {
 margin-top:0%;
 width:100%;
 height:100%;
 background:black;
 position:absolute;
 z-index: 17;
}
.loadtitle{
 width:90%;
 height:10%;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
.loadinput {
 width:100%;
 height:10%;
 line-height:20px;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
#passwordinput{
 font-size: 30px;
 width:85%;
 display:block !important;
}
#buttonsubmit{
 margin-top:3%;
 font-size: 26px;
 padding:5px;
 display:block !important;
}


#levelone {
  display: none;
  color:white;
  padding-bottom:10%;
}
#leveltwo {
  display: none;
  color:white;
  padding-bottom:10%;
}
#levelthree {
  display: none;
  color:white;
  padding-bottom:10%;
}
#incorrect {
  display: none;
  color:white;
  padding-bottom:10%;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="loadmenu" id="loadmenu">
 <div class="loadtitle">
load
</div>
<div class="loadinput">
<div class="all" id="levelone">
 correct
</div>
<div class="all" id="leveltwo">
 correct
</div>
<div class="all" id="levelthree">
 correct
</div>
<div class="all" id="incorrect">
incorrect password
</div>
<input type='text' id="passwordinput" />
<input type='button' id="buttonsubmit" value="Submit" />
</div>

  </div>
user2454060
  • 91
  • 1
  • 10

3 Answers3

1

You need to check the document object's keydown event for the key code of 13 (ENTER) and possibly 10 (CTRLENTER).

Different browsers give us different ways to obtain the key code, but since you are using JQuery, we can use event.which which will abstract that away and provide nice cross-browser support.

$(document).ready(function() {

  // Listen for keydown on the document
  // The callback function will be passed a reference to that
  // event and we should set up an argument to capture the reference
  $(document).on("keydown", function(event) {
  alert(event.which);
    // Check for ENTER key press
    // Different browsers use different event properties to provide
    // the key code. JQuery abstracts this for us if we use event.which
    if(event.which === 13 || event.which === 10){
    
      $(".all").hide("fast");
      if ($('#passwordinput').val().toLocaleLowerCase() == "level one") {
        $("#levelone").show("fast");
      } else if ($('#passwordinput').val().toLocaleLowerCase() == "level two") {
        $("#leveltwo").show("fast");
     } else if ($('#passwordinput').val().toLocaleLowerCase() == "level three") {
        $("#levelthree").show("fast");
      } else {
        $("#incorrect").show("500");
      }
    }
    
    $("#passwordinput").change(function() {
      $("#incorrect").hide("500");
    });
  });
});
.loadmenu {
 margin-top:0%;
 width:100%;
 height:100%;
 background:black;
 position:absolute;
 z-index: 17;
}
.loadtitle{
 width:90%;
 height:10%;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
.loadinput {
 width:100%;
 height:10%;
 line-height:20px;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
#passwordinput{
 font-size: 30px;
 width:85%;
 display:block !important;
}
#buttonsubmit{
 margin-top:3%;
 font-size: 26px;
 padding:5px;
 display:block !important;
}


#levelone {
  display: none;
  color:white;
  padding-bottom:10%;
}
#leveltwo {
  display: none;
  color:white;
  padding-bottom:10%;
}
#levelthree {
  display: none;
  color:white;
  padding-bottom:10%;
}
#incorrect {
  display: none;
  color:white;
  padding-bottom:10%;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="loadmenu" id="loadmenu">
 <div class="loadtitle">load</div>
 <div class="loadinput">
   <div class="all" id="levelone">correct</div>
   <div class="all" id="leveltwo">correct</div>
   <div class="all" id="levelthree">correct</div>
   <div class="all" id="incorrect">incorrect password</div>
   <input type='text' id="passwordinput">
 </div>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Thanks a lot. This answer was the easiest one for me to comprehend, since my original code is intact. However, the code only worked for me if I took out the "alert(event.which);". I forgot to mention I am using Electron, and that line seemed to cause a problem. – user2454060 Apr 05 '18 at 18:34
  • @user2454060 The `alert()` was just for testing. No worries removing it. – Scott Marcus Apr 05 '18 at 19:13
1

You can check the keycode using e.keyCode || e.which and make sure it is 13. I would define 13 as a constant ENTER to make the code clearer. Also, you can reduce the amount of code since the correct passwords are essentially equal to the ids that you want to show:

let valid = ["level one", "level two", "level three"];
const ENTER = 13;
function isValid(input) {
    return valid.indexOf(input) !== -1;
}

function submit() {
    $(".all").hide("fast");
    var input = $('#passwordinput').val().toLocaleLowerCase();
    if (isValid(input)) {
        $("#" + input.replace(' ', '')).show("fast");
    } else {
      $("#incorrect").show("500");
    }
}

$(document).ready(function() {
    $("#buttonsubmit").click(submit);

    $("#passwordinput").change(function() {
        $("#incorrect").hide("500");
    });

    $("#passwordinput").on('keydown', function(e) {
        var keypressed = event.keyCode || event.which;
        if (keypressed == ENTER) {
            submit();
        }
    });
});
.loadmenu {
 margin-top:0%;
 width:100%;
 height:100%;
 background:black;
 position:absolute;
 z-index: 17;
}
.loadtitle{
 width:90%;
 height:10%;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
.loadinput {
 width:100%;
 height:10%;
 line-height:20px;
 margin-left:5%;
 margin-top:10%;
 background:transparent;
}
#passwordinput{
 font-size: 30px;
 width:85%;
 display:block !important;
}
#buttonsubmit{
 margin-top:3%;
 font-size: 26px;
 padding:5px;
 display:block !important;
}


#levelone {
  display: none;
  color:white;
  padding-bottom:10%;
}
#leveltwo {
  display: none;
  color:white;
  padding-bottom:10%;
}
#levelthree {
  display: none;
  color:white;
  padding-bottom:10%;
}
#incorrect {
  display: none;
  color:white;
  padding-bottom:10%;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="loadmenu" id="loadmenu">
 <div class="loadtitle">
load
</div>
<div class="loadinput">
<div class="all" id="levelone">
 correct
</div>
<div class="all" id="leveltwo">
 correct
</div>
<div class="all" id="levelthree">
 correct
</div>
<div class="all" id="incorrect">
incorrect password
</div>
<input type='text' id="passwordinput" />
<input type='button' id="buttonsubmit" value="Submit" />
</div>

  </div>
dave
  • 62,300
  • 5
  • 72
  • 93
  • `keyCode` doesn't work in all browsers and `13` doesn't cover the two ENTER keys on most keyboards. – Scott Marcus Apr 05 '18 at 17:47
  • @ScottMarcus `event.keyCode || event.which;` should though... which is what I have – dave Apr 05 '18 at 17:48
  • `event.which` is all you need when using JQuery. Also, the first line of your answer doesn't mention `.which`. – Scott Marcus Apr 05 '18 at 17:50
  • Yes, but that may be desired to be trapped as well. I still don't get why you even bother with `e.keyCode` here. JQuery's `e.which` does the job. – Scott Marcus Apr 05 '18 at 17:58
  • @ScottMarcus because `e.which` is [deprecated](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which). I get the jQuery uses it, but I'd still rather be standards compliant – dave Apr 05 '18 at 18:00
  • But, it's not deprecated from [JQuery](https://api.jquery.com/event.which/) and the `event.which` that JQuery uses is their own implementation. It's not the same `event.which` from the DOM. [JQuery callback functions get a customized `event` object passed to them.](https://api.jquery.com/category/events/event-object/) It encapsulates checks for client compatibility, which is what JQuery is known for. – Scott Marcus Apr 05 '18 at 18:01
  • Thanks a lot for your answer. This code worked as well, but I was able to understand easier the code sent by Scott. – user2454060 Apr 05 '18 at 18:35
1

Your current architecture is going to leave you hurting as the project grows. You need to think about "things-your-app-does" and "events-that-make-things-happen" as related but distinct things within your codebase.

So, for example, the logic in your submit function should be moved into a function that doesn't really care how it was called:

function getEnteredPassword(){
    $('#passwordinput').val().toLocaleLowerCase();
}

function unlockLevel(password){
    $(".all").hide("fast");
    if (password == "level one") {
        $("#levelone").show("fast");
    } else if (password == "level two") {
        $("#leveltwo").show("fast");
    } else if (password == "level three") {
        $("#levelthree").show("fast");
    } else {
        $("#incorrect").show("500");
    }
}

You can then call this function from wherever you want to, or from multiple places:

var KEY_ENTER = 13;
$(document.body).keyup(function(event) {
    var key = event.which;
    if (key === KEY_ENTER) {
        unlockLevel( getEnteredPassword() );
        // The event is handled... don't do other stuff
        event.preventDefault();
    }
});

$("#buttonsubmit").click(function() {
   unlockLevel( getEnteredPassword() );
});

You could, and probably should, take this example even further. Your unlockLevel function probably shouldn't have hardcoded element selectors in it... this should be defined somewhere else so that if you change the selectors later you'll only need to update one line of code instead of crawling your entire codebase.

The point is to separate the core game logic from the UI layer. Events and elements should be hidden behind and accessed via one-off functions (or, as complexity grows, object instances). This makes your code both easier to read and easier to maintain. You can change your UI (elements, events, etc) with very minimal changes (if any) to your game logic.

JDB
  • 25,172
  • 5
  • 72
  • 123
  • IMHO `var key` isn't necessary given that you only use the `key` variable once, on the very next line after you declare it. – Scott Marcus Apr 05 '18 at 18:12
  • @ScottMarcus - I prefer clarity in my code. Named variables help to communicate intention and is generally easier to read. A good minifier will resolve this easily. – JDB Apr 05 '18 at 18:14
  • Thanks a lot for your answer and advice. – user2454060 Apr 05 '18 at 18:36