I've attached an onBlur event handler in a React component in which the logic sets the focus back to the target element (and writing this in TypeScript).
emailBlur(e: React.FocusEvent<HTMLInputElement>) {
e.currentTarget.focus();
e.preventDefault();
// re-ordering these statements makes no difference
}
This is bound
<input type="email" onBlur={this.emailBlur} />
Furthermore, the constructor contains
this.emailBlur = this.emailBlur.bind(this);
But the focus never gets set - if I click from the target element to another element, the focus never goes back to the target element.
Why isn't the focus being set back to the target element?
Have you tried using e.currentTarget and a timeout like this?
e.preventDefault();
const target = e.currentTarget;
setTimeout(
function () {
target.focus();
},
5
);
Why isn't the focus being set back to the target element?
Use setTimeout so the blur completes before you focus again 🌹
Related
<input type="checkbox" onclick="onClickHandler()" onchange="onChangeHandler()" />
From within onClickHandler and/or onChangeHandler, how can I determine what is the new state of the checkbox?
The short answer:
Use the click event, which won't fire until after the value has been updated, and fires when you want it to:
<label><input type='checkbox' onclick='handleClick(this);'>Checkbox</label>
function handleClick(cb) {
display("Clicked, new value = " + cb.checked);
}
Live example | Source
The longer answer:
The change event handler isn't called until the checked state has been updated (live example | source), but because (as Tim Büthe points out in the comments) IE doesn't fire the change event until the checkbox loses focus, you don't get the notification proactively. Worse, with IE if you click a label for the checkbox (rather than the checkbox itself) to update it, you can get the impression that you're getting the old value (try it with IE here by clicking the label: live example | source). This is because if the checkbox has focus, clicking the label takes the focus away from it, firing the change event with the old value, and then the click happens setting the new value and setting focus back on the checkbox. Very confusing.
But you can avoid all of that unpleasantness if you use click instead.
I've used DOM0 handlers (onxyz attributes) because that's what you asked about, but for the record, I would generally recommend hooking up handlers in code (DOM2's addEventListener, or attachEvent in older versions of IE) rather than using onxyz attributes. That lets you attach multiple handlers to the same element and lets you avoid making all of your handlers global functions.
An earlier version of this answer used this code for handleClick:
function handleClick(cb) {
setTimeout(function() {
display("Clicked, new value = " + cb.checked);
}, 0);
}
The goal seemed to be to allow the click to complete before looking at the value. As far as I'm aware, there's no reason to do that, and I have no idea why I did. The value is changed before the click handler is called. In fact, the spec is quite clear about that. The version without setTimeout works perfectly well in every browser I've tried (even IE6). I can only assume I was thinking about some other platform where the change isn't done until after the event. In any case, no reason to do that with HTML checkboxes.
For React.js, you can do this with more readable code. Hope it helps.
handleCheckboxChange(e) {
console.log('value of checkbox : ', e.target.checked);
}
render() {
return <input type="checkbox" onChange={this.handleCheckboxChange.bind(this)} />
}
Use this
<input type="checkbox" onclick="onClickHandler()" id="box" />
<script>
function onClickHandler(){
var chk=document.getElementById("box").value;
//use this value
}
</script>
use onclick event on all checkboxes that you want to get their values whether they are checked or not.
<input type="checkbox" value="rightSideCheckbox" onclick='handleClick(this);'>
function handleClick(checkbox) {
if(checkbox.checked){
console.log(checkbox.value+"True")
}
else{
console.log(checkbox.value+"False")
}
}
const [checkboxval, setCheckboxVal] = React.useState(null);
const handleChangeCheckbox = (e) => {
setCheckboxVal(e.target.checked);
}
render() {
return <input type="checkbox" onChange={(e) => handleChangeCheckbox(e)}
}
I'm trying to build a custom input that you can change its value by scrolling with IntersectionObserver and ScrollIntoView
The problem that I'm facing is that when I try to make the component controlled with a state it starts to flicker when scrolling.
I have the example here in this sandbox, and you can see the input gets initialized correctly with the correct value, but when you try to change it.. there is a flickering at the beginning of the scroll event. also resetting the input by the button does seem to work correctly.
I'm not really able to figure out how to get the updates correctly done in each event since I'm very new to Intersection observer
Try setting the threshold value to 1 such that it will fire only when it goes out of boundary completely.
const observer = new IntersectionObserver(
(entries) => {
const selectedEntry = entries.find(
(e) => Number.parseFloat(e.target.textContent) === value
);
selectedEntry?.target?.scrollIntoView();
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
!isFirstRender &&
onChange(Number.parseFloat(entry.target.textContent));
});
},
{ threshold: 1 } // changed to 1
);
Also please do as the linter says, and add proper dependencies for the useEffect hook unless when not needed.
If you are using React, you might consider react-intersection-observer.
In my case, I was able to remove flickering by setting option triggerOnce: true.
I have a React component that has an input element with an attached ref. I am aware of the common: inputRef.current.focus(); usage of a ref to focus a text input. But, I am struggling to find a good solution to dispatch a certain keyboard event from inputRef.current. I have tried:
let downEv = new KeyboardEvent('keydown', {'keyCode': 40, 'which': 40});
inputRef.current.dispatchEvent(downEv);
But, that doesn't seem to do anything.
KeyboardEvent is a native browser event (which is different than React's Synthetic event) hence you need to add a native listener as well like below in order to listen to them. example on csb
useEffect(()=>{
ref.current.addEventListener('keydown',handleKeyDown)
},[ref])
It's possible to do this, and not need to use ref.
You can try isolating what you want to trigger by doing this:
handleKeyPress = (e) => {
if (e.keyCode === 40) {
// Whatever you want to trigger
console.log(e.target.value)
}
}
<input onKeyPress={handleKeyPress} />
You can also trigger this from a form if you prefer:
<form onKeyPress={handleKeyPress}>
...
</form>
I have a paper-input item
<paper-input label="Test" data-ng-model="item" data-ng-blur="onBlur(x)" data-ng-change="onChange(y)"> </paper-input>
In the controller, the functions are defined as -
function onBlur(x)
{
...
}
function onChange(y)
{
...
}
On losing focus on the item, onBlur is called correctly. However, on changing data in the item, the onChange function is not called. Any ideas?
It seems that the behaviour of data-ng-change is to fire events only when you focus out of the element. To fire an event when changing data in the element, I used data-ng-keyup
Having an Input from semantic-ui-react changed when the User writes something, does fire onChange and any parent component that includes the Input fires onChange as well. A process called bubble .... right?
Example
<li onChange={this.onListChange}>
<Input onChange={this.onInputChange}/>
</li>
Any change made in the Input, fires onInputChange() and onListChange() together one after another.
Although, when Input.value/text/content is changed dynamically, Input.onChange() is not called at all. So you have to call the onChange() function manually.
setFoo() {
this.input.value = 'foo';
this.inputChange();
}
But the problem here is, that when we call inputChange we don't get as e.target the component Input, nor data has anything to do with it, and the most important ... :
No Bubbling effect.
Which means that onListChange() will not be fired.
Question:
How can I achieve a proper bugless bubbled onChange() on Semantic-UI-React?
Not exactly sure about semantic-ui-react because I've never used it, but this in theory should work (it works for a normal input):
setFoo() {
this.input.value = 'foo';
const event = new Event('input', { bubbles: true });
this.input.dispatchEvent(event);
}