How to detect when entire form is out of focus? - javascript

I have a text form with an input field for name and an input field for email. On the mobile site, when the user clicks on a field, it is brought to the top of the viewport with the keypad below it. However, when either text field is de-selected, it gets stuck here and does not reset.
I have found the jquery focusOut event to reset the page zoom, but this fires whenever either field is not focused (ie. when the name fields is active and email is not). How can I detect when NEITHER input field is in focus?
Right now my form code is:
<form class="form-signin" action="http://" method="post" id="subForm" onsubmit="movedrop()">
<input type="text" class="form-control" id="fieldName" name="cm-name" placeholder="Full Name" tabindex=1 required>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="fieldEmail" name="cm-hjjhkh-hjjhkh" class="form-control" placeholder="Email" tabindex=2 required>
<button class="btn btn-lg btn-white btn-block subscribe" id="click-subscribe" type="submit" tabindex=3>SUBSCRIBE</button>
</form>
and my javascript:
$("form").focusout(function() {
document.body.scrollTop = 0;
console.log("focus out");
})
Which fires every time either field is deselected. I want it to fire when neither is selected.

You need to check that none of the others members have become active in the meantime. Focusout just tells you when one of the input fields loses focus.
Try the following code:
$("form").focusout(function() {
var anyActive = false;
$.each($(this).find(':input'), function(index, inputField){
if($(inputField).is(':active')){
anyActive = true;
}
});
if(anyActive){
$('#focusBox').html('One is active');
} else {
$('#focusBox').html('None is active');
}
document.body.scrollTop = 0;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-signin" action="http://" method="post" id="subForm" onsubmit="movedrop()">
<input type="text" class="form-control" id="fieldName" name="cm-name" placeholder="Full Name" tabindex=1 required>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="fieldEmail" name="cm-hjjhkh-hjjhkh" class="form-control" placeholder="Email" tabindex=2 required>
<button class="btn btn-lg btn-white btn-block subscribe" id="click-subscribe" type="submit" tabindex=3>SUBSCRIBE</button>
</form>
<div id="focusBox"></div>

I've dealt with this type of thing in the past by looking at focus events for the entire page as a whole. Essentially, I use two flags to keep track of whether or not the form 1) has focus and 2) has ever had focus. Then, I use a single handler for both click and focusin for the entire body the looks at the target of the event: if that target is inside the form, we know that the form hasn't lost focus. If not and wasFormFocused, then we know the form has lost focus: reset the flags and do whatever else is necessary (in this case, scroll to the top). This solution handles tabing out, clicking out, and also clicking on labels with the form.
var wasFormFocused = false, isFormFocused = false;
$("#theForm").focusout(function() {
isFormFocused = false;
});
var handleClickOrTab = function(event) {
if ($(event.target).parents("#theForm").length) {
wasFormFocused = true;
return;
}
if (wasFormFocused && !isFormFocused) {
wasFormFocused = false;
document.body.scrollTop = 0;
$("body").append('<br>form lost focus (scrollTop = 0)');
}
}
$("body").click(handleClickOrTab).focusin(handleClickOrTab);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="theForm" class="form-signin" action="http://" method="post" id="subForm" onsubmit="movedrop()">
<input type="text" class="form-control" id="fieldName" name="cm-name" placeholder="Full Name" tabindex=1 required>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="fieldEmail" name="cm-hjjhkh-hjjhkh" class="form-control" placeholder="Email" tabindex=2 required>
<button class="btn btn-lg btn-white btn-block subscribe" id="click-subscribe" type="submit" tabindex=3>SUBSCRIBE</button>
</form>
<h4>CLICK me (cause you can't tab to me)</h4>
<input type="text" placeholder="TAB to me or CLICK me">

Related

Struggling to validate the email when toggling

The HTML Code:
<div class="form-container">
<form method="post" id="email">
<div class="form-group">
<label for="exampleInputEmail1" class="typingA spacing"><i class="bi bi-envelope"></i> Email Address:</label>
<input type="email" class="form-control" id="typingEmail" aria-describedby="emailHelp" placeholder="Enter email">
</div>
</form>
<form method="post" id="subject">
<fieldset class="form-group">
<label for="subject" class="typingA spacing">Subject:</label>
<input type="text" class="form-control"name="subject"placeholder="Subject" >
</fieldset>
</form>
<form method="post" id="content">
<fieldset class="form-group">
<label for="content" class="typingA spacing">What would you like me to ask?</label>
<textarea class="form-control" name="content" rows="3" placeholder="What would you like me to ask, Sir/Madam?"></textarea>
</fieldset>
</form>
<div id="buttons">
<button type="submit" id="next" class="btn btn-primary" enabled='enabled'>Next</button>
<button type="submit" id="submit" class="btn btn-primary">Submit</button>
</div>
The JQuery part:
function isEmail(email) {
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
}
$("#buttons").click(function() {
$("#next").click(function() {
if(isEmail($('#typingEmail').val()) == false)
{
$(':input[type="submit"]').prop('disabled', false);
}
$("#subject").toggle();
$("#email").toggle();
$("#next").click(function() {
$("#content").toggle();
$("#email").toggle();
$('#next').attr('disabled', true);
});
});
});
What I am trying to do is validate the email. if it is valid, the "next button" should enable, else it should not enable. I tried but didn't succeed. I appreciate your time and help. Ta!
Note I tried to find similar topic on StackOverflow but didn't find it. So, just a humble
request, dont report.
I think you just want to disable and enable the next button when the email is valid or not valid, here is a workaround, i don't know whether it cover your requirement or not.
function isEmail(email) {
var regex = /^([a-zA-Z0-9_.+-])+\#(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
}
$(function(){
var $emailInput = $('#typingEmail');
var $nextBtn = $('#next');
function checkIfEmailOk(){
return isEmail($emailInput.val());
}
function toggleNextByEmail(){
$nextBtn.prop('disabled', !checkIfEmailOk());
}
// or you can listen the 'blur' event
// but the validation will only triggered after your cursor moved out from the input area
// and the 'input' event may need some polyfill in lower versions of IE
$emailInput.on('input', function(){
toggleNextByEmail();
});
// disable the next button's onclick event when the email is not valid
$nextBtn.on('click', function(e){
if(!checkIfEmailOk()){
// email not ok
e.preventDefault();
$emailInput.focus();
}
});
// if you want to check the email input and toggle the next button when domready
toggleNextByEmail();
});
You can try it in the codepen.

How to show and hide a form?

When I load a page, I need to show form for name, but when I click "submit" i need hide that form. How can i do that with javascript?
<div id="small-form">
<form>
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname"><br>
<input type="submit" value="Submit" onclick="hideForm()">
</form>
</div>
In the hideForm() function set display:none style for the div small-form.
Like that:
var myFormDiv = document.getElementById("small-form");
myFormDiv.style.display = "none";
You cannot just hide the form if it submits to the server unless you either Ajax the form to the server or target an iframe or new tab
When the form submits, a new page is loaded. If it loads the same page, you can either hide it on the server or set an instruction in localStorage to tell the page to not show the form
I also strongly suggest you do NOT use onclick of a submit button but the submit event
document.getElementById("myForm").addEventListener("submit",function(e) {
e.preventDefault(); // if you want to NOT submit the form
document.getElementById("small-form").classList.add("hide");
// here you can ajax or do other stuff without submitting
})
.hide { display: none; }
<div id="small-form">
<form id="myForm">
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname"><br>
<input type="submit" value="Submit">
</form>
</div>
You can set the display style to none in the hideForm() function in javascript to hide the form.
But, because you are using a submit button on the form it will try to redirect when the submit button is pressed. A simple solution to this (if you don't want the form to actually be submitted) is to change the type of the input to button rather than submit.
function hideForm()
{
document.getElementById('small-form').style.display = 'none';
}
<div id="small-form">
<form >
<label for="fname">First name:</label><br>
<input type="text" id="fname" name="fname"><br>
<input type="button" value="Submit" onclick="hideForm();">
</form>
</div>
If you wish to permanently hide the form you can do something like this. Just set the display property of the form to none. This will hide the form but it will exist there in the HTML code.
function hideForm() {
event.preventDefault();
var myForm = document.getElementById("My-Form");
myForm.style.display = "none";
var name = document.getElementById("Name");
alert(name.value);
}
<div id="small-form">
<form id="My-Form">
<label for="fname">First name:</label><br>
<input id="Name" type="text" id="fname" name="fname"><br>
<input type="submit" value="Submit" onclick="hideForm(event)">
</form>
</div>
Another way to achieve what you are trying to do is simply remove the form. You can do this by calling remove() function on the form. This permanently removes the form.
function hideForm(event) {
event.preventDefault();
var myForm = document.getElementById("My-Form");
var name = document.getElementById("Name");
alert(name.value);
myForm.remove();
}
<div id="small-form">
<form id="My-Form">
<label for="fname">First name:</label><br>
<input id="Name" type="text" id="fname" name="fname"><br>
<input type="submit" value="Submit" onclick="hideForm(event)">
</form>
</div>

`Required` attribute not working with <form> tag [duplicate]

This question already has answers here:
HTML5 required attribute not working
(2 answers)
Closed last month.
My required attribute doesn't specify that an input field must be filled out before submitting the form.
HTML:
<!-- Modal Content -->
<form class="modal-content2">
<div class="container3">
<h1>Sign Up</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="firstName"><b>First Name</b></label>
<input type="text" id="firstName" placeholder="Enter First Name" name="firstName" required>
<label for="lastName"><b>Last Name</b></label>
<input type="text" id="lastName" placeholder="Enter Last Name" name="lastName" required>
<label for="username"><b>Username</b></label>
<input type="text" id="username" placeholder="Enter Username" name="username" required>
<label for="email"><b>Email</b></label>
<input type="text" id="email" placeholder="Enter Email" name="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" id="password" placeholder="Enter Password" name="psw" onfocus="this.value=''"
required>
<label for="psw-confirm"><b>Confirm Password</b></label>
<input type="password" id="cfmpassword" placeholder="Confirm Password" name="psw-confirm" onfocus="this.value=''"
required>
<br>
<br>
<p>By creating an account you agree to our <a href="aboutus.html" style="color:dodgerblue">Terms &
Privacy</a>.</p>
<div class="clearfix">
<button type="button" onclick="document.getElementById('id02').style.display='none'" class="cancelbtn2">Cancel</button>
<button type="button" class="signupbtn" onclick="signUp()">Sign Up</button>
</div>
</div>
</form>
JavaScript:
function signUp() {
if (document.getElementById("password").value == document.getElementById("cfmpassword").value) {
var users = new Object();
users.firstName = document.getElementById("firstName").value;
users.lastName = document.getElementById("lastName").value;
users.username = document.getElementById("username").value;
users.email = document.getElementById("email").value;
users.password = document.getElementById("password").value;
var postUser = new XMLHttpRequest(); // new HttpRequest instance to send user details
postUser.open("POST", "/users", true);
postUser.setRequestHeader("Content-Type", "application/json");
postUser.send(JSON.stringify(users));
//go to the logged in page
window.location = "main.html";
}
else {
alert("Password column and Confirm Password column doesn't match!")
}
}
As the required attribute does not work, users can continuously submit empty forms and those will be stored in my SQL database
I don't have a <button type="submit"> in the form as this prevents me from using windows.location.
I am new to programming, can someone please give some suggestions (with explanations) on what to do to fix this? Any help would be appreciated! Thanks a lot! (I am using vanilla JavaScript for this)
The required attribute does not work because your form is not submitted. You need to specify a button with a type="submit" or <input type="submit"> to submit your form.
I suggest you to move the signUp function inside the form tag like this with an onsubmit event:
<form onsubmit="signUp(event)">.
Then add this to you Javascript function:
function signUp(event) {
event.preventDefault();
... your old code
}
For me, I see a number of possible issues. I have tried to remove them with the following sample code. I am assuming that /users will return something useful for checking and alerting the member if there is an error with the accessing of /users or the processing of the data.
The use of the required attribute of <input> will do nothing obvious in your code as the <button> has an onclick=signUp() call which will triggered before the browser check. With your current code the form values (present or not) will still be sent to /users as there is no testing for those values.
You need to move the signUp() call to the <form> if you want the browser check to be run.
To test this, removing the onclick=signUp() in the <button> will show you a browser tip window saying the value is needed.
As you are insisting on using AJAX to post the form data, moving the check to the <form> submit is idea and personally, I would still be checking the values - just good practice.
The next issue is you are not waiting for the return of a success or fail response from /users. In fact, you are blindly redirecting to main.html. If there is an error, the user will never know. This is a very bad user experience.
This is corrected in the sample code by checking for a response with a call-back, checking that response value and then alerting the member or redirecting if there is no error.
var users = {};
function ajaxPost(url,postData,callFunc) {
var http = new XMLHttpRequest();
if(! http){
return false;
}
http.onreadystatechange=function(){
if((http.readyState == 4) && (http.status == 200)) {
if(callFunc){
callFunc(http.responseText);
}
}
}
http.open('POST',url,true);
http.send(postData);
}
function validResult(str) {
if (str == "valid") {
// go to the logged in page
window.location = "main.html";
} else {
console.log("invalid result, let the user know");
}
}
function signUp(e) {
if(e){e.stopPropagation();e.preventDefault();}
var d = document.getElementById("signupForm").querySelectorAll("input");
var i, max = d.length;
// Quick check for values only. No check for the format of the values.
// This is good practice as a browser may still ignore the `required`
// attribute.
for(i=0;i<max;i++) {
d[i].value = d[i].value.trim();
if (d[i].value) {
users[d[i].name] = d[i].value;
} else {
// An alert would be better for the user here.
console.log("Missing value for ["+ d[i].name +"]");
// Go no further if there is a missing value.
return;
}
}
// at this point, all values added to the users object.
console.log("users:["+ JSON.stringify(users) +"]");
// Send the data and wait for a return value from /users
// --- remove comment on the following line to post ----
//ajaxPost("/users",JSON.stringify(users),validResult);
}
window.onload = function(){
var c = document.getElementById("signupForm");
if (c) {
c.addEventListener("submit",signUp,false);
}
}
<form id="signupForm">
<label for="firstName"><b>First Name</b></label>
<input type="text" id="firstName" placeholder="Enter First Name" name="firstName" required>
<p>
<label for="email"><b>Email</b></label>
<input type="email" id="email" placeholder="Enter Email" name="email" required>
<p>
<button id="submit" type="submit">Check and submit</button>
</form>
Basic of HTML5 validation. You have it on button click and that runs before the validation happens. This shows you that the onclick runs and the onsubmit does not. Use the correct event.
function loginSubmit () {
console.log('loginSubmit')
}
function loginClick () {
console.log('loginClick')
}
<form onsubmit="loginSubmit()">
<input name="foo" required />
<button onclick="loginClick()">click</button>
</form>
The way required attribute works is it determines whether the element its assigned to has a value length higher than a zero, if that statement is false (meaning the value length of zero) then upon submitting the form it focuses that element as its "required" to be fulfilled.
Here is an example with JavaScript and how checking input fields could work inside it.
const form = document.querySelector('form[action="signup.php"]'); // Form
const inputs = form.querySelectorAll('input'); // All input elements inside the form
const submit = form.querySelector('button[type="submit"]'); // Submit button inside the form
// Add onclick event to the form button
submit.addEventListener('click', function(event) {
event.preventDefault(); // This prevents the button from submitting the form the traditional way
submit_form(); // but instead our way
});
function submit_form()
{
// We iterate through the form input elements
for (var i = 0; i < inputs.length; i++)
{
// We check if the current element has
// the attribute required and if so
// we proceed with checks
if (inputs[i].hasAttribute('required') && inputs[i].value.length == 0)
{
inputs[i].focus(); // We focus on the required element
alert(inputs[i].placeholder+' is required!'); // Alert the user that the element is required
break; // Break from the loop
}
else
{
if (i == (inputs.length - 1)) form.submit(); // If the loop's i variable counter hits the same value as the
// input elements length then it means all fields are filled
}
}
}
form {
width:300px;
margin:auto
}
form button,
form input {
width:100%;
height:48px;
padding:0 15px;
font-size:18px;
box-sizing:border-box;
}
form input:focus {
background-color:#f2dfb7;
}
<form action="signup.php" method="POST">
<input type="text" name="first_name" placeholder="First Name" required>
<input type="text" name="last_name" placeholder="Last Name" required>
<input type="email" name="email" placeholder="Email Address" required>
<input type="email" name="email_repeat" placeholder="Email Address (Repeat)" required>
<input type="password" name="password" placeholder="Password" required>
<input type="text" name="phone" placeholder="Phone Number" required>
<input type="text" name="birthday" placeholder="Birthday (MM/DD/YYYY)" required>
<button type="submit">Sign Up</button>
</form>

Why "Please fill out this field" validate message show when I clicked Irrelevant button

I used map on my page and when I clicked 'cellSize' button Fill the fields warning appeared. I dont want to this. How can fix this ?
Warning like this :
this is my text field :
<div class="form-group">
<label for="name">Name</label>
<input ng-model="Name" ng-readonly="view.readonly" ng-maxlength="100" type="text" class="form-control input-sm" id="cluster-name" placeholder="Name" required>
</div>
and this is my increment button click :
change: function () {
this.trigger("spin");
$scope.cellSizeCoefficient = this.value();
$scope.$broadcast('mapCellSizeChanged', $scope.map);
$.each($scope.cellShapes, function (index, cellShape) {
var radius = getRadius(cellShape.Cell);
cellShape.Circle.setRadius(radius);
if (cellShape.Circle.label) {
var labelLoc = findLocationAtDistanceFrom(cellShape.Cell.LOC, cellShape.Cell.AZ, radius);
cellShape.Circle.label.setLatLng([labelLoc.Y, labelLoc.X]);
}
});
if (selectedCellCircle) {
var radius = getRadius(selectedCellCircle.Cell) + 50;
selectedCellCircle.setRadius(radius);
}
}
You're seeing the message due to the required attribute on the input element. It's shown when the form is submit which is happening when the 'increment' button is clicked.
To stop that behaviour add a type="button" attribute to the button:
<button type="button" style="margin-left:2px;" kendo-button="btnCellSizeIncrement" k-options="btnCellSizeIncrementOptions">
<i class="fa fa-plus pi-icon pi-icon-plus"></i>
</button>
Just FYI, you should add the type="button" attribute on any button elements that you do not want to submit the form when they are clicked.
Remove the required attribute from this HTML if its not a required field , otherwise browser will show this message on form submit. Make sure you are not submitting the form while clicking on the cell size button.
<input ng-model="Name" ng-readonly="view.readonly" ng-maxlength="100" type="text" class="form-control input-sm" id="cluster-name" placeholder="Name" required>
Add novalidate with form tag as it's required property so that will trigger HTML5 validation.
<form novalidate>
<div class="form-group"> <label for="name">Name</label> <input ng-model="Name" ng-readonly="view.readonly" ng-maxlength="100" type="text" class="form-control input-sm" id="cluster-name" placeholder="Name" required> </div>
</form>

How to make sure a form is valid before submitting using JQuery?

I'm trying to make a login page and have the following:
<div id="loginField">
<input id="username" type="text" name="user" required></input>
<input id="password" type="password" name="password" required></input>
<input id="submit" type="submit" name="submit" value="Login"></input>
</div>
I made sure that the username and password fields are required. When the login is successful (for this sake, let's just say that both fields are not empty) a login disappears and another view appears. Anyway, I checked to see if the login button is pressed with JQuery:
$(function(){
$('#submit').on('click', function(){
$('#loginField').hide();
$('#differentView').show();});
The problem is that when the login button is clicked, the required attributes gets ignore and the next view is shown. How do I make sure that the required attributes are not ignored when the login button is clicked?
A crude way of doing it...
<div id="loginField">
<input id="username" type="text" name="user" class="required">
<input id="password" type="password" name="password" class="required">
<input id="submit" type="submit" name="submit" value="Login">
</div>
$('#submit').on('click', function(e){
e.preventDefault();
var isReady = true;
$('.required').each(function(){
if (this.value === '') {
isReady = false;
return;
};
});
if (isReady) {
// submit form
};
});
You can use this library: Parsley. It is a javascript form validation library and it is very easy to use and you can customize it for your own means. Good luck!
Instead of handling onclick on button, you can put input fields into the form...
<form action="post" method="post" id="loginField">
<input id="username" type="text" name="user" required></input>
<input id="password" type="password" name="password" required></input>
<input id="submit" type="submit" name="submit" value="Login"></input>
</form>
... and in jQuery you can handle on submit action like this:
$(document).ready(function(){
$('#loginField').on('submit', function(event){
event.preventDefault();
var [username password] = $(this).serializeArray(),
username = username.value,
password = password.value;
/* some validations */
});
});
event.PreventDefault prevents browser from subbmiting so your page won't be refresh. serializeArray returns an array of objects (key-value) that's why you have to use .value
The required attributes are ignored because the input elements are not inside an html form element
To use the HTML5 input valuation attributes (required, minlength... etc)
The inputs should be grouped inside a form element, and you can listen for the form submit event, that is triggered by default when the user press enter (while focus is on a field inside the form) or clicks the submit button (input or button with type="submit") that is also wrapped inside the form
HTML
<form id="loginForm">
<input id="username" type="text" name="user" required />
<input id="password" type="password" name="password" required />
<input id="submit" type="submit" name="submit" value="Login" />
</form>
Javascript
$(function(){
$('#loginForm').on('submit', function (event) {
event.preventDefault(); // prevent default form submit page reload
console.log('I will enter this handler only on valid form')
$('#loginForm').hide();
$('#differentView').show();
})();
Here is a basic plunker with 2 examples https://plnkr.co/edit/I0vUMSeOlrjlYYu4VofU?p=preview
using the default html5 validation
using Parsley

Categories

Resources