why does the same event recognise different activeElements? - javascript

If I click a button the activeElement is the button.
If I leave an input box the activeElement is the Window.
If I leave an input box by clicking on a button the activeElement is ... both?
Why does the onfocusout event not register the same activeElement as the button?
Is there anyway I can access the click-on-button event from the function call of the inputbox-leave-event? ie can I ask, "Did you leave me for the lousy button?"
<button type="button" onclick = "myFunction()"> button </button><br>
<input type="text" onfocusout= "myFunction()"> </input>
<script>
function myFunction() {
console.log(document.activeElement);
}
</script>

You can add an event listener for the button inside the myFunction()
function myFunction() {
// console.log(document.activeElement);
var btn = document.getElementById("btn");
btn.addEventListener("click", function (event) {
console.log(event);
});
}
<!DOCTYPE html>
<html>
<body>
<button id="btn" type="button">button</button><br>
<input type="text" onfocusout="myFunction()" />
</body>
</html>

The activeElement read-only property of the Document interface returns the Element within the DOM that currently has focus.
Often activeElement will return a HTMLInputElement or HTMLTextAreaElement object if it has the text selection at the time. If so, you can get more detail by using the object's selectionStart and selectionEnd properties.
In addition, it is indeed possible to trigger a button click when leaving the input element, you just need to make sure to handle the onfocusout function, and use the code inside the function to trigger the click event, you can refer to here.
function onMouseUp(e) {
const activeTextarea = document.activeElement;
const selection = activeTextarea.value.substring(
activeTextarea.selectionStart, activeTextarea.selectionEnd
);
const outputElement = document.getElementById('output-element');
const outputText = document.getElementById('output-text');
console.log({ id: activeTextarea.id, selection});
}
const textarea1 = document.getElementById('textarea1');
const textarea2 = document.getElementById('textarea2');
textarea1.addEventListener('mouseup', onMouseUp, false);
textarea2.addEventListener('mouseup', onMouseUp, false);
<textarea name="textarea1" id="textarea1" rows="7" cols="40">This is Text Area One.</textarea>
<textarea name="textarea2" id="textarea2" rows="7" cols="40">This is Text Area Two</textarea>

The relatedTarget in the event will show you where it's leaving to
of course, you have to use addEventListener to access the event in the first place
But I think this demonstrates what you want to see
it'll definitely tell you
"Did you leave me for the lousy button?"
const button = document.querySelector('button')
const input = document.querySelector('input')
function buttonHandler(e) {
console.log('button clicked');
}
function inputHandler(e) {
console.log('leaving input for', e.relatedTarget?.tagName || 'window');
}
input.addEventListener('focusout', inputHandler);
button.addEventListener('click', buttonHandler);
<button type="button"> button </button><br>
<input type="text"> </input>

Related

How to change button text when clicked?

I am running my website off of squarespace and I have a button that says "DELIVER ME" but when you click it, I want it to say "G.T.F.O" while the next page loads.
I don't have a code for this and need help writing one.
function changeButtonText(DELIVER ME, G.T.F.O.){
if (this.value== "DELIVER ME"){
this.value = "G.T.F.O.";
} else {
this.value = "DELIVER ME";
}
}
changeButtonText();
I want the button to say "DELIVER ME" until you click it, then once you click it the button will say "G.T.F.O."
I want the button to say "DELIVER ME" until you click it, then once you click it the button will say "G.T.F.O."
Given this button:
<input type="button" id="myButton" value="DELIVER ME">
You could do it like this:
const myButton = document.getElementById("myButton");
myButton.addEventListener("click", function() {
this.value = "G.T.F.O."
});
Or, if the button is like this:
<button id="myButton">DELIVER ME</button>
You would do:
const myButton = document.getElementById("myButton");
myButton.addEventListener("click", function() {
this.innerText = "G.T.F.O."
});
function changeText() {
return document.querySelector("#button").innerHTML = "New text";
}
document.addEventListener("click", changeText);
<button type="button" id="button">Text</button>
most of the answer can solve your particular problem but I just want to add more information about selecting htmlElement.
in VanillaJS(pure Javascript) DOM. you can select element with 3 DOM method.
Select by ID's attribute
elem = document.getElementById("id")
Select by class attribute
elem = document.getElementsByClassName("class")
Select by TagName
elem = document.getElementByTagName("Tag")
and 1 more extra way which used.
elem = document.querySelector(selector)
selector can be one of ".class","#id", or "Tags"
Thanks
<button type="button" id="btn" onclick=changeButtonText()>deliver me</button>
<script>
function changeButtonText(){
document.getElementById("btn").innerHTML = "GTFO";
}
</script>

