0

I using javascript to check the length of height input by the user and but the problem I am facing is that even javascript just check the first number of the input and throws an error. Just for eexample if I have to input 45 in the height, I get an error height must be between 6-36 just after entering 4 it doesnt let me enter 5 and when i try to remove move and it input becomes empty It again throws an error height must be between 6-36. Please help me find the problem.

<input type="number" id="message1" name="height" oninput="function_two()">

function function_two() {
    var FrameHeight = document.getElementsByName('height')[0].value;
    if (FrameHeight <= 36 && FrameHeight >= 6) 
        return true;
    else 

    alert("Height must be between 6-36");
  }
User7777
  • 289
  • 4
  • 19
  • 2
    Use `onchange`, or a form and a submit event listener. But please, please, please don't use inline event attributes. They are the devil. –  Nov 20 '18 at 22:49
  • Try the `onblur` event instead of `oninput`. That will wait until the input loses focus. (Or `onchange` like Tiny Giant said... that will wait until the input is changed *and* loses focus which is probably better...) – mpen Nov 20 '18 at 22:50
  • How is the code supposed to know how many digits you want to add? I suggest you either use onblur as the event, that is fired when user leaves the input, or use a slider or (there is another html5 element that I don't remember), to restrict the value to your limits – kkica Nov 20 '18 at 22:50
  • What if you used a text input rather than a number? – Caleb H. Nov 20 '18 at 22:50
  • @TinyGiant They're not identical. Yours is better. – mpen Nov 20 '18 at 22:51
  • function_two() is a terrible method name .... I wonder what function_one() does? – HaukurHaf Nov 20 '18 at 22:51
  • @CalebH. input type is number. – kkica Nov 20 '18 at 22:51
  • @HaukurHaf technically it isn't a method because it isn't part of an object[.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions) –  Nov 20 '18 at 22:53
  • 1
    @TinyGiant well, it's a part of the window object ..... :-) – HaukurHaf Nov 20 '18 at 22:57
  • @HaukurHaf I suppose that counts. –  Nov 20 '18 at 22:58

7 Answers7

2

You are using the wrong event (input), which fires as any input is given to the field. Use the change event, which fires when the value changes and the field loses the focus.

Additionally, separate your JavaScript from your HTML. Do your event handling with modern, standards-based practices, rather than with inline HTML event attributes, which should not be used.

See the comments below for other adjustments to the solution that make the code more efficient and/or update it to modern standards.

// Get your DOM reference just once. .querySelector() is preferred
// over .getElementsByName, .getElementsByTagName, .getElementsByClassName
// as the former returns a static node list and the latter(s) return 
// live node lists that hurt performance.
let nameInput = document.querySelector("input[name='height']");

// And set up event handlers in JavaScript, not HTML
nameInput.addEventListener("change", rangeCheck);

// Name functions with descriptive names as to what they do.
// Don't use the word "function" in a function name.
function rangeCheck() {
    // In a DOM event handler, you can just use "this" as a reference
    // to the DOM element that triggered the event.
    var FrameHeight = this.value;
    // Just test for the bad values and act accordingly
    if (FrameHeight < 6 || FrameHeight > 36) {
      alert("Height must be between 6-36");
    }
}
<input type="number" id="message1" name="height">
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
2

How is the code supposed to know how many digits you want to add? So that it triggers the validation? At the moment, the function is called every time the user gives an input, that is every time a user types.

I suggest you either use change as the event, that is fired when user leaves the input after it changes it, or change the type to range. This way you don't need to do the validation.

I would advice you use <input type="range" min="6" max="36" step="1" /> if you can. Note that it is not supported by all browsers as it is a HTML5 element.

kkica
  • 4,034
  • 1
  • 20
  • 40
1

Sounds like you have a few problems and therefore a couple possible solutions

If you want the error to appear after your first character but still want to be able to keep entering characters until the requirements are met, try displaying the error by adding it to your page somewhere instead of using alert.

If you want to only check the value when someone is done typing, you can use onchange instead of oninput, though this means that the user will have to defocus the input.

If you want to check the value when someone is done typing but without having to defocus the input you should look into using a debounce function. Underscorejs has a good one or you can write your own.

nathan.medz
  • 1,595
  • 11
  • 21
1

The function is ok. 4 is less than 6 therefore it throws an error. The best way forward is to run function after user has finished typing. To do this, edit the html section to onchange.

<input type="number" id="message1" name="height" onchange="function_two()"> 


function function_two() {
 var FrameHeight = this.value;
  if( trim (value ) == '' ){
     return false;
   }
  if (FrameHeight < 6 || FrameHeight > 36) { 
     alert("Height must be between 6-36");
   } 
}
  • `onblur` fires even if there is no change. I fail to see how that is "The best way" to proceed. –  Nov 20 '18 at 22:57
  • You can return false if trim value equals '' – Edwin Dijas Chiwona Nov 20 '18 at 23:01
  • 1
    I fail to see how that would solve the problem of calling the function when there is no change. The `change` event is dispatched when the input blurs and the value has changed, no point in reinventing the wheel. This is literally not "The best way forward". 100% –  Nov 20 '18 at 23:04
  • 2
    The `input type` is `number`. Spaces aren't allowed in the field in the first place, so `trim()` is not needed. – Scott Marcus Nov 20 '18 at 23:06
  • @scott i never had trim in the first place. I like your answer. You are using change which i suggested earlier and someone voted me down. Then i added the return false... :) – Edwin Dijas Chiwona Nov 20 '18 at 23:10
  • The initial version of your answer uses `onblur` just like your current version. As far as I can tell you have not suggested the use of the `change` event. –  Nov 20 '18 at 23:19
  • Onblur works as well, but as pointed, it is not the best. Corrected to onchange. Thanks for the pointers. – Edwin Dijas Chiwona Nov 20 '18 at 23:36
  • Your answer involves a call to `trim()`, which isn't declared anywhere. It implies you meant space trimming (as you've passed `value` to it). So, how can you say you never had `trim` in the first place? The OP doesn't use it and your answer does. – Scott Marcus Nov 21 '18 at 02:58
