Search code examples
javascripthtmleventsonmouseoutonfocusout

Why doesn't setting an input type="number" to type="text" in an mouseout event handler working?


Goal:

I have an input element in which the user should enter a number between 1 and 999, optionally may use the (input type="number") up/down spinner, but when the mouse isn't over this element or the element doesn't have the focus, I want the input element to be of 'text' type to ensure that the input is sized to only show the element's value without the spinner showing or the blank area of the hidden spinner. This way the value in the input element and the text to the right of the element doesn't move whether the element is of type 'text' or 'number', the element has the focus or not, or the mouse is over the element or not.

Background:

Currently, I'm initially setting the input element's type to 'text', margin-left to '2ch', and width to '4ch', then when the mouse is over the element, I set the element's type to 'number', margin-left to '0', and width to '6ch'. When the mouse moves off of the element or the element looses focus, I set these properties back to their initial values.

Code:

<style>
  /* Number text (1/3 etc) */
  .numbertext { color: #f2f2f2; font-size: 12px; padding: 8px 12px; position: absolute; top: -90px; }
</style>
<div class="numbertext">
  <input type="text" style="text-align: right; margin-left: 2ch; width: 4ch;" min="1" max="999" value="1"
         onmouseover="setInputType( 'number' );"
         mouseout="setInputType( 'text' );"
         onblur="setInputType( 'text' );" />/
  <span>999</span>
</div>
<script>
  function setInputType( type ) {
    var input = window.event.currentTarget;

    if( type === 'text' ) {

      input.style.marginLeft = '2ch'; 
      input.style.width      = '4ch';

    }
    else {

      input.style.marginLeft = '0'; 
      input.style.width      = '6ch';

    }
    input.type = type;
  }
</script>

Problem:

When the page initially shows, the code displays the way that I want, hovering the cursor over the field or focusing on it works, too. However, moving the mouse away from the field after the mouse hovered over the it, or the field looses the focus, inconsistently restores the initial setting of the input element because the mouseout and blur event handlers aren't always triggering. I know this because putting a breakpoint on the setInputType function's if( type === 'text' ) statement branch and running the code in the Chrome inspect > source panel doesn't stop the code execution when the mouse moves away from the element after it mouse was moved over it.

Any ideas about why the mouseout and blur event handlers aren't properly working consistently?

Solution:

This CodePage shows a fully working solution that includes Bryan Elliott's correction and Jon P's suggestion.

Thanks


Solution

  • On your element events, you have mouseout="...", It needs to be: onmouseout="..."

    Like this:

    <input
        type="text"
        style="text-align: right; margin-left: 2ch; width: 4ch;"
        min="1" max="999"
        value="1"
        onmouseover="setInputType( 'number' );"
        onmouseout="setInputType( 'text' );"   //notice the onmouseout=""  instead of mouseout=""
        onblur="setInputType( 'text' );"
    />