Javascript focus() not working when onkeyup event is executed in iOS - javascript

I have 4 input boxes to enter 4 digit passcode. I want to focus to the next input box when the first input box is filled by user.
I had to use document.getElementById('second').focus(); to focus to the next input box. Unfortunately this does not work in iOs.
I did further research and found that focusing is not happened with the event like "onkeyup", "onkeypress", but it works with "onclick" event.
Do you guys any idea to fix this problem or alternative solution to fix this problem.
HTML
<input id="first" name="first" type="number" style="width: 50px; height: 50px;" maxlength="1" onkeyup="focusSecondBox(event);" />
<input id="second" name="second" type="number" style="width: 50px; height: 50px;" maxlength="1" onkeyup="focusThirdBox(event);"/>
JS
function getEventCharCode(evt){
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
return charCode;
}
function isEmptyElement(element){
return (element === null || element.value === null || element.value === '');
}
function focusSecondBox(evt){
var element = document.getElementById('first');
var previousElement = document.getElementById('first');
var nextElement = document.getElementById('second');
focusInput();
}
function focusInput(){
var charCode = getEventCharCode(evt);
if (isEmptyElement(element)) {
if (charCode === 8) {
previousElement.focus();
previousElement.value = previousElement.value;
}
} else if (nextElement !== null) {
nextElement.focus();
}
}
Thank you

In iOS safari. Difficult or impossible to show keyboard by call focus() without mouse event as far as I know.
alternative solution
But, in this case, I implemented what expect in the following ways:
Use invisible input field.
Focus invisible input field when any input passcode field focused.
Move invisible input field position with key event.
Change passcode field by invisible input field.
HTML
<div id="dummyDiv" style="width:0px;height:0px;overflow:hidden;">
<input id="dummy" type="number" />
</div>
<input id="p0" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p1" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p2" type="number" style="width: 50px; height: 50px;" maxlength="1" />
<input id="p3" type="number" style="width: 50px; height: 50px;" maxlength="1" />
JavaScript
window.addEventListener('load', function() {
var words = [];
for(var i=0; i < 4; i++) {
words[i] = document.getElementById('p'+i);
}
var dummy = document.getElementById('dummy');
var dummyDiv = document.getElementById('dummyDiv');
words.forEach(function(word) {
word.addEventListener('click', function(e) {
dummy.focus();
});
});
dummy.addEventListener('keypress', function(e) {
if (dummy.value.length >= 4 || !String.fromCharCode(e.keyCode).match(/[0-9\.]/)) {
e.preventDefault();
}
});
dummy.addEventListener('keyup', function(e) {
console.log(dummy.value);
var len = dummy.value.length;
for(var i=0; i<4; i++) {
if(len <= i) {
words[i].value = '';
} else {
words[i].value = dummy.value[i];
}
}
if (len>=4) {
return;
}
dummyDiv.style.position = 'absolute';
var rect = words[len].getBoundingClientRect();
dummyDiv.style.left = rect.left+'px';
dummyDiv.style.top = (rect.top+15)+'px';
});
});
working sample
http://nakaji-dayo.github.com/ios-safari-passcode-boxes/
Please look on iOS

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#hidebox {position:absolute; border: none; background:transparent;padding:1px;}
#hidebox:focus{outline: 0;}
</style>
</head>
<body>
<input type="text" maxlength="1" onkeyup="keyUp(this)" onkeydown="keyDown(this)" size="2" id="hidebox" at="1">
<input type="text" maxlength="1" size="2" id="mFirst" at="1" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mSecond" at="2" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mThird" at="3" onfocus="onFocus(this)"><input type="text" maxlength="1" size="2" id="mFourth" at="4" onfocus="onFocus(this)">
</li>
<script type="text/javascript">
window.onload = function() {
document.getElementById("mFirst").focus();
}
var array = ["mFirst","mSecond","mThird","mFourth"];
function keyUp(e) {
var curId = array[Number(e.getAttribute("at"))-1];
var nextId = array[Number(e.getAttribute("at"))];
var curval= e.value;
var letters = /^[0-9a-zA-Z]+$/;
if(e.value.match(letters)){
document.getElementById(curId).value = curval;
if(e.getAttribute("at") <= 3){
var nextPos = document.getElementById(nextId).offsetLeft;
e.setAttribute("at",Number(e.getAttribute("at"))+1);
e.style.left = nextPos+"px";
}
e.value = ""
}else {
e.value = "";
}
}
function keyDown(e) {
var curId = array[Number(e.getAttribute("at"))-1];
document.getElementById(curId).value = "";
}
function onFocus(e) {
document.getElementById("hidebox").focus();
document.getElementById("hidebox").setAttribute("at",Number(e.getAttribute("at")));
document.getElementById("hidebox").style.left = e.offsetLeft+"px";
document.getElementById("hidebox").style.top = e.offsetTop+"px";
}
</script>
</body>
</html>

