Can't focus back to input field after blur - javascript

So I have look at most related link on my problem and can't seems to make it work.
Tried the workaround on this link jquery focus back to the same input field on error not working on all browsers but it didn't work for me.
I have a javascript that evaluate the value of an input field on exit (blur). That works well. The problem is when the value is wrong, I show an alert, delete the content of the field and set the focus back on the faulty field.
There comes the problem. In Firefox, the focus will still go on the other field which I clicked on (triggering the blur() of the previous field).
In IE(11.0.9600) or Chrome(64.0), the alert shows but keeps coming back in some sort of infinite loop. I have to kill the browser.
So here is a VERY truncated version of my HTML:
<!DOCTYPE html>
<html class="OUTPUT WEB CHANNEL_WEB simplex" section="ChargesLinesList" dpi="96" scale="1.0">
<input id="dateBilled" class="myDateField" name="dateBilled" value="2018-01-18" type="text">
<input id="dateBilled" class="myDateField" name="dateBilled" type="text">
<input id="dateBilled" class="myDateField" name="dateBilled" type="text">
and this is my code to validate the value and show the alert:
$(".myDateField").on("blur", function(event){
var myDateFormat = /^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$/;
if(!myDateFormat.test($(this).val())){
alert('Invalid date or format. Make sure you the format his YYYY-MM-DD and the date is valid');
$(this).val("");
$(this).focus();
}
})

