Onmouseout not triggering event following 'paste' - javascript

I'm running a form which contains a textbox for the entry of a PIN code.
When typing the code in, each character is replaced with an * and the actual value entered is put into a new variable.
Click 'Submit' or 'Enter' and it works fine. (code below).
However, when I paste the code into the textbox, (id=user_pin_code) the characters are not replaced with * and the values are not entered to that other variable (PINcode), which means that, when I click 'Submit' or hit Enter key, the value is not passed to the next script.
It seems I need the onmouseup or onmouseout event to trigger the JS (to change the chars to ****** and to put the actual characters into 'PINcode' ) but, those two events don't seem to work which means the new variable is not populated.
Any guidance or pointers would be much appreciated.
<script>
\$(document).ready(function(e) {
var actualTextEntered = "";
\$("#user_pin_code").keyup(function(e) {
var x = document.getElementById("user_pin_code").value;
actualTextEntered += x.replace(/\\*/g,"");
//actualTextEntered += x.replace(/*/g,"");
addEventListener('keydown', function(event) {
const key = event.key; // const {key} = event; ES6+
//console.log( 'key = ' + key );
if ( key === "Backspace" ) {
// Do something
actualTextEntered = '';
x='';
}
if ( key === "Return" ) {
//console.log( 'key pressed = ' + key);
}
});
document.getElementById("user_pin_code").value = "";
for (var i=0;i<actualTextEntered.length;i++)
{
document.getElementById("user_pin_code").value += "*";
document.getElementById("PINcode").value = actualTextEntered;
}
});
});
</script>);

Check this code if it works:
<script>
\$(document).ready(function(e) {
var actualTextEntered = "";
\$("#user_pin_code").keyup(function(e) {
var x = document.getElementById("user_pin_code").value;
actualTextEntered += x.replace(/\\*/g,"");
//actualTextEntered += x.replace(/*/g,"");
\$("#user_pin_code").keydown(function(event) {
const key = event.key; // const {key} = event; ES6+
//console.log( 'key = ' + key );
if ( key === "Backspace" ) {
// Do something
actualTextEntered = '';
x='';
}
if ( key === "Return" ) {
//console.log( 'key pressed = ' + key);
}
});
document.getElementById("user_pin_code").value = "";
for (var i=0;i<actualTextEntered.length;i++)
{
document.getElementById("user_pin_code").value += "*";
document.getElementById("PINcode").value = actualTextEntered;
}
});
});
</script>);

Related

JQUERY + sign keep on adding on typing backspace key

Running below HTML and JS code to get value from JSON and render itself input field. Rendering and display works fine.
But when i try to edit the number, +90 98888222 (example) exists.. on typing backspace key, it repeatedly adding + sign. ex: +++++90 98888222. On each press of backspace, it adds the + sign.
This code in get function only causing the issue i think. Need to add + sign manually it front as JSON data response without + sign.
return CONTACT_MOBILE ? '+' + CONTACT_MOBILE.number : '';
Not sure how to block with 1 + when typing backspace.
Thanks
get: function() {
let CONTACT_MOBILE = _.find(this.updateProfile.contactList, (contact) => {
return contact.type == 'MOBILE';
});
return CONTACT_MOBILE ? '+' + CONTACT_MOBILE.number : '';
},
set: function(newValue) {
let CONTACT_MOBILE = _.find(this.updateProfile.contactList, (contact) => {
return contact.type == 'MOBILE';
});
if(CONTACT_MOBILE) {
CONTACT_MOBILE.number = '+' + newValue;
}
}
Use this :
set: function(newValue) {
let CONTACT_MOBILE = _.find(this.updateProfile.contactList, (contact) => {
return contact.type == 'MOBILE';
});
if(CONTACT_MOBILE) {
CONTACT_MOBILE.number = "";
if(!(newValue.charAt(0) === '+')){
CONTACT_MOBILE.number = '+';
}
CONTACT_MOBILE.number += newValue;
}
}

javascript focus() not working, nor setting field value

Notes Domino web form, validating onblur what was entered in a field. Field is set as a number but I want to catch what was entered immediately if it is not a number. Then I want to clear what was entered and put the focus right back in the field. I get the code to run, and the alert comes up correctly but the focus does not happen, nor does the value get removed.
function checkNumeric(fld, nm) {
debugger;
var x;
x = document.getElementById(fld).value;
// If x is Not a Number or less than one or greater than 10
if (isNaN(x)) {
document.getElementById(fld).value = '';
alert("Non-numeric entry of '" + x + "' in : " + nm +", please try again.");
document.getElementById(fld).focus();
}
}
Be also sure that the event handler which calls this is set to prevent default. Otherwise it might be the element get the focus but is removed afterwards by the event handler emediatly.
function checkNumeric(fld, nm) {
//debugger;
var x;
if (typeof fld !== "string") {
alert("fld is not a string");
}
if (typeof nm !== "string") {
alert("nm is not a string");
}
var elm = document.getElementById(fld);
if (elm) {
x = elm.value;
if (isNaN(x)) {
elm.value = '';
alert("Non-numeric entry of '" + x + "' in : " + nm + ", please try again.");
elm.focus();
}
}
}