How to call a JS function when a textbox text property changes? [duplicate]

Is there any way I can create a constant function that listens to an input, so when that input value changes, something is triggered immediately?
I am looking for something using pure javascript, no plugins, no frameworks and I can't edit the HTML.
Something, for example:
When I change the value in the input MyObject, this function runs.
Any help?
This is what events are for.
HTMLInputElementObject.addEventListener('input', function (evt) {
something(this.value);
});
As a basic example...
HTML:
<input type="text" name="Thing" value="" />
Script:
/* event listener */
document.getElementsByName("Thing")[0].addEventListener('change', doThing);
/* function */
function doThing(){
alert('Horray! Someone wrote "' + this.value + '"!');
}
Here's a fiddle: http://jsfiddle.net/Niffler/514gg4tk/
Actually, the ticked answer is exactly right, but the answer can be in ES6 shape:
HTMLInputElementObject.oninput = () => {
console.log('run'); // Do something
}
Or can be written like below:
HTMLInputElementObject.addEventListener('input', (evt) => {
console.log('run'); // Do something
});
Default usage
el.addEventListener('input', function () {
fn();
});
But, if you want to fire event when you change inputs value manualy via JS you should use custom event(any name, like 'myEvent' \ 'ev' etc.) IF you need to listen forms 'change' or 'input' event and you change inputs value via JS - you can name your custom event 'change' \ 'input' and it will work too.
var event = new Event('input');
el.addEventListener('input', function () {
fn();
});
form.addEventListener('input', function () {
anotherFn();
});
el.value = 'something';
el.dispatchEvent(event);
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
Another approach in 2021 could be using document.querySelector():
const myInput = document.querySelector('input[name="exampleInput"]');
myInput.addEventListener("change", (e) => {
// here we do something
});
This sounds exactly like the problem I had.
And I would have stated the same question, but I guess it's the same wrong question...
IMHO it's just 'onchange' mistaken as 'oninput' which are 2 different things.
Give me a lot of minus for this statement, I dont care, but I guess it may help one or the other ...
HTML form input contain many events. Refer from MDN document, on the sidebar go to Events menu and expand it. You will see many useful events such as beforeinput, change, copy, cut, input, paste, and drag drop events.
iput & change.
The beforeinput, and input events are fired by order when you type the form input value.
When the form input value has changed and you lost focus on that input, the change event is fired.
Cut, copy, paste.
When you cut (CTRL+X on keyboard shortcut) the input value, the cut, beforeinput, input events are fired.
When you copy (CTRL+C on keyboard shortcut), the copy event is fired alone.
When you paste the value from clipboard (CTRL+V on keyboard shortcut), the paste, beforeinput, input events are fired.
JS change value.
To change input value by JavaScript and make important events work, you need to dispatch at least 2 events by order. One is input and two is change. So that you can focus your code to listened to input or change event. It's easier this way.
Here is all sample code.
(() => {
let inputText = document.getElementById('text');
let submitBtn = document.getElementById('submit');
let triggerJSBtn = document.getElementById('button');
submitBtn.addEventListener('click', (event) => {
event.preventDefault(); // just prevent form submitted.
});
triggerJSBtn.addEventListener('click', (event) => {
const thisTarget = event.target;
event.preventDefault();
inputText.value = thisTarget.innerText;
inputText.dispatchEvent(new Event('input'));
inputText.dispatchEvent(new Event('change'));
});
inputText.addEventListener('beforeinput', (event) => {
const thisTarget = event.target;
console.log('beforeinput event. (%s)', thisTarget.value);
});
inputText.addEventListener('input', (event) => {
const thisTarget = event.target;
console.log('input event. (%s)', thisTarget.value);
});
inputText.addEventListener('change', (event) => {
const thisTarget = event.target;
console.log('change event. (%s)', thisTarget.value);
});
inputText.addEventListener('cut', (event) => {
const thisTarget = event.target;
console.log('cut event. (%s)', thisTarget.value);
});
inputText.addEventListener('copy', (event) => {
const thisTarget = event.target;
console.log('copy event. (%s)', thisTarget.value);
});
inputText.addEventListener('paste', (event) => {
const thisTarget = event.target;
console.log('paste event. (%s)', thisTarget.value);
});
})();
/* for beautification only */
code {
color: rgb(200, 140, 50);
}
small {
color: rgb(150, 150, 150);
}
<form id="form">
<p>
Text: <input id="text" type="text" name="text">
</p>
<p>
Text 2: <input id="text2" type="text" name="text2"><br>
<small>(For lost focus after modified first input text so the <code>change</code> event will be triggered.)</small>
</p>
<p>
<button id="submit" type="submit">
Submit
</button>
<button id="button" type="button">
Trigger JS to set input value.
</button>
</p>
<p>Press F12 to view results in your browser console.</p>
</form>
Please press F12 to open browser's console and see result there.
Each time a user inputs some value, do something.
var element = document.getElementById('input');
element.addEventListener('input', function() {
// Do something
});
Keydown, keyup, input are events that fire immediately when input changes,
I would use keydown or input events to get the changed value from the input box.
const myObject = document.getElementById('Your_element_id');
myObject.addEventListener('keydown', function (evt) {
// your code goes here
console.log(myObject.value);
});
If you would like to monitor the changes each time there is a keystroke on the keyboard.
const textarea = document.querySelector(`#string`)
textarea.addEventListener("keydown", (e) =>{
console.log('test')
})
instead of id use title to identify your element and write the code as below.
$(document).ready(()=>{
$("input[title='MyObject']").change(()=>{
console.log("Field has been changed...")
})
});

