0

How do I force a user to enter a valid time and valid number before pressing the button "Show"?

I have two fields in my html code and I found two good validation scripts in JS. One for time and one to determine if input field has a numeric value.

I can't change anything in the HTML.

function checkTime() {
  re = /^\d{1,2}:\d{2}([ap]m)?$/;
  if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
    alert("Wrong time!");
    return false;
  }
}

function checkRoomNr() {
  var numbers = /^[0-9]+$/;
  if (roomopt.value.match(numbers)) {
    console.log("is number");
  } else {
    console.log("not a number!");
  }
}
<div>
  <label for="time-until">Time</label>
  <input type="text" id="time-until">
</div>
<div>
  <label for="room">Room</label>
  <input type="text" id="room">
</div>
<button id="show-schedule">Show</button>
Andrew Lohr
  • 5,380
  • 1
  • 26
  • 38
Toms Eglite
  • 349
  • 1
  • 4
  • 13

4 Answers4

0

function checkTime( val ) {                     //Pass a value
  return /^\d{1,2}:\d{2}([ap]m)?$/.test( val ); //Return a boolean
}

function checkNum( val ) {    //Pass a value
  return /^\d+$/.test( val ); //Return a boolean
}

const time = document.getElementById("time-until"),
      room = document.getElementById("room"),
      show = document.getElementById("show-schedule");

function validateForm () {
  show.disabled = (checkTime( time.value ) && checkNum( room.value )) === false;
}

[time, room].forEach( el => el.addEventListener("input", validateForm) );
<div>
  <label for="time-until">Time</label>
  <input type="text" id="time-until">
</div>
<div>
  <label for="room">Room</label>
  <input type="text" id="room">
</div>

<!-- MAKE BUTTON DISABLED -->
<button id="show-schedule" disabled>Show</button>

Now you can reuse your functions like checkTime( val ) regardless of the input ID.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

If you want the validation to take place as data is being entered into the fields, you should set your functions up to run on the input event of the fields. If you want to wait until the user leaves the field and has made changes to the value of the field, then you can use the change event of the fields.

But, you'll also want the data to be checked when the form that contains the fields is submitted, so you need to set up a submit event handler for the form as well.

The way to connect a function to an event is to register the function as an "event handler" and that is done (using modern standards-based code) with the .addEventListener() method:

// First, get references to the elements you'll want to work with.
// And, use those variable names to reference the elements in your 
// code, not their IDs.
var timeUntil = document.getElementById("time-until");
var room = document.getElementById("room");
var form = document.querySelector("form");

// We'll set up a variable to keep track of whether there are any errors
// and we'll assume that there are not any initially
var valid = true; 

// Set up the event handling functions:
timeUntil.addEventListener("change", checkTime);
room.addEventListener("change", checkRoomNr);
form.addEventListener("submit", validate);

function checkTime(evt){
  re = /^\d{1,2}:\d{2}([ap]m)?$/;
  if(timeUntil.value != '' && !timeUntil.value.match(re)) {
    console.log("Wrong time!");
    valid = false; // Indicate an error
  } else {
    valid = true;
  }
}

function checkRoomNr(evt){
  var numbers = /^[0-9]+$/;
  if(!room.value.match(numbers)){
    console.log ("not a number!");
    valid = false; // Indicate an error    
  } else {
    valid = true;
  }
}

// This function is called when the form is submitted
function validate(evt){
  // Invoke the validation functions in case the fields have not been checked yet
  checkTime();
  checkRoomNr();
  if(!valid){
     evt.preventDefault(); // Cancel the form's submission
     console.log("Submission cancelled due to invalid data");
  }
}
<form action="#">
  <div>
    <label for="time-until">Time</label>      
    <input type="text" id="time-until">
  </div>  
  <div>
    <label for="room">Room</label>      
    <input type="text" id="room">
  <div>
  <button id="show-schedule">Show</button>
<form>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
-1

This may be a starting point basically you need to add event handlers and wire up time_untiloptand time_untilopt and add disabled to the show button. and listen for changes. There many ways, this is just an idea.

const button = document.getElementById('show-schedule');
const time_untilopt = document.getElementById('time-until');
const roomopt = document.getElementById('room');

