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

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);
}

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>

Is there a way to speed up a function's completion in Javascript?

I am very new to Javascript as I began self-learning just yesterday. I am trying to emulate a type racer game.
(spacebar) as the input will signify the completion of my attempt to type the current word, and I have functions to check if it is correct/incorrect, and then resets the input.
So if I type apple and then (space), the input field becomes reset.
However the problem is if the user types too quickly, then the first or more character of the next word is included in the input before the reset function.
Example:
words to type: apple lemon
user input: apple lemon
input field: apple le -> upon space, reset() is called and clears input but user already typed le once reset() is completed -> mon
So I am wondering if there is a way to speed up reset() such that it is called and completed before the next input from the user.
I initially had everything under 1 function "inputMatch", that was called upon keyup, but tried to separate the reset() and inputMatch() functions by having one being called upon keydown, and the other upon keyup.
This is the code I have. I can provide more context/the full code if needed, but since I am new here, I am unsure whether people prefer to read simplified pseudo code or actual code.
<input type="text" class="form-control" id="inputfield" value="" dir="ltr" placeholder="" onkeyup="reset()" onkeydown="inputMatch(event)">
<script>
const inputMatch = () => {
var current = word that I am currently attempting to type;
if(event.keyCode == 32){ //spacebar
change word that was typed to be either correct or incorrect
};
//once at end need to remove the first (current.wordnr - 1) words
}
const reset = () => {
if(event.keyCode == 32){ //spacebar
document.getElementById('inputfield').value = ""; //clear input field
}
}
</script>
Welcome to Stack Overflow! My recommendation would be to use the oninput event handler instead of onkeyup/onkeydown. See the following code:
const handle = (input) => {
if (input.charAt(input.length - 1) === ' ') // If the last character is a space
reset()
else // otherwise, handle your input (in your case, use it in your type racing game)
console.log("Partial word: " + input)
}
const inputField = document.getElementById("inputfield")
const reset = () => {
console.log("Entered word: " + inputField.value.trimRight())
inputField.value = ""
}
<input type="text" id="inputfield" value="" dir="ltr" placeholder="" oninput="handle(this.value)">
oninput runs synchronously, meaning that it's impossible for the user to type too quickly. It also makes the code a lot simpler.

Regex for negative money format - 2decimal place & can go negative

I have an input and on input change, I change it to the money format.
<input type="number" class="currency" step="0.01">
like this:
$('input[type="number"].currency').on('input', function(e) {
this.value = this.value.match(/^-?\d+\.?\d{0,2}/);
});
However, as this gets triggered on every keypress, it doesn't let me write "-" as first character; so it erases it as soon as I click "-"
What kind of regex can I use for allowing that?
https://jsfiddle.net/4zv9wLr3/ - Here is a fiddle, try to write a negative number, it won't allow you to write.
When "number" input triggers the input event, the value was received blank.
$('input[type="number"].currency').on('input', function(e) {
if (e.target.value.length !== 0) {
this.value = this.value.match(/^-?\d+\.?\d{0,2}/);
}
});
I added a guard like this and it worked.

How to enter text into a input without using input.value

I have an existing app which requires a user to answer questions using an input box. I did not code this app and I do not want to mess around with the apps code. I have created a virtual on screen numpad from buttons which when pressed add the corresponding value to the input box using '.value'. This does 'work' and the numbers do appear in the input box but they are not saved by the existing code meaning that they mustn't be capturing the '.value'.
Is there some easy way of essentially.. simulating a user inputting text
function geet (clicked_value) {
var input = document.querySelector(".pt-subpage-current input");
if (input.value.length < 3) {
input.value += clicked_value;
}
}
function removeValue() {
var input = document.querySelector(".pt-subpage-current input");
var length = input.value.length;
if (length > 0) {
input.value = input.value.substring(0, length-1);
}
}
<input type="button" onClick="geet(this.value)" value="7" class="button
number" id="num7" />
You can use div with content editable true ,if that works for you.This is for your simulating part in your question
function edit()
{
let te=document.getElementById("textdiv").textContent;
console.log(te)
}
<div id="textdiv" contenteditable="true">Hello, edit me!</div>
<button onclick="edit()">Button</button>
I literally just made a numpad for someone here. all you need to do is use the showKeyPad() in an onclick event and give the fields id's. Let me know if you need help.
EDIT: Sorry just realized you said it is not saving .value.
This keypad uses the .value.

Trigger onKeyUp from script after input value is changed

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

Categories

Resources