Prevent function execution twice within two triggered events

I have the following code:
myInput.change(function (e) { // this triggers first
triggerProcess();
});
myButton.click(function (e) { // this triggers second
triggerProcess();
});
The problem with the above is when I click myButton both events are triggered and triggerProcess() is fired twice which is not desired.
I only need triggerProcess() to fire once. How can I do that?
Small demo
You can have a static flag that disables any more triggers once the first trigger has occurred. Might look something like this:
var hasTriggered = false;
myInput.change(function (e) { // this triggers first
triggerProcess();
});
myButton.click(function (e) { // this triggers second
triggerProcess();
});
function triggerProcess () {
// If this process has already been triggered,
// don't execute the function
if (hasTriggered) return;
// Set the flag to signal that we've already triggered
hasTriggered = true;
// ...
}
For resetting the hasTriggered flag, that's entirely up to you and how this program works. Maybe after a certain event occurring in the program you'd want to reenable the ability to trigger this event again — all you'd need to do it set the hasTriggered flag back to true.
You can use the mousedown event, which will fire before the input is blurred, and then check if the input has focus by checking if it's the activeElement, and if it does have focus, don't fire the mousedown event, as the change event will fire instead.
Additionally, if you want a mousedown event to occur when the value hasn't changed, and the change event doesn't fire, you'll need a check for that as well
var myInput = $('#test1'),
myButton = $('#test2'),
i = 0;
myInput.change(function(e) { // this triggers first
$(this).data('prev', this.value);
triggerProcess();
});
myButton.mousedown(function(e) { // this triggers second
var inp = myInput.get(0);
if (document.activeElement !== inp || inp.value === myInput.data('prev'))
triggerProcess();
});
function triggerProcess() {
console.log('triggered : ' + (++i))
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="test1">
<br />
<br />
<button id="test2">
Click
</button>
In a fairly typical scenario where you have an input with a button next to ie, eg quick search.
You want to fire when the input changes (ie onblur) but also if the user clicks the button.
In the case where the user changes the input then clicks the button without changing input focus (ie no blur), the change event fires because the text has changed and the click event fires because the button has been clicked.
One option is to debounce the desired event handler.
You can use a plugin or a simple setTimeout/clearTimeout, eg:
$('#inp').change(debounceProcess)
$('#btn').click(debounceProcess);
function debounceProcess() {
if (debounceProcess.timeout != null)
clearTimeout(debounceProcess.timeout);
debounceProcess.timeout = setTimeout(triggerProcess, 100)
}
function triggerProcess() {
console.log('process')
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="inp">
<button id="btn">Click</button>
Use a real <button>BUTTON</button>. If you click on input text, alert is triggered, then once you leave the input text to click anywhere else, that unfocuses the input text which triggers the change event, so now 2 events have been triggered from the text input.
This is an assumption since the code provided is far from sufficient to give a complete and accurate answer. The HTML is needed as well as more jQuery/JavaScript. What is myInput and myButton actually referring to, etc.?
So I bet if you change...
var myButton = $('{whatever this is}'); and <input type='button'>
...TO:
var myButton = $("button"); and <button></button>
...you should no longer have an event trigger twice for an element.
This is assuming that triggerProcess() is a function that does something that doesn't manipulate the event chain or anything else involving events. This is an entirely different ballgame if instead of click() and change() methods you are using .trigger() or triggerHandler(), but it isn't. I'm not certain why such complex answers are derived from a question with very little info...?
BTW, if myInput is a search box and myButton is the button for myInput, as freedomn-m has mentioned, simply remove:
myButton.click(...
Leave myButton as a dummy. The change event is sufficient in that circumstance.
SNIPPET
var xInput = $('input');
var xButton = $('button'); //«———Add
xInput.on('change', alarm);
xInput.on('click', alarm);
xButton.on('click', alarm);
function alarm() {
return alert('Activated')
}
/* For demo it's not required */
[type='text'] {
width: 5ex;
}
b {
font-size: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id='f1' name='f1'>
<input type='text'>
<input type='button' value='BUTTON TYPE'>
<label><b>⇦</b>Remove this button</label>
<button>BUTTON TAG</button>
<label><b>⇦</b>Replace it with this button</label>
</form>

Disabled textbox change event

Short Explanation
I want to do something whenever disabled textbox value is changed
Detailed Explanation
I have a disabled text box which value is setting programitically I want to bind the change event of disabled textbox to fire some other function. This is what I tried but won't work.
$('#Rate').change(function() {
// alert("Change Event Called");
CalculateMedicine();
});
$('input[id$=Rate]').bind("change", function () {
CalculateMedicine();
});
This both thing don't work for me and the I don't like the idea to put a function CalculateMedicine() to all the place from which possibly Rate textbox is changing.So apart from this solution any help will be appreciated
assuming that your your input has disable class on on click or something else you check like this
if ($( "#input" ).hasClass( "disable" )) {
Your logics and codes here //
}
//Hope this would help
You can use triggerfor a change event:
<input type="text" disabled="disabled" name="fname" class="myTextBox" ><br>
<input type="button" name="submit" id="submit" value="Submit">
Javascript:
$(".myTextBox").change(function(){
console.log("yes i m working");
});
$("#submit").click("input", function() {
$(".myTextBox").val("New value").trigger("change");
});
Check Demo
It is possible if one redefines the value property of that input.
<html>
<head>
<script>
function Init(){
var tE = document.querySelector('input'); //Our input field.
//We redefine the value property for the input
tE._value = tE.value;
Object.defineProperty(tE, 'value', {
get: function(){return this._value},
set: function(v){
console.log(1, 'The value changed to ' + v)
this._value = v;
this.setAttribute('value', v) //We set the attribute for display and dom reasons
//Here we can trigger our code
}
})
}
function Test(){
//In one second we are going to change the value of the input
window.setTimeout(function(){
var tE = document.querySelector('input'); //Our input field.
tE.value = 'Changed!'
console.log(0, 'Changed the value for input to ' + tE.value)
}, 1000)
}
</script>
</head>
<body onload = 'Init(); Test();'>
<input type = 'text' disabled = 'true' value = 'Initial' />
</body>
</html>
https://jsfiddle.net/v9enoL0r/
The change event will not fire if you change the value programmatically
See https://stackoverflow.com/a/7878081/3052648
A not elegant possible solution:
function checkChanges(){
if(prevRate != $('#Rate').val()){
prevRate = $('#Rate').val();
alert('changed');
}
}
var prevRate;
$(document).ready(function(){
prevRate = $('#Rate').val();
setInterval(function(){
checkChanges();
} ,500);
});
You can fire change event by the following code from wherever you want to fire change event or any other event. The event will be fired either value changed or not. Just place the code after from where you are changing value programatically.
element.dispatchEvent(new Event('change'))
let input = document.querySelector("input");
input.addEventListener("change", () => alert("Change Event is Fired"));
input.value = "xyz";
input.dispatchEvent(new Event("change"));
<input type="text" disabled value="abc">

Activate onchange after changing content with javascript

Why wouldn't onChange function of an input be activated when the value of the input is changed by javascript? For example why when clicking on the button alert wouldn't happen?
<html>
<body>
<input type="text" id="myInput" onchange="alert(1)" />
<button onclick = "document.getElementById('myInput').value = 'ads'">click</button>
</body>
</html>
How can I make the onchange function work then?
edit:
I now understand event won't be triggered automatically, how can I call it(jquery too) ?
Scripted value changes don't trigger an event. You have to manually trigger an event.
jQuery: $('#myInput').trigger('change');
Add the following code to the onchange event:
var input = document.getElementById("myInput");
if(input.fireEvent) input.fireEvent("onchange");
else {
var ev = document.createEvent('HTMLEvents');
ev.initEvent("change", true, false);
input.dispatchEvent(ev);
}
So, combined with your code (you should actually separate the JS code from the HTML):
<button onclick="var input = document.getElementById('myInput');input.value = 'ads';if(input.fireEvent)input.fireEvent('onchange');else{var ev=document.createEvent('HTMLEvents');ev.initEvent('change',true,false);input.dispatchEvent(ev);}">click</button>

Categories