Javascript regex to count occurrences of hashtags in a textarea

I am trying to add a count value before each hashtag in a textarea like this:
"An example #string containing a #few #hashtags"
"An example 1:#string containing a 2:#few 3:#hashtags"
I need the counters to appear in real time as the user is typing.
I am using a keyup() event callback to check the value of the textarea and trying to insert the count before each occurrence of a hashtag using a regex match:
let value = '';
let _textarea = document.querySelector('textarea');
_textarea.addEventListener('keyup', e => {
value = _textarea.value;
let tags = value.match(/(#\S*)/g); //Match all hashtags
let i = 0;
value = value.replace(/(#\S*)/g, matched => {
console.log(matched, i);
i++;
return i + ':' + matched;
});
_textarea.value = value;
console.log(tags);
});
<textarea></textarea>
The problem is that this continuously prepends the counter after each keyup event is triggered.
What would be a suitable solution for this?
let _textarea = document.querySelector('textarea');
_textarea.addEventListener('keyup', e => {
let target = e.target;
let value = target.value;
let i = 0;
value = value.replace(/.?#/g, matched => {
i++;
let output = matched;
if (/[^:]#/.test(matched)) {
output = `${matched[0]}${i}:${matched[1]}`;
}
return output;
});
_textarea.value = value;
});
<textarea></textarea>
I have made some changes to your code that I believe achieve what you want.
Inside your replace function I have added a conditional that only attaches the index to the hashtag if it doesn't have a colon in front of it already
Improving on #Cameron's answer, this one allows for a hashtag to be used at the start of a string as well.
let _textarea = document.querySelector('textarea');
_textarea.addEventListener('keyup', e => {
let target = e.target;
let value = target.value;
let i = 0;
value = value.replace(/.?#/g, matched => {
i++;
let output = matched;
if (/(?:[^:]|^)#/.test(matched)) {
if(matched.length > 1) {
output = `${matched[0]}${i}:${matched[1]}`;
} else {
output = `${i}:${matched[0]}`;
}
}
return output;
});
_textarea.value = value;
});
<textarea></textarea>
In value.replace use /.#/g. This regex will return hashtag with it's previous symbol. So you can check if it ":" or not
value = value.replace(/.#/g, matched => {
i++;
if(matched[0] === ':')
return matched;
return i + ':' + matched;
});

Speech recognition API duplicated phrases on Android

I found, that speech recognition API duplicates result phrases on my Android (and does not duplicate on desktop).
For each phrase said, it returns two results. First one is
and the second one is
As you see, in the second return, phrase is duplicated, each copy is marked as final and second one is beyond resultIndex. In first return there is only one copy, it is final and it is beyond resultIndex.
I would take only second return, but the problem is that it happens on mobile Chrome, but does not happen on desktop Chrome. Desktop Chrome returns only first return.
So, the question is: is this by design behavior? Then how to distinguish single final phrase then commonly for all computers?
Or may be this is some error like sound echo, then the question is how to avoid/check echo?
UPDATE
Html is follows:
<input id="recbutton" type="button" value="Recognize">
<div id="output">
<div>
Initial text
</div>
</div>
Code is follows:
var recognition = null;
var recognitionStarted = false;
var printcount = 1;
var lastPhrase = null;
$(function() {
attachRecognition();
});
$('#recbutton').click( function() {
if( !recognitionStarted ) {
recognition.start();
}
else {
recognition.stop();
}
});
function printOut(text) {
var id = 'printcount' + printcount;
printcount++;
$('#output').append(
"<div id='" + printcount + "'>" + text + "</div>"
);
$("#output").animate({ scrollTop: $("#output").prop('scrollHeight')});
return printcount;
}
function attachRecognition() {
if (!('webkitSpeechRecognition' in window)) {
$('button').prop('disabled', true);
recognition = null;
} else {
$('button').prop('disabled', false);
recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onstart = function(event) {
recognitionStarted = true;
printOut("speech recognition started");
};
recognition.onend = function(event) {
recognitionStarted = false;
printOut("speech recognition stopped");
};
recognition.onresult = function(event) {
var finalPhrase = '';
var interimPhrase = '';
var result;
var printcount;
for(var i=0; i<event.results.length; ++i) {
result = event.results[i];
if( result.isFinal ) {
finalPhrase = finalPhrase.trim() + ' ' + result[0].transcript;
}
else {
interimPhrase = interimPhrase.trim() + ' ' + result[0].transcript;
}
}
if( !lastPhrase ) {
printcount = printOut('');
lastPhrase = $('#' + printcount);
}
lastPhrase.html(finalPhrase.trim() + ' ' + interimPhrase.trim());
if( finalPhrase.trim() ) {
lastPhrase = null;
}
};
}
}
JsFiddle: https://jsfiddle.net/dimskraft/envwao8o/1/
The results provided on Chrome mobile regarding the result.isFinal property seem to have a bug or in any case to differ from the ones on Chrome desktop. A possible workaround is to check the confidence attribute of the (first) alternative:
onResultHandler(event) {
let i = event.resultIndex;
let result = event.results[i];
let isFinal = result.isFinal && (result[0].confidence > 0);
}
It also looks like that sometimes the final result is emitted twice (with the same confidence value), in that case you may want to debounce it or just process the first event, like this:
if (isFinal) {
transcript = result[0].transcript;
if(transcript == lastDebounceTranscript) {
return;
}
lastDebounceTranscript = transcript;
}
where lastDebounceTranscript is a variable that you initialize outside of the scope of the event handler
Try this:
recognition.continuous = false;
recognition.interimResults = false;
recognition.maxAlternatives = 1;
JSFiddle: https://jsfiddle.net/envwao8o/4/

