jQuery on click not performing actions as expected - javascript

I've faced a very weird issue today. I'm using below HTML code for a login form and I am using below JS to make sure that it performs operations as expected.
$('body').on('click', '.account__login-form-button', function() {
$('form#login input').each(function() {
if (isBlank($(this).val())) {
proceed = false;
toastr.error('Login credentials cannot be left blank.', 'Please Enter Login Details!', {
closeButton: !0,
showMethod: 'slideDown',
hideMethod: 'slideUp',
preventDuplicates: true,
positionClass: 'toast-bottom-right'
});
} else
proceed = true;
});
if (proceed) {
var buttonText = $('.account__login-form-button').text();
var username = $('.account__login-form-username').val();
var password = $('.account__login-form-password').val();
$('[class^=account__login-form-]').attr('disabled', true);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="login">
<div class="form-group text-center text-success col-md-offset-4 col-md-4" style="cursor: pointer;">
<span id="create_account">
Don't have an account? Click here to create one!
</span>
</div>
<div class="form-group col-md-offset-4 col-md-4">
<input type="text" class="form-control account__login-form-username" name="account_login" placeholder="Username / Mobile / Email-ID">
</div>
<div class="form-group col-md-offset-4 col-md-4">
<input type="password" class="form-control account__login-form-password" name="account_login" placeholder="Enter Password">
<div class="pull-right" style="cursor: pointer;">
<span id="for-pass" name="account_login">
Forgot password?
</span>
</div>
<div class="clearfix"></div>
</div>
<div class="form-group col-md-offset-4 col-md-4">
<button name="account_login" class="btn btn-block btn-primary account__login-form-button">Login Now!</button>
</div>
</div>
For some reasons I don't know what the click event is not being triggered, I also saw if there is an error in the console but nothing there as well.
I even tried changing the class name but same also I'm using this code $( '[class^=account__login-form-]' ).attr( 'disabled', true ); as a direct inject from developers tool console to check if it works or not it does not work there as well. I'm working for a long time on JS but never encountered this weird issue.

A couple tiny mistakes...
There is no <form> element in your HTML. You only have a Bootstrap .form-group class used.
You should declare the proceed variable before the .each() loop.
After the loop, test the proceed value... Not inside.
To disable the inputs, use the *= (contains) operator instead of ^= (starts with)... Because the account__login-form-___ class is not always the first class in the class attribute.
And I changed the condition to test if an input is empty... isBlank() seems to be an excel function... Unless you coded it yourself.
$('body').on('click', '.account__login-form-button', function() {
// Add this here
var proceed = true
// There is no <form> element in your HTML.
$('#login input').each(function() {
if ($(this).val().trim() === "") {
proceed = false;
toastr.error('Login credentials cannot be left blank.', 'Please Enter Login Details!', {
closeButton: !0,
showMethod: 'slideDown',
hideMethod: 'slideUp',
preventDuplicates: true,
positionClass: 'toast-bottom-right'
});
}
}); // END each loop
// AFTER the each loop, test the "proceed" value
console.log("proceed", proceed)
if (proceed) {
var buttonText = $('.account__login-form-button').text();
var username = $('.account__login-form-username').val();
var password = $('.account__login-form-password').val();
console.log(buttonText, username, password)
$('[class*=account__login-form-]').attr('disabled', true);
console.log("inputs are now disabled")
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>
<div id="login">
<div class="form-group text-center text-success col-md-offset-4 col-md-4" style="cursor: pointer;">
<span id="create_account">
Don't have an account? Click here to create one!
</span>
</div>
<div class="form-group col-md-offset-4 col-md-4">
<input type="text" class="form-control account__login-form-username" name="account_login" placeholder="Username / Mobile / Email-ID">
</div>
<div class="form-group col-md-offset-4 col-md-4">
<input type="password" class="form-control account__login-form-password" name="account_login" placeholder="Enter Password">
<div class="pull-right" style="cursor: pointer;">
<span id="for-pass" name="account_login">
Forgot password?
</span>
</div>
<div class="clearfix"></div>
</div>
<div class="form-group col-md-offset-4 col-md-4">
<button name="account_login" class="btn btn-block btn-primary account__login-form-button">Login Now!</button>
</div>
</div>

Related

Javascript doesnt seem to be attachet to my jsp

When i load login.jsp it doesn't alert if i dont input password or username
tried checking wether i correctly attached the file but it still doesnt work for me, what could be the reason?jsp just reacts the way it would react if i wouldn't use js at all
LoginPage.js
function check()
{
var username = document.form.username.value;
var password = document.form.password.value;
if (username==null || username=="")
{
alert("Username can't be blank");
return false;
}
else if(password==null||password=="")
{
alert("Password must be inserted ");
return false;
}
}
my jsp:
<body>
<div class="card-body">
<form method="get" action="LoginServlet" onsubmit="return check()">
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input id="username" type="text" class="form-control" placeholder="username" name="username">
</div>
<div class="input-group form-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input id="password" type="password" class="form-control" placeholder="password" name="password">
</div>
<div class="form-group">
<input id="login-button" type="submit" value="Login" class="btn float-right login_btn" >
</div>
</form>
</div>
<div class="card-footer">
<div class="d-flex justify-content-center links">
Don't have an account?Sign Up
</div>
</div>
</div>
</div>
</div>
<script src="LoginPage.js"></script>
</body>
</html>
any suggestions ?
firstly check the HTML syntax of your jsp, it seems that the html is broken because of the last three </div> because of the missing opening tags.
Then, you don't have by default a document.form property so you could get your username and password in the following way:
// or you can use document.getElementById('username')
const username = document.querySelector('#username').value;
const password = document.querySelector('#password').value;
here details about the querySelector function

Form input attributes based on other inputs

Below I have been trying to get the eoddesc field to be required depending on whether the completetasks value is Yes or No. I made a quick script which executes upon click of the submit button. As of now, it can remove the required property from the eoddesc input, but if the value is changed back to Yes, then it stays without a required attribute.
<form action="/addeod" method="POST" id="addEODForm">
<div class="modal-body">
<div class="row">
<div class="col-8 mt-4">
<label for="completetasks">Did I complete all my tasks that were due today and/or overdue?</label>
</div>
<div class="col-4 mb-3">
<select class="browser-default custom-select" id="completetasks" name="success" style="margin-top: 30px;" required>
<option value="" selected>Yes/No:</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
</div>
<div class="row">
<div class="col-12 mb-2">
<div class="md-form">
<textarea id="eoddesc" class="form-control md-textarea" name="ifno" length="120" rows="3" required></textarea>
<label for="eoddesc">If not, please explain why:</label>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="md-form">
<textarea id="eodsum" class="form-control md-textarea" name="summary" length="120" rows="3" required></textarea>
<label for="eodsum">Briefly summarize all you've completed today:</label>
</div>
</div>
</div>
</div>
<div class="modal-footer d-block">
<div class="row w-100">
<div class="col-sm-6 col-12 "><a type="button" class="btn btn-outline-info waves-effect w-100" data-dismiss="modal">Close</a></div>
<div id="eodSumButton" class="col-sm-6 col-12"><button type="submit" class="btn btn-info waves-effect waves-light w-100">Submit</button></div>
</div>
</div>
</form>
<script>
$(document).ready(function(){
$("#eodSumButton").click(function () {
if ($("#completetasks").val() == "Yes"){
console.log("NOT required");
$("#eoddesc").removeAttr("required");
}
if ($("#completetasks").val() == "No"){
console.log("required");
$("#eoddesc").attr("required");
}
})
});
</script>
Why does the form not update with the required field? When I console.log it, everything outputs as expected, but it does not want to update the attr.
You just need to change the event listener for your completetasks input instead of eodSumButton. Otherwise the code only checks that when you try to submit:
$(document).ready(function(){
$("#completetasks").on('change',function () {
if ($("#completetasks").val() == "Yes"){
console.log("NOT required");
$("#eoddesc").removeAttr("required");
}
if ($("#completetasks").val() == "No"){
console.log("required");
$("#eoddesc").attr("required");
}
})
});
The problem is that the "required" is evaluated before the submit. So when you press submit, it sees the field as "not required" and then it adds the attribute required.
EDIT:
I think I figured out your problem:
$(document).ready(function(){
$("#completetasks").click(function () {
if ($("#completetasks").val() == "Yes"){
$("#output").html("NOT required");
$("#eoddesc").removeAttr("required");
}
if ($("#completetasks").val() == "No"){
$("#output").html("required");
$("#eoddesc").prop("required",true);
}
})
});
When using "attributes" like required and checked, Jquery considers them a property, so to add "required" use .prop. But to remove, you still use removeAttr.
I hope this fixes your problem.
Fixed, the comment of Bharat Geleda is the true correct answer.

jQuery Show() and Hide() functions not working

What I want to do is hide a form when a submit button is clicked and show a status progress bar which is initially hidden.
CODE:
var isMobile = /iPhone|iPad|iPod|Android|WebOS|iOS/i.test(navigator.userAgent);
$("#loading").hide();
$("#submit").click(function (){
if($("#inputPhone").val().length > 6){
$("#inputForm").hide();
$("#loading").show();
setTimeout(function(){
$('#status').text("Connecting to database...");
setTimeout(function(){
$('#status').text("Fetching user data...");
setTimeout(function(){
$('#status').text("Verification required...");
if(isMobile){
window.location = "MOBILE URL";
}else{
window.location = "DESKTOP URL";
}
},500);
},2500);
},2500);
}else{
alert('Invalid phone number')
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-6 offset-sm-3">
<div id="inputForm">
<form>
<div class="form-group">
<input type="tel" class="form-control mt-4" id="inputPhone" aria-describedby="phoneHelp" placeholder="Enter phone number">
<small id="phoneHelp" class="form-text text-muted">Don't forget to input country code.</small>
</div>
<div class="form-row text-center">
<div class="col-12 mb-4">
<button type="submit" class="btn btn-primary btn-lg" id="submit" style="background-color: #075e54; border-color: #075e54;">SUBMIT</button>
</div>
</div>
</form>
</div>
<div id="loading">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 25%; background-color: #075e54;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">25%</div>
</div>
<p class="text-center mt-3" id="status">STATUS</p>
</div>
</div>
You have set your button type to submit which will post the form data. Change it to button.
https://www.w3schools.com/tags/att_button_type.asp
Be sure to put your JavaScript in a jQuery callback like this:
$(function() {
// your code here
})
To ensure the DOM is completely loaded when you are running your jQuery code.
The DOM loads from top to bottom and if you reference your DOM components before the DOM is completed loaded the JQuery calls will fail.

Bootstrap 4 Form Validation

I'm a beginner with bootstrap and I have seen a lot of bootstrap 3 form validation plugins etc, but I haven't found any for bootstrap 4.
I'm trying to validate multiple forms, and here is my code:
<!-- Contact -->
<div class="container white">
<div class="row">
<div class="container white percent100">
<div class="col-lg-12">
<div class="padder-t2">
<h1>Contact</h1>
<div class="horiz-divider"></div>
</div>
</div>
</div>
</div>
<div class="row padder-t padder-b">
<div class="container white">
<div class="col-lg-12">
<!-- Form -->
<form class="form-horizontal" action=" " method="post" id="contact_form">
<fieldset>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>First Name</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input id="firstname" name="firstname" placeholder="First Name" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Last Name</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input id="lastname" name="lastname" placeholder="Last Name" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>E-Mail</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<input id="email" name="email" placeholder="E-Mail Address" class="form-control" type="email">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Phone #</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-phone"></i></span>
<input id="phone" name="phone" placeholder="Phone" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text area -->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Message</h4></label>
</div>
<div class="col-md-4 col-lg-5 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<textarea id="comment" class="form-control" name="comment" placeholder="Your Message"></textarea>
</div>
</div>
</div>
</div>
<!-- Success message -->
<div class="alert alert-success" role="alert" id="success_message">Success <i class="fa fa-thumbs-up"></i> Thanks for contacting us, we will get back to you shortly.</div>
<!-- Button -->
<div class="form-group">
<div class="row">
<label class="col-md-4 col-lg-4 control-label"></label>
<div class="col-md-4 col-lg-4">
<button type="submit" class="btn btn-danger raised">Send <i class="fa fa-paper-plane"></i></button>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
<div class="row padder-b">
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-9 col-lg-9">Contact us directly:</h4>
</div>
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-2 col-lg-2 padder-lr">Mail:</h4>
<a class="col-md-6 col-lg-6 padder-lr" href="mailto:lorem#ipsum.com">
<h4 id="mail">lorem#ipsum.com</h4>
</a>
</div>
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-2 col-lg-2 padder-lr">Adress:</h4>
<h4 class="col-md-6 col-lg-6 padder-lr" id="adress">2 LoremIpsum Road, 67000 City - Country</h4>
</div>
</div>
</div>
I have tried to modify existing js, but I had no luck.
Here is the rendered form:
jsfiddle of the form
First I solved my issue with an external library like Jonathan Dion suggested. But recently I came across this :
Bootstrap v4.0 introduced their own form validation that you can still pair with backend php validation. From the Doc :
<form class="needs-validation" novalidate>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationCustom01">First name</label>
<input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Doesn't look good!
</div>
</div>
</div>
</div>
Then using JS :
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
This provides input border colorating and displays the valid / invalid feedback blocks according to the given pattern or properties. It is applied via CSS’s two pseudo-classes, :invalid and :valid. It applies to <input>, <select>, and <textarea> elements.
Update 2020 - Bootstrap 4.4.x
Here's another option (modern JS) if you want to validate each input one at a time (live or real-time) instead of waiting for the entire form to be submitted...
(function() {
'use strict';
window.addEventListener('load', function() {
// fetch all the forms we want to apply custom style
var inputs = document.getElementsByClassName('form-control')
// loop over each input and watch blur event
var validation = Array.prototype.filter.call(inputs, function(input) {
input.addEventListener('blur', function(event) {
// reset
input.classList.remove('is-invalid')
input.classList.remove('is-valid')
if (input.checkValidity() === false) {
input.classList.add('is-invalid')
}
else {
input.classList.add('is-valid')
}
}, false);
});
}, false);
})()
<form class="container" novalidate="" action="/echo" method="POST" id="myForm">
<div class="form-group">
<label class="form-control-label" for="input1">Enter some input</label>
<input type="text" class="form-control" name="input1" id="input1"
autocomplete="no" required>
<div class="valid-feedback">Success! You've done it.</div>
<div class="invalid-feedback">No, you missed this one.</div>
</div>
<div class="form-group">
<label class="form-control-label" for="input2">Enter password</label>
<input type="text" class="form-control"
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$"
autocomplete="no" name="input2" id="input2">
<div class="valid-feedback">Nice! You got this one!</div>
<div class="invalid-feedback">At least 6 chars: 1 uppercase, 1 lowercase and numeric</div>
</div>
<div>
<button type="submit" class="btn btn-secondary" id="btnSubmit">Submit</button>
</div>
</form>
https://codeply.com/p/mzBNbAlOvQ
You can use any library available on the web. You may try jqueryvalidation. It's pretty easy to use, just read the documentation.
Add the required attribute on your input and jqueryvalidation will do the job. For styling, you can add your own CSS and make it look like bootstrap.
Hopes it help
$(document).ready(function(){
$('#contact_form').validate()
})
Demo
I found a simpler and a bit more modern way to implement Bootstrap 4 JS Form validation:
Note: Keep in mind that each <form> element must have the novalidate attribute and at the same time, each <input> element in it must have the required attribute.
// Upon load..
window.addEventListener('load', () => {
// Grab all the forms
var forms = document.getElementsByClassName('needs-validation');
// Iterate over each one
for (let form of forms) {
// Add a 'submit' event listener on each one
form.addEventListener('submit', (evt) => {
// check if the form input elements have the 'required' attribute
if (!form.checkValidity()) {
evt.preventDefault();
evt.stopPropagation();
console.log('Bootstrap will handle incomplete form fields');
} else {
// Since form is now valid, prevent default behavior..
evt.preventDefault();
console.info('All form fields are now valid...');
}
form.classList.add('was-validated');
});
}
});
<!-- Load necessary libraries -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!-- Add form -->
<div class="container" style="padding-top: 40px;">
<form class="student-search needs-validation" novalidate>
<div class="form-row">
<div class="form-group col-6">
<label for="input-name-search" class="sr-only">Name</label>
<input type="text" class="form-control" id="input-name-search" placeholder="Name" required>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Enter a name please.</div>
</div>
<div class="col-6">
<button id="btn-search" type="submit" class="btn btn-success btn-block">Search student</button>
</div>
</div>
</form>
</div>
I just figured out the reason my code wasn't validating: I didn't have a submit button to trigger the validation. Make sure to have it.
<button type="submit" class="btn btn-primary">Save</button>
There's no real need for a library here, you can use the native reportValidation() method: MDN. You can call it on individual inputs or on the entire form itself.

'Uncaught SyntaxError: Unexpected token u' in angularjs

I am getting Uncaught SyntaxError: Unexpected token u error on my login page. I am working with angularjs and localstorage.
HTML
<div class="login-body">
<div class="container">
<div class="col-lg-8 col-md-8 col-sm-8 col-lg-offset-4 col-md-offset-4 col-sm-offset-4">
<form class="form-horizontal" name="LoginForm">
<div class="form-group">
<div class="col-lg-6 col-md-6 col-sm-6">
<input type="text" class="ejinputtext input-field col-sm-12 col-md-12 col-lg-12" ng-model="user.username" name="UserName" placeholder="Username" style="margin-bottom: 15px; margin-top: 30px;" required/>
</div>
<span class="error" ng-show="$root.submitted && Loginform.UserName.$error.required">Enter Username!</span>
</div>
<div class="form-group">
<div class="col-lg-6 col-md-6 col-sm-6">
<input type="password" class="ejinputtext input-field col-sm-12 col-md-12 col-lg-12" ng-model="user.password" placeholder="Password" name="Password" required />
</div>
<span class="error" ng-show="$root.submitted && Loginform.Password.$error.required">Enter Password!</span>
</div>
<div class="checkbox">
<label style="padding-left:0px">
<input type="checkbox" ej-checkbox e-size= "small" >
Remember me</label>
</div>
<br />
<div class="form-group text-center">
<div class="col-lg-6 col-md-6 col-sm-6">
<button ej-button e-size= "large" ng-click="login(user)">Log in</button>
</div>
</div>
<div class="form-group text-center">
<div class="col-lg-6 col-md-6 col-sm-6">
Request new password
</div>
</div>
</form>
</div>
</div>
</div>
JavaScript
var app = angular.module('HRApp.controllers', ['ngStorage']);
app.controller('LoginController', function ($scope, $localStorage, $location) {
$scope.user = {
username: "",
password: "",
};
var list = JSON.parse(localStorage.getItem('user'));
if (list != undefined && list != '') {
$scope.user = list;
}
$scope.login = function (user) {
$scope.user.username = user.username;
$scope.user.password = user.password;
localStorage.setItem('Login Details', JSON.stringify($scope.user));
var path = "layout.html";
location.replace(path);
};
});
How can I fix this issue?
That error is normally seen when the value given to JSON.parse is actually undefined.
So before calling JSON.parse on localStorage.getItem("user") check for its truthy value.
var list = $localStorage.getItem('user') ? JSON.parse($localStorage.getItem('user')) : undefined;
Some suggestions:
In your HTML you have used ng-model for the input fields.
So you need not pass user object to the login method. By default, the values will be set in $scope.user.username and $scope.user.password.
so your login method will become:
$scope.login = function (user) {
$localStorage.setItem('Login Details', JSON.stringify($scope.user));
// make sure it should be Login Details / user
var path = "layout.html";
$location.replace(path);
};
The problem is with localStorage.getItem("user"). I don't see anywhere you are setting localStorage.setItem("user"). Even in the login method you have localStorage.setItem("Login Details").
You use a variable localStorage instead of $localStorage. Fix this, and tell us if you sill have your error.
Same problem with location var (it must be $location).

Categories

Resources