The blur event triggers whenever a field loses the focus, but in your case, when someone leaves a field and clicks into another one, blur will fire for the first field, and if that field fails your validation, the focus will switch back to it, causing the other field that the user clicked into to lose the focus and then blur will fire for that field and so on.
Instead, you should be using the change event, which triggers when the focus is lost, but only if the value of the field has changed since it got the focus. This will avoid an infinite loop and .focus() will then work properly.
Also, you can't have multiple elements with the same id and each text box should also have a unique name.
Lastly, your <html> tag is full of attributes that are not valid for HTML. Most of what you are doing there should be accomplished via media queries.
$(".myDateField").on("change", function(event){
var myDateFormat = /^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$/;
if(!myDateFormat.test($(this).val())){
alert('Invalid date or format. Make sure you the format his YYYY-MM-DD and the date is valid');
$(this).val("");
$(this).focus();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="dateBilled1" class="myDateField" name="dateBilled1" value="2018-01-18" type="text">
<input id="dateBilled2" class="myDateField" name="dateBilled2" type="text">
<input id="dateBilled3" class="myDateField" name="dateBilled3" type="text">

Related

Javascript first click on input with a suggestion doesn't work in safari

I am trying to attach a click handler on an input, but for some reason it doesn't work for first click on inputs that get autosuggestion in safari. All other clicks after the first one work. So for example if an input has a name or label before it saying First name, Last name, Email or anything similar Safari will put a suggestion widget at the end of the input and suggest my information that is in Keychain Access I guess. Click event will not trigger the first time I click on that input, after the first one it triggers ok.
Here is the code that produces this issue. Basically I need a way to trigger a click event on inputs every time it gets clicked (preferably vanilla js, but jquery would be ok too).
HTML:
<form>
// Click on this input doesn't trigger the first time I click it because Safari has a suggestion widget for this input
<label for="email">Email</label>
<input type="email" class="form-control" id="email" placeholder="you#example.com" data-input="">
// Click on this input triggers every time I click it with no issue
<label for="address">Address</label>
<input type="text" class="form-control" id="address" placeholder="1234 Main St" required="" data-input="">
</form>
JS:
var inputs = document.querySelectorAll('[data-input]');
var myFunction = function(event) {
console.log('Clicked');
};
for (var i = 0; i < inputs.length; i++) {
// I put this console.log here to see if all of the inputs pass through this for loop to get the event listener and they do
console.log(inputs[i]);
inputs[i].addEventListener('click', myFunction);
}
EDIT: even though #gopigorantala's link in his comment might be considered duplicate, I am not looking for the same thing that question is looking for. That question asks for a way to disable safari autosuggestion feature on inputs, I am looking for a way to detect clicks on inputs despite autosuggestion being there.

Excel VBA fill textbox with autocomplete in IE11

How can I fill a textbox that uses javascript to suggest available entries using Excel VBA? Filling the textbox manually, I would start typing a few letters and a list of available inputs I could choose from will appear below the textbox. I need to click with my mouse or use the arrow keys to navigate to the entry I want in the javascript dropdown box and click enter.
This is the key difference with other regular input boxes. If I simply enter the text in the input box and proceed to the next input box without choosing the entry from the dropdown box, the input does not register. So I cannot simply find the element of the input box and change its value. I believe I need to execute the javascript that activates the dropdown box which I must then select from it.
The HTML code for the input textbox is:
<td id="input2" class="createInputField" colspan="0" valign="middle"
<input value="" id="" name="docTypeDisplay" title="Document Type" size="18" type="text">
<input value="" name="docType" type="hidden">
<input value="" name="docTypeID" type="hidden">
There are 5 event listeners on the first input tag line of the code above - blur, dblclick, focus, keydown and keypress from a javascript. I tried looking up the javascript but it is not readily understandable and is H-U-G-E! So with this limitation in mind, here's what I've tried:
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Value = "Monthly Report"
Set objEvent = IE.Document.createEvent("HTMLEvents")
objEvent.initEvent "change", False, True
IE.Document.getElementById("input2").getElementsByTagName("input")(0).dispatchEvent objEvent
and variations by changing the first argument in objEvent.initEvent to "blur", "dblclick", "focus", "keydown" and "keypress". I don't get any errors and the input does not register.
Then I've tried:
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Value = "Monthly Report"
IE.Document.getElementById("input2").getElementsByTagName("input")(0).FireEvent ("onchange")
and also tried:
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Focus
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Value = "Monthly Report"
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Blur
and nothing has worked.
Can anyone help please? I think I've exhausted google looking for a solution for this.
Using sendkeys, I was able to fill the input box, wait for the suggested input to show up in the dropdown box and then simulate an "Enter" keypress to register the input. I found Application.SendKeys "Enter" didn't work and so I had to improvise. I suspect the "Enter" key may be tied to the Keypress javascript event.
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Focus
Application.SendKeys "Monthly Report"
Application.Wait (Now + TimeValue("0:00:05")) 'Wait for javascript to fire and suggest an input
Application.SendKeys "~" 'This simulates an "Enter" keypress on the first suggested input
This script will fail though if at anytime during the Excel VBA execution I click on another window. I am hoping someone will come along with a more reliable solution.
Y-E-S! I finally found something that worked through trial and error without using SendKeys. Credit to #QHarr to suggest trying combining events, which kept me going in the right direction. So this is what worked for me:
'First fill the input box with text
IE.Document.getElementById("input2").getElementsByTagName("input")(0).Value = "Monthly Report"
'Fire the keypress event to start the javascript to suggest an input
Set objEvent = IE.Document.createEvent("keyboardEvent")
objEvent.initEvent "keypress", True, False
IE.Document.getElementById("input2").getElementsByTagName("input")(0).dispatchEvent objEvent
'Wait for a few seconds for the javascript to complete creating the dropdown box
Application.Wait (Now + TimeValue("0:00:05"))
'Select the first suggested input from the dropdown box. I noticed a new element was created when the dropdown box appeared, which I simulated a click on.
IE.Document.getElementById("suggest_input2").getElementsByClassName("object")(0).Click
Only one more thing I would like to change with this answer before it's perfect, which is to replace the application.wait time with a more robust line. Trying the code below didn't work. Any ideas how I can tell Excel VBA to wait for a javascript to finish loading before proceeding?
While IE.Busy Or IE.ReadyState <> 4: DoEvents: Wend

How to automatically disable a text field after checkbox is ticked

I am currently working on a project, that requires me to implement the following:
I've got 2 input fields - a regular text field, and a checkbox.
What I want to do is - if the user fills in the text field, the checkbox should be automatically disabled. If the checkbox is checked instead, the text field should be disabled.
What I've come up with so far is:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onblur="document.getElementById('dis_rm').disabled = (''!=this.value);" >
If I fill in the text field, the checkbox is successfully disabled. However, if I tick the checkbox, the text field remains available.
What am I missing?
If I were you I would:
Move my JS code out of the HTML and into a separate file or at least into a script element.
Use document.getElementById to find an item in the DOM. See https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Once you have the element from the DOM, add an event listener for the blur events like this myElement.addEventListener('blur', myCallbackMethod). See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener for more info.
Inside your callback method you can use event.target.checked to see if the element you've added the event listener to is checked.
Here is a little snippet to get you going:
const
textInput = document.getElementById('element-ID-here'),
checkbox = document.getElementById('element-ID-here');
function onTextInputBlurHandler(event) {
// if textinput value is empty then
// set disabled for checkbox to false
// else
// set disabled for chexbox to true
}
textInput.addEventListenet('blur', onTextInputBlurHandler);
<input type="text" name="num-input1" id="dis_rm" value=""/>
<input type="checkbox" name="num-input2" id="dis_per" value=""/>
With this info you should be able to get (a little) further. When you do, update your question with your JavaScript code and I am sure people will be happy to help you further.
People are bringing up great suggestions in the comments and answers for better code design and quality, but from a purely functional point of view, there are two core things that you should do to get the functionality that you are describing:
1) As mentioned by Paul S. use the checked property for your checkbox logic. Right now, you are checking to see if the checkbox value is not an empty string, but it will always be an empty string, because that's the value that you've assigned to the element:
<input type="checkbox" name="num-input2" id="dis_per" value="" <----- *here*
Nothing else in your code is changing that, so it will always fail the logic check.
However, the checked property automatically switches between true and false as you check and uncheck the input. To do the logic check that you are looking for using that, do this for your JavaScript!
document.getElementById('dis_rm').disabled = this.checked;
2) Switch the event that you are binding for (at least) the checkbox to the "change" event instead of "blur". For checkboxes, the "change" event will trigger when you click on the checkbox (or hit space bar), but the element still maintains its focus. The blur event Will only fire once the user moves the focus to another element of the page.
I'd also recommend using "change" for the text field (there's no point in running the check, if the value is the same when you leave the field as it was when you entered it), but it's not as important since, from a timing point of view, when the "change" event fires, it happens immediately after the "blur" event, so, from the user's point-of-view, the behavior would be the same.
When it's all said and done, if you made no other changes to your code to improve the code design/quality (Thijs made some great suggestions, BTW), this is the minimum change that you would need to get the functionality that you want:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onchange="document.getElementById('dis_rm').disabled = (this.checked);" >