Modify javascript code to iterate through all variables in the form

I have the following code that worked fine till now as I decided to add more variables to the form. How can I make this function smart and itterate and pass all the variables in the form?
function getquerystring(strFormName) {
var form = document.forms[strFormName];
var word = form.clock_code.value;
qstr = 'clock_code=' + escape(word); // NOTE: no '?' before querystring
return qstr;
}
complete JS code # pastie
It looks like you're serializing a form to a querystring? If that's the case, then this is one place where a JavaScript library is really nice.
Each of these will serialize the first form on the page to a querystring.
// ExtJS
var str = Ext.lib.Ajax.serializeForm(Ext.select('form').elements[0]);
// jQuery
var str = $("form").serialize();
// MooTools
var str = $$('form').toQueryString();
// PrototypeJS
var str = $$('form')[0].serialize();
You can see some other methods and how they compare at http://jquery.malsup.com/form/comp/
Try this
function formToQueryString(form) {
var elements = form.elements;
var cgi = [];
for (var i = 0, n = elements.length; i < n; ++i) {
var el = elements[i];
if (!el.name) { continue; }
if (el.tagName === 'INPUT' && (el.type === 'checkbox' || el.type === 'radio')
&& !el.checked) {
continue;
}
cgi.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
}
return cgi.length ? '?' + cgi.join('&') : '';
}
The issue with your code is that you're only grabbing the clock_code element value, and ignoring the rest. Here's a replacement I wrote up:
function getquerystring(strFormName) {
var qstr = '', word = '';
var key = 0;
var form = document.forms[strFormName];
var fields = ['clock_code', 'message', 'type'];
for (var i = 0; i<fields.length; i++) {
key = fields[i];
word = form[key].value;
if (qstr && qstr.length > 0) {
qstr += '&';
}
qstr += encodeURIComponent(key) + '=' + encodeURIComponent(word);
}
return qstr;
}
Benjamin's approach is a bit more flexible; mine only queries those fields specifically named in the fields array
Assuming they are all simple fields, the following should work just fine (didn't test it, though - sorry if it doesn't "compile"):
function getquerystring(strFormName) {
var qstr = '';
var form = document.forms[strFormName];
var elements = form.elements;
var first = true;
for (elem in elements) {
var word = elem.value;
var name = elem.name;
if (first) {
first = false;
} else {
qstr = qstr + '&';
}
qstr = qstr + name + '=' + escape(word);
}
return qstr;
}
Adding info on supporting multiple Element types:
The question only mentioned text fields so I assumed the easier answer would suffice. Wrong!
Glad you're able to use JQuery (which rocks), but for completeness I'll just flesh this out with a bit of info on how to build your own "dynamic form handler".
First, you have to add checking on the class of elem, like so:
function isCheckbox(o){ return (o && o.constructor == Checkbox) }
and you have to then do something a little different depending on the type of object you are looking at.
For example:
for (var elem in elements) {
var value = '';
var name = elem.name;
if (isCheckbox(elem)) {
value = elem.checked ? 'true' : 'false';
} else if (isSingleSelect(elem)) {
var index = elem.selectedIndex;
if(selected_index > 0) {
value = elem.options[selected_index].value;
}
}
}
There may be situations where you have to turn values into something that is meaningful to your app, like in a multiple-select combo box. You could send one name=value pair for each value or roll them into a comma-seperated list or the like - it all depends on your app. But with this approach one can certainly build the "dynamic form handler" that fits their specific needs.
Check out this article for helpful stuff about how to process each form field type: http://www.javascript-coder.com/javascript-form/javascript-get-form.htm

Categories

Resources