Related

Value of Sum not changed after unchecked Checkbox Button

Im looking solution for this problem.
I have 3 input number that will sum all of that and display it to input4.
All my code is working fine but only when I unchecked the checkbox, the value of sum didn't update.
Scenario example:
Checked on first checkbox and enter value of 1
Checked on second checkbox and enter value of 1. This will trigger the display value and will show result=2
Unchecked the first checkbox will clear the first input value, but the result display not update(still result=2.. Should be result=1)
Html:
<input type="checkbox" id="chkbxcasting" />
<input type="number" id="casting1" name="casting1" value="0" disabled onchange="valChange(this);" onkeyup="sum1();" /><br>
<input type="checkbox" id="chkbxdeburring" />
<input type="number" id="deburring1" name="deburring1" value="0" disabled onchange="valChange(this);" onkeyup="sum1();" /><br>
<input type="checkbox" id="chkbxecoat" />
<input type="number" id="ecoat1" name="ecoat1" value="0" disabled onchange="valChange(this);" onkeyup="sum1();" /><br><br>
<input class="invisibleinput" type="number" id="totalaffectqty" name="totalaffectqty" readonly />
CSS
input[value="0"] { color: #fff; }
Javascript + JQuery
function valChange(obj){
if(obj.value=="0"){
obj.style.color="#fff"
} else{
obj.style.color="#000"
}
}
$(document).ready(function() {
$('#chkbxcasting').on('change', function() {
$("#casting1").prop("disabled", !$(this).is(':checked'));
$("#casting1").val('');
});
$('#chkbxdeburring').on('change', function() {
$("#deburring1").prop("disabled", !$(this).is(':checked'));
$("#deburring1").val('');
});
$('#chkbxecoat').on('change', function() {
$("#ecoat1").prop("disabled", !$(this).is(':checked'));
$("#ecoat1").val('');
});
});
function sum1() {
let casting1 = +(document.getElementById('casting1').value);
let deburring1 = +(document.getElementById('deburring1').value);
let ecoat1 = +(document.getElementById('ecoat1').value);
let result1 = casting1 + deburring1 + ecoat1;
if (!isNaN(result1)) {
document.getElementById('totalaffectqty').value = result1;
}
else {
document.getElementById('totalaffectqty').value = '0';
}
}
This is the demo:
Demo Here
Thank You in Advance
Working Demo - https://jsfiddle.net/disingh123/szmt8rv2/3/
<input type="checkbox" id="chkbxcasting" />
<input type="number" id="casting1" name="casting1" value="0" disabled /><br>
<input type="checkbox" id="chkbxdeburring" />
<input type="number" id="deburring1" name="deburring1" value="0" disabled /><br>
<input type="checkbox" id="chkbxecoat" />
<input type="number" id="ecoat1" name="ecoat1" value="0" disabled /><br><br>
<input class="invisibleinput" type="number" id="totalaffectqty" name="totalaffectqty" readonly />
$(document).ready(function () {
$('body').on('change', function (event) {
const { target: { type } } = event
if (type === 'checkbox') {
const jQueryFiedTarget = $(event.target)
const isChecked = jQueryFiedTarget.is(':checked')
const associatedTextField = jQueryFiedTarget.next()
associatedTextField.prop("disabled", !isChecked);
associatedTextField.val(isChecked ? '' : '0')
if (!isChecked) {
sum1()
}
}
})
$('body').on('keyup', function (event) {
const { target: { type } } = event
if (type === 'number') {
sum1()
}
})
});
function sum1() {
const casting1 = +(document.getElementById('casting1').value);
const deburring1 = +(document.getElementById('deburring1').value);
const ecoat1 = +(document.getElementById('ecoat1').value);
const result1 = casting1 + deburring1 + ecoat1;
document.getElementById('totalaffectqty').value = isNaN(result1) ? '0' : result1
}

Javascript textbox either 1 can be entered

I had 2 textbox, but only 1 can be enter and cannot enter both fields. For example if I enter value in input1, input2 is disable. if both value is 0 both field disable to false.
Any help here?
var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
function myFunction() {
if (input1 != 0 && input2 == 0){
document.getElementById("input2").disabled = true;
//ALERT(1);
}else if(input1 == 0 && input2 != 0){
//ALERT(2);
document.getElementById("input1").disabled = true;
}else if(input1 == 0 && input2 == 0){
//ALERT(3);
document.getElementById("input1").disabled = false;
document.getElementById("input2").disabled = false;
}
}
<input id="input1" style="width: 100px;" type="number" min="0" value="0.00" onchange="myFunction()"/>
<input id="input2" style="width: 100px;" type="number" min="0" value="0.00" onchange="myFunction()"/>
You can use the blur event, which fires when an element has lost focus.
var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
function myFunction() {
input1.addEventListener("blur", event => {
let value = event.target.value;
input2.disabled = !!value && value != 0;
});
input2.addEventListener("blur", event => {
let value = event.target.value;
input1.disabled = !!value && value != 0;
});
}
<input id="input1" style="width: 100px;" type="number" min="0" value="0.00" onchange="myFunction()" />
<input id="input2" style="width: 100px;" type="number" min="0" value="0.00" onchange="myFunction()" />
Consider the following code example.
$(function() {
function isEmpty(fObj) {
console.log($(fObj).val());
return ($(fObj).val() == "" ? true : false);
}
$(".form").on("change blur", "input", function() {
if (!isEmpty(this)) {
$(".form input").not(this).prop("disabled", true);
}
if ($(this).val() == "0") {
$(".form input").prop("disabled", false);
}
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form">
<input id="input1" style="width: 100px;" type="number" min="0" value="0.00" />
<input id="input2" style="width: 100px;" type="number" min="0" value="0.00" />
</div>
You can use change or blur callbacks and examine the target (this) of the event.

Auto Selecting the next Input field and going Back

Once inputed, a user can't go back to change their input.
$("form").on("keyup change paste", function(e) {
e.preventDefault();
var a = $(this).find("input[type='text'].a");
var b = $(this).find("input[type='text'].b");
var c = $(this).find("input[type='text'].c");
var d = $(this).find("input[type='text'].d");
var e = $(this).find("input[type='text'].e");
var f = $(this).find("input[type='text'].f");
a.val(a.val().replace(/[^0-9]/g, ""));
b.val(b.val().replace(/[^0-9]/g, ""));
c.val(c.val().replace(/[^0-9]/g, ""));
d.val(d.val().replace(/[^0-9]/g, ""));
e.val(e.val().replace(/[^0-9]/g, ""));
f.val(f.val().replace(/[^0-9]/g, ""));
if (a.val().length == a.attr('maxlength')) {
a.next("input").focus();
}
if (b.val().length == a.attr('maxlength')) {
b.next("input").focus();
}
if (c.val().length == a.attr('maxlength')) {
c.next().next("input").focus();
}
if (d.val().length == a.attr('maxlength')) {
d.next("input").focus();
}
if (e.val().length == a.attr('maxlength')) {
e.next("input").focus();
}
if (f.val().length == a.attr('maxlength')) {
f.next("input").focus();
}
});
input {
width: 20px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="code" action="*" method="post" autocomplete="off">
<input type="text" name="code" maxlength="1" autocomplete="off" class="a">
<input type="text" name="code" maxlength="1" autocomplete="off" class="b">
<input type="text" name="code" maxlength="1" autocomplete="off" class="c">
<span>—</span>
<input type="text" name="code" maxlength="1" autocomplete="off" class="d">
<input type="text" name="code" maxlength="1" autocomplete="off" class="e">
<input type="text" name="code" maxlength="1" autocomplete="off" class="f last">
</form>
How can that be done?
And is there a more elegant approach to mine above?
Live: jsFiddle
Any time you find yourself finding very repetitious code, always think LOOP.
The below will allow the user to edit their values. It also greatly reduces your code.
$('form').on('input', e => {
var letters = ['a', 'b', 'c', 'd', 'e', 'f'];
letters.forEach(letter => {
let field = $(e.target);
field.val(field.val().replace(/[^0-9]/g, ''));
if(field.val().length == field.attr('maxlength')) { field.nextAll('input').first().focus(); }
});
});
Fiddle.
Notes:
Listen for the input event; it has the advantage of covering all the events you were listening for, and, crucially, fires after keypress (meaning you can be sure of grabbing the latest, complete value from the field)
avoid repetitious code; the loop allows us to write the business logic once rather than repeatedly
there is no need to prevent the event's default action
by using nextAll('input').first(), we can be sure of getting the next input, whether it's the next sibling or, as is the case with the third input, separated by another type of element
My idea would be to focus next, and loop when arriving at the last one. Replace the number in case of a new entry.
// init the html
const nbInput = 6;
let html = '';
for (let i = 0; i < nbInput; i += 1) {
html += `<input type="text" name="code" maxlength="1" autocomplete="off" number="${i}">`;
}
$('form').html(html);
$('form input').on('keypress', function(e) {
e.preventDefault();
// Ignore bad values
if (/^[^0-9]$/g.test(String.fromCharCode(e.which))) {
return;
}
// Replace the actual value with the keypressed one
$(this).val(String.fromCharCode(e.which));
// Reset & focus next
if ($(this).val() !== '' && Number($(this).attr('number')) < (nbInput - 1)) {
$(`input[number=${Number($(this).attr('number')) + 1}]`).focus();
} else {
// Focus the first item when we finished
$('input[number="0"]').focus();
}
});
input {
width: 20px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="code" action="*" method="post" autocomplete="off">
</form>
Clearing the inputs on focus would do it. (I don't use jQuery much, so apologies if I have any incorrect syntax.)
$("form").focus(function() {
var a = $(this).find("input[type='text'].a")
var b = $(this).find("input[type='text'].b") // ...etc
a.val("");
b.val(""); // ...etc
});
That said, Utkanos is 100% correct that a loop is the right way to handle both issues (auto-advancing and allowing edits).

Text boxes only char save-reset box

i want to create 2 text boxes.I want to write something on those text boxes ,and save the value of each in an array or somewhere.There are only char characters.I have and reset to delete a value if it needs.I did a lot work,but it didn't worked.
AM: <input type="text" id="myText" value="GiveAm" size="10" id="myInput">
<button onclick="document.getElementById('myInput').value = ''">Reset</button>
<button onclick="myFunction()">Kataxwrisi</button>
<br>
Surname <input id='charInput' type="text" value="" size="10%">
<button onclick="myFunction()">Kataxwrisi</button>
</br>
<script>
function myFunction() {
document.getElementById("myText").value = "Johnny Bravo";
}
function getChar(event){
if(event.which == null){
return String.fromCharCode(event.keyCode);
}else if(event.which !-0 && event.charCode != 0){
return String.fromCharCode(event.which);
}else{return null; }
}
document.getElementById('charInput').onkeypress=
function(event){
var char =getChar(event || window.event)
if(!char) return false;
document.getElementById('keyData').innerHTML =char + "was clicked";
return true;
}
</script>
Not 100% sure what you are trying to do here. But this is my best guess at a solution. When a user presses the 'enter' key in a text box, the current value of that text box is stored in an array.
var arrSavedValues = [];
function setInputValue(argInputID, argNewValue) {
document.getElementById(argInputID).value = argNewValue;
}
function saveValue(e){
if(e.keyCode === 13){
e.preventDefault();
var caller = e.target || e.srcElement;
arrSavedValues.push(caller.value);
alert("Saved " + caller.value + " to arrSavedValues.");
}
}
<div>
<label>AM:</label>
<input id="txtAM" type="text" value="GiveAm" size="10" onkeypress="saveValue(event)" />
<button onclick="setInputValue('txtAM','')">Reset</button>
<button onclick="setInputValue('txtAM','Johnny Bravo')">Kataxwrisi</button>
</div>
<div>
<label>Surname:</label>
<input id="txtSurname" type="text" value="" size="10" onkeypress="saveValue(event)" />
<button onclick="setInputValue('txtSurname','Johnny Bravo')">Kataxwrisi</button>
</div>

How to create a label inside an <input> element and style it?

I can make my label inside an input element (my "disappearing text"):
HTML
<input name="firstName" type="text" maxlength="40" value="Enter your first name"
onfocus="if(this.value==this.defaultValue)this.value=''"
onblur="if(this.value=='')this.value=this.defaultValue" />
Then style it so my disappearing text is faded (#333). And style it so when I start to input a value into the field the text is black (#000).
CSS
input[type=text] {
color: #333;
}
input[type=text]:focus {
color: #000;
}
It all works fine until you move onto the next input field. Then the field you just entered a value in changes back to the #333 color. I can see why that happens, but can't quite get to how to keep the value black #000 color if the input field has had a value put into it.
Thanks in advance for the assist and education!
HTML5
HTML5 brings a handy attribute for the <input> tag called placeholder which enables native support of this functionality.
jsFiddle
<input type="text" placeholder="Search..." />
Support
All latest browsers support this, IE9 and below don't however.
<label>
Note that the placeholder attribute is not a replacemenr for the <label> tag which every input should have, make sure you include a label for the <input> even if it's not visible to the user.
<label for="search">Search</label>
<input id="search" placeholder="Search..." />
The above <label> can be hidden so it's still available to assistive technologies like so:
label[for=search] {
position:absolute;
left:-9999px;
top:-9999px;
}
Cross-browser solution
Here is a potential cross-browser solution, I've moved the code out of the tag and into script tags and then used the class placeholder to indicate when to fade the text.
jsFiddle
HTML
<input name="firstName" type="text" maxlength="40" value="Enter your first name"
class="placeholder" id="my-input" />
CSS
input[type=text].placeholder {
color: #999;
}
JS
<script type="text/javascript">
var input = document.getElementById('my-input');
input.onfocus = function () {
if (this.value == this.defaultValue && this.className == 'placeholder') {
this.value = '';
}
this.className = '';
};
input.onblur = function() {
if (this.value == '') {
this.className = 'placeholder';
this.value = this.defaultValue;
}
};
</script>
Apply to all input[type=text]
We can extend the above solution to apply to all input[type=text] by using document.getElementsByTagName(), looping through them and checking the type attribute with element.getAttribute().
jsFiddle
var input = document.getElementsByTagName('input');
for (var i = 0; i < input.length; i++) {
if (input[i].getAttribute('type') === 'text') {
input[i].onfocus = inputOnfocus;
input[i].onblur = inputOnblur;
}
}
function inputOnfocus () {
if (this.value == this.defaultValue && this.className == 'placeholder') {
this.value = '';
}
this.className = '';
}
function inputOnblur() {
if (this.value == '') {
this.className = 'placeholder';
this.value = this.defaultValue;
}
}
This appears to work xbrowser using a combination of jQuery and the Modernizer library.
Requires the jQuery and Modernizer Libraries be on the site and properly referenced.
HTML
<head>
<script src="jquery-1.9.1.min.js"></script>
<script src="modernizr.js"></script>
<script>
$(document).ready(function(){
if(!Modernizr.input.placeholder){
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
input.removeClass('placeholder');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.addClass('placeholder');
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
}
</script>
</head>
<body>
<form>
<input name="firstName" type="text" maxlength="40" placeholder="Enter your first name">
</form>
CSS
input[type=text] {
color: #000;
}
input[type=text].placeholder {
color: #666;
}
SOURCE: http://webdesignerwall.com/tutorials/cross-browser-html5-placeholder-text

Categories