onchange without losing focus?
Asked Answered
V

6

15

I'm creating a form with a select dropdown. One of the options is "other - please specify", which is supposed to display an extra text field for more details.

I managed to do it using onChange event + some simple value check (as I can't rely on the position).

I started testing it and realized that while it works perfectly when using a mouse (onChange is ran after the control loses focus), it doesn't when I use the keyboard (since it didn't lose focus yet) - only after I press tab do the changes appear (which looks weird).

It seems to me like I'm missing something obvious, I looked for other events and the closest I've found is onclick, but that's not it either.

So the question is, is there a better way of solving this?

Vonnie answered 2/9, 2009 at 15:42 Comment(0)
E
10

You can simply add this to the <select> tag:

onkeyup="this.onchange();"
Edelsten answered 30/11, 2010 at 11:51 Comment(0)
K
5

You can use the "input" event instead:

dropdown.addEventListener("input", () => {alert("CH-CH-CH CHANGES!")})

I made a quick example here: https://codepen.io/sekmo/full/rNKzedZ

PS: the "input" event is what also React is using for the onChange property :)

Kaka answered 15/11, 2022 at 10:36 Comment(1)
So react was fooling us about what onChange actually does the whole time, and no one complaints.Piperpiperaceous
X
3

onkeyup="this.onchange(); but keyup event may fire if there's no change

Xiphisternum answered 6/1, 2012 at 14:32 Comment(0)
G
2

This article might help you. It uses tricks like so:

// executes an onchange function after 750ms (or specified delay)
function safeOnChange1( code, delay ) {
  delay = delay || 750;
  window.clearTimeout( soc_id );
  soc_id = window.setTimeout( code, delay );
} 
// global timer ID for the safeOnChange1 function.
var soc_id = null;

It's not pretty but that's the problem with using the onchange function on a dropdown. The other solution would be a function checking the value of the dropdown every once in a while and calling the onchange function if it changed.

Look up tutorials like this: http://onlinetools.org/articles/unobtrusivejavascript/chapter4.html

function addEvent(obj, evType, fn){ 
 if (obj.addEventListener){ 
   obj.addEventListener(evType, fn, false); 
   return true; 
 } else if (obj.attachEvent){ 
   var r = obj.attachEvent("on"+evType, fn); 
   return r; 
 } else { 
   return false; 
 } 
}
addEvent(window, 'load', foo);
addEvent(window, 'load', bar);

There's also a jquery way if you can look it up

Gospodin answered 2/9, 2009 at 15:50 Comment(0)
V
1

Examples Using angular and jquery you can achieve this as you want ,

$("#mytxt").on('keypress', function() {
  console.log($("#mytxt").val())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  Angular Example: <input type="text" ng-model="bad" ng-change="badri(bad)"/>
  <br/>
  jQuery Example: <input type="text" id="mytxt">
</div>
<script>
var app = angular.module("myApp", []); 
app.controller("myCtrl", function($scope) {
    $scope.badri = function(v) {
      console.log(v)
    }
});  
</script>
Vitals answered 28/7, 2017 at 12:30 Comment(0)
L
1

This is how to use 'marcgg' answer, (It is the only correct answer here BTW and was the first idea came to my mind before googling it) :

        // executes an onchange function after 750ms (or specified delay)
        function safeOnChange1(code, delay) {
            delay = delay || 750;
            window.clearTimeout(soc_id);
            soc_id = window.setTimeout(code, delay);
        }
        // global timer ID for the safeOnChange1 function.
        var soc_id = null;

    $('#your-input-element').keyup(function () {
        safeOnChange1(function () {
            var finalInputValue = $('#your-input-element').val();
            if (finalInputValue != "") {
                //do the work here
                console.log(finalInputValue);
            }
        }, 1000);
    });
Listed answered 17/9, 2018 at 19:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.