Trigger onKeyUp from script after input value is changed - javascript

I have a few input fields that use onKeyUp="script" to return data the moment something is entered.
As a shortcut, I would like to be able to add a value to one of the fields when data is entered from another location AND trigger the script.
I can use document.getElementById("myID").value = MyValue; to add a specific value to the input box, or .addEventListener(); to watch another input field.
This part works well.
However, I have not been able to trigger anything equivalent to onKeyUp, which will happen either when:
1. You press/release a key while the input field is in focus.
2. You focus the input and release a key AFTER the script has added a value.
3. You enter the input field via [TAB] AFTER the script has added a value.
Adding .keyup(); or .keypress(); have had no effect.
I've been able to use .focus(); to focus and then change the input, but this does not have the same effect as pressing [TAB]
What can I do to trigger the onKeyUp for this field, even if the data was not manually typed?
ADDITIONAL INFO
This part works...
<input type="text" id="box1" onKeyUp="script1();">
<div id="result1" "> (script places result here) </div>
Add value from another location - Option 1
<input type="text" id="Test1">
<button type="button" onclick="TestScript()"> TEST</button>
<script type='text/javascript'>
function TestScript() {
var test1=document.getElementById("Test1").value;
document.getElementById("box1").value = test1;
document.getElementById("box1").keyup();
return false;
}
</script>
Add value from another location - Option 2
<script type='text/javascript'>
window.onload = function () {
document.getElementsByName("box2")[0].addEventListener('change', TestScript2);
function TestScript2(){
var test2=document.getElementById("box2").value;
document.getElementById("box1").value = test2;
}}
</script>
Both of these options will copy the value to the correct location, but I have not been able to get either to trigger the onKeyUp so that the original script realizes something has changed.
Non working Fiddle example: https://jsfiddle.net/mj8g4xa2/4/

Trigger keyup programatically in;
JAVASCRIPT:
Call onkeyup() on the element.
Create a new keyup event and dispatch it using the element. Note: The source here doesn't support IE. Refer this answer for cross-browser support. Also createEvent is deprecated (MDN Docs for reference).
JQUERY:
$("#elem").keyup();
$("#elem").trigger('keyup');
Change events fire only when the input blurs, according to the MDN Docs.
Also, you should have got Uncaught TypeError: element.keyup is not a function error in your console.
var elem = document.getElementById("data");
function triggerKeyUpEvent()
{
var e = document.createEvent('HTMLEvents');
e.initEvent("keyup",false,true);
elem.dispatchEvent(e);
}
function perform()
{
console.log("KeyUp");
}
function add()
{
elem.value = String.fromCharCode(Math.random().toFixed(2)*100).repeat(5);
elem.onkeyup();
triggerKeyUpEvent();
}
<input id="data" onkeyup="perform()">
<button id="add" onclick="add()">Add Random Data</button>

To fix your JSFiddle update the following code:
var elem = document.getElementById("sim1");
function triggerKeyUpEvent() {
var e = document.createEvent('HTMLEvents');
e.initEvent("keyup",false,true);
elem.dispatchEvent(e);
}
function add() {
var sim1=document.getElementById("sim1").value;
document.getElementById("box1").value = sim1;
elem.onkeyup();
triggerKeyUpEvent()
}
by replacing the line elem.dispatchEvent(e) with box1.dispatchEvent(e)
And the line elem.onkeyup() with box1.onkeyup()
Lastly, it would seem that you don't need to call triggerKeyUpEvent as when I removed it, it still works.
Here's the udpated JSFiddle

Related

HTML Input - Undo history lost when setting input value programmatically

I have an HTML input. When a user types in it, I've set up the 'input' event to handle updating the input to a filtered version of what the user typed (as well as updating selectionStart and selectionEnd for smooth UX). This happens constantly in order to give the proper effect.
What I've noticed, however, is that whenever JS sets the value of an input via input.value = '...';, it appears the undo history for the input disappears. That is, pressing Ctrl-Z with it focused no longer steps back to the previous state.
Is there any way to either provide the input custom undo history, or otherwise prevent it from losing the history whilst still changing its value?
Here is a minimal example of my issue:
After typing in the top input (which rudimentarily adds periods between every character), Ctrl-Z does not undo.
<body>
<input type="text" id="textbox" placeholder="No undo"/><br/>
<input type="text" id="textbox2" placeholder="Undo"/>
<script>
var tbx = document.getElementById("textbox");
tbx.addEventListener('input', () => {
tbx.value = tbx.value + '.'
});
</script>
</body>
You can try storing the input's previous value in a variable, then listen for the Ctrl + Z key combination in a keydown event listener attached to the input. When it is fired, you can set the value of the input to the previous stored value.
btn.addEventListener('click', function() {
savePrevInput(input.value)
input.value = "Hello World!";
})
var prevInput;
function savePrevInput(input) {
prevInput = input;
}
input.addEventListener("keydown", function(e) {
if (e.ctrlKey && e.keyCode == 90) {
if (prevInput) {
input.value = prevInput;
input.selectionStart = prevInput.length;
}
}
})
<input id="input" />
<button id="btn">Change</button>

