Pass additional information into event handler - javascript

I have an event handler that is executed when an option in a selectbox is clicked.
$('#my-select').live('change', function(evt) {
....
});
Is there a way to pass the status of the Ctrl-key (pressed/not pressed) into the event handler ? evt does not contain this information because all key related attributes are undefined.

change event and the keys used to enter the value
The change event is not something that has keys associated. Please read jQuery's .change() documentation:
The change event is sent to an element when its value changes. This event is limited to elements, boxes and elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
The example is this:
You have some input field.
You enter "some name" text into the field.
Before going to some other field, you decide to change it to "some test", eg. by hitting backspace couple times, then you navigate to next field (eg. by using Tab key, or by tapping Next on iOS keyboard etc.),
The onchange event handler is fired, when you navigate to other field (or rather, as soon as the field loses focus), so the information about all keys used to enter value are pretty unrelated.
Solution using keypress event
To solve that problem, you would need to implement your solution using keypress event, eg. thanks to jQuery's .keypress() function. In such case, event object's ctrlKey attribute (listed eg. here) lets you know about the status of the Ctrl key. Example usage is here: https://stackoverflow.com/a/4604093/548696
Demo for saving keys on keypress/keydown/keyup and reading on change
It is available here:
http://jsfiddle.net/tadeck/vPu94/
The demo clears the recorded keys on focus, saves them on every keypress event (you can easily edit that and test different cases) and reads them (and outputs on the screen) whenever change event is fired (so when the changed field leaves focus).

Related

Click vs Input vs Change for checkboxes?