function checkTime() {
  re = /^\d{1,2}:\d{2}([ap]m)?$/;
  if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
    alert("Wrong time!");
    return false;
  }
  return true;
}

function checkRoomNr() {
  var numbers = /^[0-9]+$/;
  if (roomopt.value.match(numbers)) {
    console.log("is number");
    return true;
  } else {
    console.log("not a number!");
    return false;
  }
}

function change() {
  button.disabled = !(checkTime() && checkRoomNr());
}
<div>
  <label for="time-until">Time</label>
  <input type="text" id="time-until" onchange="change()">
</div>
<div>
  <label for="room">Room</label>
  <input type="text" id="room" onchange="change()">
</div>
<button id="show-schedule" disabled="true">Show</button>
MotKohn
  • 3,485
  • 1
  • 24
  • 41
  • You edited your question. Don't have time to edit my answer, but idea is same. just set up eventhandlers from code. – MotKohn Dec 19 '17 at 20:09
  • Inline HTML event attributes should not be used. As such. `return true/false` shouldn't be used either. – Scott Marcus Dec 19 '17 at 20:21
  • @ScottMarcus I understand the inline HTML attribute part, but what is wrong with functions returning true/false? – MotKohn Dec 19 '17 at 20:29
  • Returning `true` or `false` only have an impact on event handlers when you are using inline event attributes. They won't cancel the event when you wire up event handlers using `.addEventListener()`. – Scott Marcus Dec 19 '17 at 20:31
  • @ScottMarcus oh. I'm not preventing the event, just disabling the "show" button. – MotKohn Dec 19 '17 at 20:33
  • But that is not the correct way to prevent someone from submitting a form, since forms can also be submitted by pressing the ENTER key in many situations. – Scott Marcus Dec 19 '17 at 20:35
-2

Inside both of your functions you'll want to set up your variables (time_untilopt and roomopt) to actually point to your two <input> fields. Then you'll simply want to return true if they pass validation, and return false if they don't.

To trigger these checks, you'll want to set up an onlick attribute for your submission, which is tied in to a third function, which I have named show(). This third function should conditionally check that both of the other functions return true. If they do, all is good, and you can continue with the submission. If they're not good, simply return false in this function as well.

This can be seen in the following:

function checkTime() {
  re = /^\d{1,2}:\d{2}([ap]m)?$/;
  var time_untilopt = document.getElementById('time-until');
  if (time_untilopt.value != '' && !time_untilopt.value.match(re)) {
    return true;
  }
  else {
    console.log("Wrong time!");
    return false;
  }
}

function checkRoomNr() {
  var numbers = /^[0-9]+$/;
  var roomopt = document.getElementById('room');
  if (roomopt.value.match(numbers)) {
    return true;
  } else {
    console.log("The room number is not a number!");
    return false;
  }
}

function show() {
  if (checkTime() && checkRoomNr()) {
    console.log('Both validations passed!');
    return true;
  }
  else {
    return false;
  }
}
<div>
  <label for="time-until">Time</label>
  <input type="text" id="time-until">
</div>
<div>
  <label for="room">Room</label>
  <input type="text" id="room">
</div>
<button id="show-schedule" onclick="show()">Show</button>

Also note that your checkTime() function is actually doing the exact opposite of what you want; if the time is not empty and matches the validation, you want to return true, not false. This has been corrected in the above example.

Hope this helps! :)

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • 1
    Inline HTML event attributes should not be used. As such. `return true/false` shouldn't be used either. – Scott Marcus Dec 19 '17 at 20:10
  • I've admittedly *never* heard anyone say that those should not be used before, but looking in to it, I can see a disadvantage or two. I will look further in to Unobtrusive JavaScript :) – Obsidian Age Dec 19 '17 at 20:29
  • 1
    Unfortunately, that technique is so ubiquitous that it will probably never go away, but it hasn't been the way to set up events since DOM Level 2 came out many, many years ago. See **[this](https://stackoverflow.com/questions/43459890/javascript-function-doesnt-work-when-link-is-clicked/43459991#43459991)**. – Scott Marcus Dec 19 '17 at 20:39