i want value from input field which is using template drive form of angular and giving me previously typed value [duplicate]

I am trying to get the text in a text box as the user types in it (jsfiddle playground):
function edValueKeyPress() {
var edValue = document.getElementById("edValue");
var s = edValue.value;
var lblValue = document.getElementById("lblValue");
lblValue.innerText = "The text box contains: " + s;
//var s = $("#edValue").val();
//$("#lblValue").text(s);
}
<input id="edValue" type="text" onKeyPress="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>
​
The code runs without errors, except that the value of the input text box, during onKeyPress is always the value before the change:
Question: How do I get the text of a text box during onKeyPress?
Bonus Chatter
There are three events related to "the user is typing" in the HTML DOM:
onKeyDown
onKeyPress
onKeyUp
In Windows, the order of WM_Key messages becomes important when the user holds down a key, and the key begins to repeat:
WM_KEYDOWN('a') - user has pushed down the A key
WM_CHAR('a') - an a character has been received from the user
WM_CHAR('a') - an a character has been received from the user
WM_CHAR('a') - an a character has been received from the user
WM_CHAR('a') - an a character has been received from the user
WM_CHAR('a') - an a character has been received from the user
WM_KEYUP('a') - the user has released the A key
Will result in five characters appearing in a text control: aaaaa
The important point being that the you respond to the WM_CHAR message, the one that repeats. Otherwise you miss events when a key is pressed.
In HTML things are slightly different:
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyDown
onKeyPress
onKeyUp
Html delivers an KeyDown and KeyPress every key repeat. And the KeyUp event is only raised when the user releases the key.
Take aways
I can respond to onKeyDown or onKeyPress, but both are still raised before the input.value has been updated
I cannot respond to onKeyUp, because it doesn't happen as the text in the text-box changes.
Question: How do I get the text of a text-box during onKeyPress?
Bonus Reading
Getting a form value with jQuery
Get the value in an input text box
Keep it simple. Use both onKeyPress() and onKeyUp():
<input id="edValue" type="text" onKeyPress="edValueKeyPress()" onKeyUp="edValueKeyPress()">
This takes care of getting the most updated string value (after key up) and also updates if the user holds down a key.
jsfiddle: http://jsfiddle.net/VDd6C/8/
Handling the input event is a consistent solution: it is supported for textarea and input elements in all contemporary browsers and it fires exactly when you need it:
function edValueKeyPress() {
var edValue = document.getElementById("edValue");
var s = edValue.value;
var lblValue = document.getElementById("lblValue");
lblValue.innerText = "The text box contains: " + s;
}
<input id="edValue" type="text" onInput="edValueKeyPress()"><br>
<span id="lblValue">The text box contains: </span>
I'd rewrite this a bit, though:
function showCurrentValue(event)
{
const value = event.target.value;
document.getElementById("label").innerText = value;
}
<input type="text" onInput="showCurrentValue(event)"><br>
The text box contains: <span id="label"></span>
the value of the input text box, during onKeyPress is always the value before the change
This is on purpose: This allows the event listener to cancel the keypress.
If the event listeners cancels the event, the value is not updated. If the event is not canceled, the value is updated, but after the event listener was called.
To get the value after the field value has been updated, schedule a function to run on the next event loop. The usual way to do this is to call setTimeout with a timeout of 0:
$('#field').keyup(function() {
var $field = $(this);
// this is the value before the keypress
var beforeVal = $field.val();
setTimeout(function() {
// this is the value after the keypress
var afterVal = $field.val();
}, 0);
});
Try here: http://jsfiddle.net/Q57gY/2/
Edit: Some browsers (e.g. Chrome) do not trigger keypress events for backspace; changed keypress to keyup in code.
keep it Compact.
Each time you press a key, the function edValueKeyPress() is called.
You've also declared and initialized some variables in that function - which slow down the process and requires more CPU and memory as well.
You can simply use this code - derived from simple substitution.
function edValueKeyPress()
{
document.getElementById("lblValue").innerText =""+document.getElementById("edValue").value;
}
That's all you want, and it's faster!
<asp:TextBox ID="txtMobile" runat="server" CssClass="form-control" style="width:92%; margin:0px 5px 0px 5px;" onkeypress="javascript:return isNumberKey(event);" MaxLength="12"></asp:TextBox>
<script>
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false;
}
return true;
}
</script>
None of the answers so far offer a complete solution. There are quite a few issues to address:
Not all keypresses are passed onto keydown and keypress handlers (e.g. backspace and delete keys are suppressed by some browsers).
Handling keydown is not a good idea. There are situations where a keydown does NOT result in a keypress!
setTimeout() style solutions get delayed under Google Chrome/Blink web browsers until the user stops typing.
Mouse and touch events may be used to perform actions such as cut, copy, and paste. Those events will not trigger keyboard events.
The browser, depending on the input method, may not deliver notification that the element has changed until the user navigates away from the field.
A more correct solution will handle the keypress, keyup, input, and change events.
Example:
<p><input id="editvalue" type="text"></p>
<p>The text box contains: <span id="labelvalue"></span></p>
<script>
function UpdateDisplay()
{
var inputelem = document.getElementById("editvalue");
var s = inputelem.value;
var labelelem = document.getElementById("labelvalue");
labelelem.innerText = s;
}
// Initial update.
UpdateDisplay();
// Register event handlers.
var inputelem = document.getElementById("editvalue");
inputelem.addEventListener('keypress', UpdateDisplay);
inputelem.addEventListener('keyup', UpdateDisplay);
inputelem.addEventListener('input', UpdateDisplay);
inputelem.addEventListener('change', UpdateDisplay);
</script>
Fiddle:
http://jsfiddle.net/VDd6C/2175/
Handling all four events catches all of the edge cases. When working with input from a user, all types of input methods should be considered and cross-browser and cross-device functionality should be verified. The above code has been tested in Firefox, Edge, and Chrome on desktop as well as the mobile devices I own.
I normally concatenate the field's value (i.e. before it's updated) with the key associated with the key event. The following uses recent JS so would need adjusting for support in older IE's.
Recent JS example
document.querySelector('#test').addEventListener('keypress', function(evt) {
var real_val = this.value + String.fromCharCode(evt.which);
if (evt.which == 8) real_val = real_val.substr(0, real_val.length - 2);
alert(real_val);
}, false);
Support for older IEs example
//get field
var field = document.getElementById('test');
//bind, somehow
if (window.addEventListener)
field.addEventListener('keypress', keypress_cb, false);
else
field.attachEvent('onkeypress', keypress_cb);
//callback
function keypress_cb(evt) {
evt = evt || window.event;
var code = evt.which || evt.keyCode,
real_val = this.value + String.fromCharCode(code);
if (code == 8) real_val = real_val.substr(0, real_val.length - 2);
}
[EDIT - this approach, by default, disables key presses for things like back space, CTRL+A. The code above accommodates for the former, but would need further tinkering to allow for the latter, and a few other eventualities. See Ian Boyd's comment below.]
easy...
In your keyPress event handler, write
void ValidateKeyPressHandler(object sender, KeyPressEventArgs e)
{
var tb = sender as TextBox;
var startPos = tb.SelectionStart;
var selLen= tb.SelectionLength;
var afterEditValue = tb.Text.Remove(startPos, selLen)
.Insert(startPos, e.KeyChar.ToString());
// ... more here
}
So there are advantages and disadvantages to each event. The events onkeypress and onkeydown don't retrieve the latest value, and onkeypress doesn't fire for non-printable characters in some browsers. The onkeyup event doesn't detect when a key is held down for multiple characters.
This is a little hacky, but doing something like
function edValueKeyDown(input) {
var s = input.value;
var lblValue = document.getElementById("lblValue");
lblValue.innerText = "The text box contains: "+s;
//var s = $("#edValue").val();
//$("#lblValue").text(s);
}
<input id="edValue" type="text" onkeydown="setTimeout(edValueKeyDown, 0, this)" />
seems to handle the best of all worlds.
By using event.key we can get values prior entry into HTML Input Text Box. Here is the code.
function checkText()
{
console.log("Value Entered which was prevented was - " + event.key);
//Following will prevent displaying value on textbox
//You need to use your validation functions here and return value true or false.
return false;
}
<input type="text" placeholder="Enter Value" onkeypress="return checkText()" />
Try to concatenate the event charCode to the value you get.
Here is a sample of my code:
<input type="text" name="price" onkeypress="return (cnum(event,this))" maxlength="10">
<p id="demo"></p>
js:
function cnum(event, str) {
var a = event.charCode;
var ab = str.value + String.fromCharCode(a);
document.getElementById('demo').innerHTML = ab;
}
The value in ab will get the latest value in the input field.
There is a better way to do this. Use the concat Method. Example
declare a global variable. this works good on angular 10, just pass it to Vanilla JavaScript. Example:
HTML
<input id="edValue" type="text" onKeyPress="edValueKeyPress($event)"><br>
<span id="lblValue">The text box contains: </span>
CODE
emptyString = ''
edValueKeyPress ($event){
this.emptyString = this.emptyString.concat($event.key);
console.log(this.emptyString);
}

Use XPath or onClick or onblur to select an element and use jQuery to blur this element

*UPDATE:I am new to jQuery, as well as using XPath, and I am struggling with getting a proper working solution that will blur a dynamically created HTML element. I have an .onblur event hooked up (doesn't work as expected), and have tried using the $(document.activeElement), but my implementation might be incorrect. I would appreciate any help in creating a working solution, that will blur this element (jqInput) when a user clicks anywhere outside the active element. I have added the HTML and jQuery/JavaScript below.
Some ideas I have had:
(1) Use XPath to select a dynamic HTML element (jqInput), and then use jQuery's .onClick method to blur a this element, when a user clicks anywhere outside of the area of the XPath selected element.
(2) Use the $(document.activeElement) to determine where the .onblur should fire:
var thisTitle = input0;
var activeElement = $(document.activeElement);
if (thisTitle != activeElement) {
jqInput.hide();
_layout.viewHeaderTextInput.inputOnBlurHandler(canvasObj, jqHeaderText, jqInput);
}
I am open to all working solutions. And hopefully this will answer someone else's question in the future.
My challenge: Multiple elements are active, and the .onblur does not fire. See the image below:
NOTE: The <input /> field has focus, as well as the <div> to the left of the (the blue outline). If a user clicks anywhere outside that <input />, the blur must be applied to that element.
My Code: jQuery and JavaScript
This is a code snippet where the variable jqInput and input0 is created:
var jqInput = null;
if (jqHeaderText.next().hasClass("inline-editable"))
{
//Use existing input if it already exists
jqInput = jqHeaderText.next();
}
else
{
//Creaet a new editable header text input
jqInput = $("<input class=\"inline-editable\" type=\"text\"/>").insertAfter(jqHeaderText);
}
var input0 = jqInput.get(0);
//Assign key down event for the input when user preses enter to complete entering of the text
input0.onkeydown = function (e)
{
if (e.keyCode === 13)
{
jqInput.trigger("blur");
e.preventDefault();
e.stopPropagation();
}
};
This is my .onblur event, and my helper method to blur the element:
input0.onblur = function ()
{
_layout.viewHeaderTextInput.inputOnBlurHandler(canvasObj, jqHeaderText, jqInput);
};
inputOnBlurHandler: function (canvasObj, jqHeaderText, jqInput)
{
// Hide input textbox
jqInput.hide();
// Store the value in the canvas
canvasObj.headingText = jqInput.val();
_layout.updateCanvasControlProperty(canvasObj.instanceid, "Title", canvasObj.headingText, canvasObj.headingText);
// Show header element
jqHeaderText.show();
_layout.$propertiesContent.find(".propertyGridEditWrapper").filter(function ()
{
return $(this).data("propertyName") === "Title";
}).find("input[type=text]").val(canvasObj.headingText); // Update the property grid title input element
}
I have tried using the active element, but I don't think the implementation is correct:
var thisTitle = input0;
var activeElement = $(document.activeElement);
if (thisTitle != activeElement) {
jqInput.hide();
_layout.viewHeaderTextInput.inputOnBlurHandler(canvasObj, jqHeaderText, jqInput);
}
My HTML code:
<div class="panel-header-c">
<div class="panel-header-wrapper">
<div class="panel-header-text" style="display: none;">(Enter View Title)</div><input class="inline-editable" type="text" style="display: block;"><div class="panel-header-controls">
<span></span>
</div>
</div>
</div>
I thank you all in advance.

Enabling a disabled element

I tried to enable a disabled element on click of a P element.The code below will store the value from the textbox into another textbox which I have appended with the div.later this textbox will be disabled.On mouse over the div an edit and delete will appear.On click of the edit, the textbox within the div must be enabled again.
<div id="ta"></div>
<input type="text" id="tb"><br>
<button onclick="add()">Submit</button><br>
<script type="text/javascript">
var ta="";
function add() {
var newDiv="",newTa="",newP="",newImg="";
ta=document.getElementById('ta');
newDiv = document.createElement("div");
ta.appendChild(newDiv);
newTa = document.createElement("input");
newTa.type="text"
newTa.disabled="true";
newTa.value=document.getElementById("tb").value;
newDiv.onmousedown=function(){
newP.style.visibility="visible";
newImg.style.visibility="visible";
};
newP=document.createElement("p");
newP.innerHTML="Edit";
newP.style.visibility="hidden";
newP.style.display="inline";
newP.style.padding="5px";
newP.onclick=function()
{
newTa.disabled="false";//this is not working
}
Why is it not working?Is there any other way to do this?
The reason is probably because you are providing "false" as a string. From another answer here:
[...] a non empty string is truthy. So assigning "false" to the disabled property has the same effect of setting it to true.
Try using the proper boolean value instead.
newTa.disabled = false;
newTa.disabled="true"
newTa.disabled="false"
these two should be without ""
newTa.disabled=true
newTa.disabled=false
otherwise you could do it like this:
var x = document.getElementById("mySelect").disabled;
https://www.w3schools.com/jsref/prop_select_disabled.asp

Get a variable immediately after typing

I have this code
<span></span>
and this
<div> variable like a number </div>
and
<script>
$(document).ready(function(){
var x = $('div').html();
$('span').html(x)
});
</script>
I need that every time I change the div value, the span reflects the changes of the div
For example.
If I type 1 in the div, the span should immediately show me number 1
If I type 3283 in the div, the span should immediately show me number 3283
but with this code - I need to create
$("div").click(function(){
var x = $('div').html();
$('span').html(x)
});
I do not want to use .click(function) . in need this function run Automatically
after your answer
I use this code
http://jsfiddle.net/Danin_Na/uuo8yht1/3/
but doesn't work . whats the problem ?
This is very simple. If you add the contenteditable attribute to the div, you can use the keyup event:
var div = $('div'),
span = $('span');
span.html(div.html());
div.on('keyup', function() {
span.html(div.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span></span>
<div contenteditable="true"> variable like a number </div>
here is a demo with input:
html:
<span></span>
<input type="text" id="input01">
js:
$(document).ready(function(){
$( "#input01" ).on('keyup',function() {
var x = parseFloat($('#input01').val());
$('span').html(x)
});
});
How can you edit in div element on browser?
It have to be any input type then only you can edit or change value.
So for that on click of that div you have to show some input/textarea at that place and on change event of that input you can update the value of input in span.
<div id="main-div">
<input type="text" id="input-box" />
</div>
<script>
$(document).ready(function(){
$('#input-box').change(function(){
$('span').html($(this).text)
});
});
</script>
$("input[type=text]").change(function(){
var x = $('div').html();
$('span').text(x)
});
This can be use with textbox or textarea, For div user cannot enter text.
http://jsfiddle.net/uuo8yht1/
.change() will not work with a DIV-element. Since you did not specify how the DIV is updated I would recommend either setting a timer or using .keypress()
Example with timer:
$(function(){
var oldVal = "";
var divEl = $("div");
setInterval(function(){
var elTxt = divEl.text();
if (elTxt != oldVal) {
oldVal = elTxt;
$("span").text(elTxt);
}
}, 50);
});
You need a key listener, jquery provides a .keypress(), Examples are provided on keypress documentation.
I recommend to lookup the combination of .on() and .keyup() with some delay or throttle/debounce either via jquery or underscore.js library.
One of the reason or need for delay is to prevent too many event calls which will affect performance.
Here is an example of code in another question regarding throttle and keyup
Hope this helps.

Categories

Resources