I have a form. I want to only allow form submit if the user checks precisely 4 out of 8 available checkboxes; and once the user checks 4 checkboxes I want to disable the remaining unchecked ones.
Should I add a hook to the click event? Or maybe the input event? Or perhaps the change event?
I'm overwhelemed by the amount of events that seem to duplicate each other's functionality.
I'm also confused by the documentation.
MDN docs about input:
For <input> elements with type=checkbox or type=radio, the input event should fire whenever a user toggles the control, per the HTML5 specification. However, historically this has not always been the case. Check compatibility, or use the change event instead for elements of these types.
MDN docs about change:
Unlike the input event, the change event is not necessarily fired for each alteration to an element's value.
And below:
Depending on the kind of element being changed and the way the user interacts with the element, the change event fires at a different moment:
When the element is :checked (by clicking or using the keyboard) for <input type="radio"> and <input type="checkbox">;
MDN docs about click:
An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.
Practice:
The below JS fiddle seems to hint that all 3 events are equivalent. Clicking the checkbox, clicking the label, focusing the checkbox and pressing space on keyboard seem to all fire all three events.
const checkbox = document.querySelector('input[type=checkbox]');
for (const event of ['input', 'click', 'change']) {
checkbox.addEventListener(event, () => {
log.textContent = `${event}\n${log.textContent}`
})
}
<label>Toggle <input type="checkbox" name="" id="">
</label>
<pre id="log"></pre>
As per the docs change and input seem equivalent; click does not seem equivalent to the other 3 as per the docs but in practice it seems equivalent.
Do we really have 3 events that duplicate each other's functionality? Does it matter in any way which event I use?
Or am I missing something?
These 3 events duplicate each other's functionality because you are looking at a checkbox which happens to be a special case.
For example, if you were to take a text field
The event input will fire whenever the text in an element is changed using the user interface.
The event change will fire (on most browsers) whenever the text element loses focus. It would only be triggered once instead of after every keystroke.
The event click will fire whenever a user clicks on the text field.
If we were to apply this to checkboxes (keeping in mind there is only one thing a checkbox can be changes into: either checked => unchecked orunchecked => checked)
The event input will fire whenever the checked state is changed using user interface.
The event change will fire whenever the checked state has changed
in an element (or when the checkbox loses focus in IE).
The event click will fire after the check state has finished changing .
The 3 events have very similar functionality (almost duplicates) because they are all trying to do something different that functionally does the same thing on checkboxes. The only differences being subtle implementation details.
I would use click to avoid having issues from the user of diffrent browsers.
They are not duplicated. There are subtle differences.
change happens once the value or state changes, and the element loses focus.
$('input').on('change', function(){
console.log('changed');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1">
<input type="text">
click happens once the element is clicked.
input happens IMMEDIATELY once the value or state changes, before it loses focus. This happens regardless of if the state changes as per a mouse or keyboard event. A checkbox can change state by clicking it, or focusing on it and hitting the spacebar. A click event would not catch the spacebar state change.
$('input').on('change', function(){
console.log('changed');
});
$('input').on('input', function(){
console.log('input');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" value="1">
<input type="text">
To test the lack of focus change and the spacebar change on the checkbox, you can click the input box and then shift+tab to focus the checkbox to hit spacebar. It appears from the fiddle that for checkboxes, the change and input events both happen any time it changes, even without the focus being lost.
This differs from how the text field behaves. So there appears to be some behavioral differences between the two elements in when the events are generated. The checkboxes appear to follow a less strict implementation of the pattern, as opposed to input boxes.

Is it possible to determine the type of input from the input handler?

I have an event handler for the 'input' event:
inputEl.addEventListener('input', function(event) {
log('yaay!')
});
I need to do something just for paste. I know I could make a separate event handler for 'paste' only, however I share code for most types of inputs and would like to avoid extra listeners if not necessary. Is it possible - for example, by checking a property of the event object, to see if a input event was initiated by pasting?
From what I can see, there is no way to do that without binding a separate event listener.
The event object has no "input type" methods that I can see in the log, so just checking for an input you cannot determine if typed or pasted. It's just plain input.
For example (from a deleted answer I saw), checking say, event.type in the input listener will yield input whether you typed or pasted.

What event to know when user has entered data into form?

I have a HTML form. I want to enable/disable a button until user eneters text in one of the fields. I am adding an event attribute to the which triggers some javascript. This javascript will enable/disable the button.
Problem is I can't figure out what event attribute to use. What event attribute please will trigger as soon as user enters data? I tried onchange but that only gets called when i clicked back outside the text area. So it may aswell be onblur.
You can use the input
function activateForm (event) {
if(!this.value == ""){
}
}
var input = document.querySelector(".myInput");
input.addEventListener("input", activateForm , false)
There are 2 possible events that can be used: either onChange or onKeyPress. onChange will trigger when the value of an input has changed while onKeyPress will trigger every time the user types something in a text box. The onChange triggers once the user has CHANGED something in the value, and got out of the input focus. That means the user has to hit TAB or click somewhere else for the event to trigger, hence why onKeyPress might be better suited.
Read more:
http://www.w3schools.com/jsref/event_onchange.asp
http://www.w3schools.com/jsref/event_onkeypress.asp
Younger browsers also support onInput which should certainly be prefered for now, if you do not need to support older browsers.

Selecting from a drop down ( browser cached drop down ) - which event gets triggered?

Gist
Which event gets triggered when we select from a dropdown which is populated from the cache ( such as usernames and other form values ) in a <input type="text"> .
Detailed
In a form, we can login with multiple username say A,B,ABC . And the browser caches all these values ( w.r.t password remember ). So,if we try to login with A - a drop down pops up giving multiple option say A , ABC -- which event gets triggered once we select any of the options provided.
oninput, onchange, onblur -- none of which seems to get triggered if we select from browser provided drop down.
Help,
Beginner
You can use these events with select.
Cache has nothing to do with the drop down.
What you need is depending on your use.
Generally onchange is used to get the value or call a function when the value changes.
onblur would trigger a function when the drop down losses focus. eg, when you use tab or other methods.
This question is answered here: On input change event?
In modern browsers use the input event. This event will fire when the user is typing into a text field, pasting, undoing, basically anytime the value changed from one value to another.
easily use select event
example:
$('#test').select(function(){ alert('data changed'); });

Is it possible to set the pre-change value of an input element

I have an input element with an onchange event. The onchange event alerts the user if the value is not accepted, and returns focus back to the input element.
However, if the user then clicks out of the element, the onchange event doesn't fire - which is understandable since the user hasn't made a further change, but it introduces the problem of only validating once.
I explored a possible solution to reset the value back to what it was before it was changed, but I'd like to avoid that if at all possible for the sake of allowing the user to correct the value they entered without having to type the whole thing again.
Another possibility was to put the validation into the blur event but this would introduce other problems such as events on other elements firing if they are focused.
So my question is, if the user changes the input value from 'X' to 'Y', can I return focus to the element, leaving the value as 'Y' but make it treat 'X' as the pre-change value, thus behaving so if the user changes it back to 'X' the change event will not subsequently fire, but if they leave it as 'Y' and lose focus again, the change event fires again as if changing from 'X' to 'Y'?
Why not just mark the field as invalid (using CSS or jQuery to add markup) instead of using an alert? The field remains invalid until the user changes the value to a valid one, and the validation script removes the invalid marking.
Is the input type text? In these circumstances I prefer to use onkeyup instead of onchange for the very reason you're describing.
Sometimes even that doesn't work: This will not capture the change when text is pasted into the text box using a mouse since a key isn't pressed (but shift+insert or ctrl+v are). You might want to add the same event to both onchange and onkeyup to cover all bases.

Categories

Resources