Reducing 2 steps to 1step when clicked on input type=date

So I am using input type="date" in cordova type mobile application. For some reason, placeholder won't show up if the input type is date. So an empty button like thing appears, when clicked calendar would appear. So I am trying to follow a hack in which input type="text" has a placeholder "Next Action Date". And onfocus I am changing the type to date. And onblur I am changing back to type="text" and make a placeholder again. So this process is partly solving the problem, which I am trying to solve. Which to make that white button thing disappear. But in my current code, I have to follow two steps
First is to click on placeholder, then onfocus will get fired and makes the white thing to appear
Second is I have to click on the white thing to make the calendar appear
I don't want this second step to appear. Here is my code
<ElementsBasket name='nextActionDate'
data={this.props.newLead.get('actions').get('nextActionDate')}>
<div className="form-group">
<input type="text" className="form-control" onFocus={this._onFocus} onBlur={this._onBlur} placeholder="Next Action Date"
value={this.props.newLead.get('actions').get('nextActionDate')}
onChange={onFieldChanged.bind(this, 'actions.nextActionDate')}
/>
</div>
</ElementsBasket>
_onFocus: function(e){
e.currentTarget.type = "date";
},
_onBlur:function(e){
e.currentTarget.type="text"
e.currentTarget.placeholder = "Next Action Date";
},
Also I tried onclick, which also took two steps. I have followed this link
Not showing placeholder for input type="date" field
PS: White thing is a button with no text, when clicked would give a calendar
You can try firing focus or click event:
_onFocus: function() {
e.currentTarget.type = "date";
e.currentTarget.focus(); // or .click();
}
Try overlaying the date input over the placeholder input and setting the date input to CSS opacity: 0. Therefore, when the user tries to click the placeholder input, they actually click the date input.
Here is an example JSBin. http://jsbin.com/rozusihade/edit?css,js,output
Notice the onDateInputFocus and onDateInputBlur callbacks that update the date input's appearance.
try onfocus=""
<input placeholder="select date" type="text" onfocus="(this.type='date')">
http://codepen.io/anon/pen/zGaQax
Otherwise, I will make a place holder with ng-show, instead of change input tag. Input tag should always be "date" if you want to use native selection of date. (which is always should do)

Making a text field uneditable and not just readonly

When i click on a textfield, i get a dropdown so the user could select a value from the list.
After the user selects the date from the dropdown, he/she could edit the date by even adding characters to it. So i want to find a way to prevent this. I thought of making the field un-editable. So i used readonly but, this prevents the user from clicking and displaying the list. So can someone tell me how can i make the field uneditable.
<input id="datePiccc" type="text" class="dates" />
You can use the below code. This will make the text input field clickable but when the user types in anything, nothing would happen.
document.getElementById('datePiccc').onkeydown = function(e){
e.preventDefault();
}
Fiddle Demo
As pointed out by nnnnnn, onkeydown is a better option than onkeypress as it would stop the delete and backspace key functions.
You could add the below also to your code to nullify Cut and Paste events1. (Note: Not doing anything for Copy as that operation isn't going to change the value of the text field).
document.getElementById('datePiccc').oncut = function(e){
e.preventDefault();
}
document.getElementById('datePiccc').onpaste = function(e){
e.preventDefault();
}
1 I think these should work in all browsers. Currently tested in Chrome 31, Opera 15, IE10 and FireFox 24. (Note: In IE10, there is an x mark which appears on the right side of the input field which when clicked clears the entire field value. Could not find a way around this.)
I'm assuming the text field is being set in javascript. If so, you can use the following line to disable the field:
document.getElementById('datePiccc').disabled=true;
The input will remain as it is and the value from the selection field can also be set.
Disable the input in JQuery as
$("#datePiccc").attr("disabled", true);
And in pure JS
document.getElementById('datePiccc').disabled = true;
May be this can help!

Categories

Resources