0

You are validating each keystroke entered, so you may want to combine a combination of oninput and onblur to validate the entire value and the keystrokes as they happen.

Try something like this:

<html>
<head>
<style>
    input.invalid {
        background-color: red;
    }
</style>
<script>
    function validateInput(inputElement) {
       var frameHeight = inputElement.value
       if (isValidHeight(frameHeight)) {
           inputElement.className = ""
       } else {
          inputElement.className = "invalid"
       }
    }

    function validateFrameHeight(inputElement) {
        var frameHeight = inputElement.value
        if(!isValidHeight(frameHeight)) {
            alert("Height must be between 6-36");
        }
    }

    function isValidHeight(frameHeight) {
        return frameHeight <= 36 && frameHeight >= 6
    }
</script>
</head>
<body>

    <input class="invalid" type="number" id="message1" name="height" oninput="validateInput(this)" onblur="validateFrameHeight(this)">

</body>

Ian Pilipski
  • 507
  • 3
  • 8
  • 1
    This seems like an even worse idea. I seriously do not get the aversion to using the proper event (`change`), and the need to reinvent the wheel for absolutely no reason. –  Nov 20 '18 at 23:21
  • Agree and disagree. I agree that change is a better event for validation than blur. However I disagree that oninput is a bad way to get real-time feedback on your currently entered data. – Ian Pilipski Nov 21 '18 at 20:00
  • But the problem is that they don't need real time feedback, the need feedback on change. Hacking `oninput` and `onblur` together to make a fragile substitute for `onchange` is not a good alternative to `onchange`. –  Nov 21 '18 at 20:24
0

@TinyGiant thankyou. it worked

onchange="function_two()"
User7777
  • 289
  • 4
  • 19
0

I would think focus out event would help https://api.jquery.com/focusout/