Delay of updating with if meteor/blaze statements - javascript

I created a mini application with custom login always in the same page, to explain better I have a main page with the login and registration and when I do the login/registration I remain on the same page and where was the login form appear a "Welcome Back" panel.
The problem is that when I try to reload the page with F5 I get for like 2 seconds the old login form and then appear the "Welcome Back" panel. I've used the If statements of Blaze to manage the check of the current user logged in as we can see:
<template name="login">
{{#if currentUser}}
<div class=" card mb-4 shadow-sm">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Welcome Back</h4>
</div>
<div class="card-body">
TEST
</div>
</div>
{{else}}
<div id="panel-login" class=" card mb-4 shadow-sm">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Login Form</h4>
</div>
<div class="card-body">
<form class="login-form">
<div class="form-group">
<label for="InputEmail">Email address</label>
<input type="email" class="form-control" name="email" id="InputEmailLogin" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="InputPassword">Password</label>
<input type="password" name="password" class="form-control" id="InputPasswordLogin" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Login</button>
<span>or Create an account</span>
</form>
</div>
</div>
<div id="panel-register" class=" card mb-4 shadow-sm">
<div class="card-header">
<h4 class="my-0 font-weight-normal">Register Form</h4>
</div>
<div class="card-body">
<form class="register-form">
<div class="form-group">
<label for="InputEmail">Email address</label>
<input type="email" class="form-control" name="email" id="InputEmail" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="InputPassword">Password</label>
<input type="password" name="password" class="form-control" id="InputPassword" placeholder="Password">
</div>
<div class="form-group">
<label for="InputPassword">Repeat Password</label>
<input type="password" name="password2" class="form-control" id="InputPasswordConfirm" placeholder="Repeat Password">
</div>
<button type="submit" class="btn btn-primary">Register</button>
<span>or Login</span>
</form>
</div>
</div>
{{/if}}
</template>
That's my JS file where I manage the entire events of login/registration system:
Template.login.events({
'click .register-link': function() {
$('#panel-login').hide();
$('#panel-register').show().addClass("animated fadeIn");
},
'click .login-link': function() {
$('#panel-register').hide();
$('#panel-login').show().addClass("animated fadeIn");
},
// Registration
'submit .register-form': function(event) {
var email = trimInput(event.target.email.value);
var password = trimInput(event.target.password.value);
var password2 = trimInput(event.target.password2.value);
if(isNotEmpty(email) && isNotEmpty(password) && isNotEmpty(password2)
&& isEmail(email) && areValidPasswords(password,password2)) {
Accounts.createUser({
email: email,
password: password,
profile: {
userType: 'Normal'
}
}, function(err) {
if(err) {
sAlert.error("There was an error with the registration, try again!");
} else {
sAlert.success("Account Created! You are now logged in");
}
});
}
// Prevent Submit
return false;
},
// Login
'submit .login-form': function(event) {
var email = event.target.email.value;
var password = event.target.password.value;
Meteor.loginWithPassword(email, password, function(err) {
if(err) {
event.target.email.value = email;
event.target.password.value = password;
sAlert.error("There is an error with your login, try again!");
} else {
sAlert.success("You are now logged in!");
}
})
// Prevent Submit
return false;
}
});
Template.login.helpers({
ifLogged: function(user) {
if(user != null) {
$('#panel-login').hide();
}
}
});
// Trim the input
var trimInput = function(val) {
return val.replace(/^\s*|\s*$/g, "");
};
// Check for empty fields
isNotEmpty = function(value) {
if(value && value !== "") {
return true;
}
sAlert.error('Please fill all the fields');
return false;
};
// Validating Email
isEmail = function(value) {
var filter = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if(filter.test(value)) {
return true;
}
sAlert.error("Invalid email, please use a valid email address");
return false;
};
// Check passwords fields
isValidPassword = function(password) {
if(password.length < 6) {
sAlert.error("Password must be at least 6 characters");
return false;
}
return true;
}
// Check confirmation password
areValidPasswords = function(password, confirm) {
if(!isValidPassword(password)) {
return false;
}
if(password !== confirm) {
sAlert.error("Password do not match");
return false;
}
return true;
};
Here there's a GIF to show you the problem:
https://i.gyazo.com/120efc183793d4d1adc5fb518e01c09c.mp4
Thanks if someone can help me.

If you just wanna to git rid of that flick then you can implement loading on Meteor.loggingIn as sample below, alter it with your use case i.e wrap it in a template Helper and replace that helper with currentUser
if (Meteor.loggingIn()) {
return 'loading';
} else if (Meteor.user()) {
return 'home';
} else {
return 'signin';
}

Related

JavaScript form validation not working as intended

Good morning,
I'm working on some simple form validation. Whenever I submit my form, the error message appears, but I can repeatedly spam the button for numerous error messages. Is there a way I can change this to only show the error message once? I've also noticed that even if I populate both fields it will still flash quickly in my console with the error log but not show the error.
Can anyone tell me what I'm doing wrong here?
var uname = document.forms['signIn']['userame'].value;
var pword = document.forms['signIn']['password'].value;
function validateMe (e) {
if (uname.length || pword.length < 1 || '') {
var container = document.getElementById('error-container');
var errorMsg = document.createElement('div');
errorMsg.className = 'error-message';
errorMsg.innerHTML = '<span class="heading-large">Please enter a valid username or password</span>';
container.appendChild(errorMsg);
console.log('An error occured');
return false;
}
}
<form id="signIn" action='#'>
<div class="boxed left-floater">
<h1 class="heading-large margin-top">Sign in</h1>
<div id="error-container"></div>
<div class="form-group">
<label class="form-label-bold" for="username">Username</label>
<input class="form-control log-in-form-control" id="username" name="username" type="text">
</div>
<div class="form-group">
<label class="form-label-bold" for="password">Password</label>
<input class="form-control log-in-form-control" id="password" type="password" name="password">
</div>
<div>
<a class="right-floater forgotten-password" href="forgottenpassword.html">Forgotten Password</a>
<button class="button clear right-floater" type="submit" onclick="validateMe();">Sign In</button>
</div>
</div>
</form>
Fiddle
You must be clearing the contents of your container to avoid duplication of elements. Below are few things to note:
You were trying to get userame instead of username in your fiddle. May be spelling mistake.
Keep input type=submit instead of button
Pass the event to your validateMe function to prevent the default action of post.
Move the variables within the function to get the actual value all the time
function validateMe(e) {
e.preventDefault();
var uname = document.forms['signIn']['username'].value;
var pword = document.forms['signIn']['password'].value;
var container = document.getElementById('error-container');
container.innerHTML = ''; //Clear the contents instead of repeating it
if (uname.length < 1 || pword.length < 1) {
var errorMsg = document.createElement('div');
errorMsg.className = 'error-message';
errorMsg.innerHTML = '<span class="heading-large">Please enter a valid username or password</span>';
container.appendChild(errorMsg);
console.log('An error occured');
return false;
}
}
<form id="signIn" action='#'>
<div class="boxed left-floater">
<h1 class="heading-large margin-top">Sign in</h1>
<div id="error-container"></div>
<div class="form-group">
<label class="form-label-bold" for="username">Username</label>
<input class="form-control log-in-form-control" id="username" name="username" type="text">
</div>
<div class="form-group">
<label class="form-label-bold" for="password">Password</label>
<input class="form-control log-in-form-control" id="password" type="password" name="password">
</div>
<div>
<a class="right-floater forgotten-password" href="forgottenpassword.html">Forgotten Password</a>
<input value="Sign In" class="button clear right-floater" type="submit" onclick="validateMe(event);" />
</div>
</div>
</form>
Updated Fiddle
Edit - if condition was failing and have updated it accordingly
this is full work code
var uname = "";
var pword = "";
function validateMe(e) {
e.preventDefault();
uname = document.forms['signIn']['username'].value;
pword = document.forms['signIn']['password'].value;
if (uname.length || pword.length < 1 || '') {
var container = document.getElementById('error-container');
var errorMsg = document.createElement('div');
errorMsg.className = 'error-message';
errorMsg.innerHTML = '<span class="heading-large">Please enter a valid username or password</span>';
container.appendChild(errorMsg);
console.log('An error occured');
return false;
}
return true;
}
<form id="signIn">
<div class="boxed left-floater">
<h1 class="heading-large margin-top">Sign in</h1>
<div id="error-container"></div>
<div class="form-group">
<label class="form-label-bold" for="username">Username</label>
<input class="form-control log-in-form-control" id="username" name="username" type="text">
</div>
<div class="form-group">
<label class="form-label-bold" for="password">Password</label>
<input class="form-control log-in-form-control" id="password" type="password" name="password">
</div>
<div>
<a class="right-floater forgotten-password" href="forgottenpassword.html">Forgotten Password</a>
<button class="button clear right-floater" type="submit" onclick="validateMe(event);">Sign In</button>
</div>
</div>
</form>

Bootstrap login with javascript

I'm new to Javascript and I need to validate a log-in form with Bootstrap, the thing is not validating the password in the script.
https://jsfiddle.net/98uqsvu2/
<script type="text/javascript">
function check_info()
{
var user = document.getElementById("inputEmail").value;
var pass = document.getElementById("inputPassword").value;
if(user == "test#gmail.com")
{
if(pass == "123")
{
return true;
}
}
else
{
return false;
}
}
</script>
git: https://gist.github.com/Adaryn/6c38cfafd5e95d8a0bba508a33cebec7
#Adaryn
Since I cannot comment, I posted it as an answer.
I made the following changes to the fiddle and I was able to execute the code.
Removed the link href's from your HTML.
Added the closing body tag.
Moved the script from the javascript code section and pasted it just above the closing body tag.
Here is the updated fiddle.
<div class="container">
<form class="form-signin" form role="form" action="hola.html" name="formlogin" method="post" class="login-form" onsubmit="check_info()">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required="">
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
<script type="text/javascript">
function check_info()
{
var user = document.getElementById("inputEmail").value;
var pass = document.getElementById("inputPassword").value;
if(user == "test#gmail.com")
{
if(pass == "123")
{
return true;
}
}
else
{
return false;
}
}
</script>
try this code. also added jsfiddle
document.getElementById("submit-form").addEventListener("click", check_info);
function check_info() {
var user = document.getElementById("inputEmail").value;
var pass = document.getElementById("inputPassword").value;
if (user == "test#gmail.com" && pass == "123") {
alert("email and password is valid!!!");
return true;
} else {
alert("email and password is NOT valid!!!");
return false;
}
}
https://jsfiddle.net/damaxrss/

How to use $asyncValidators with angularjs and set a warning message in the HTML

This is my first bigger form with validations and etc.
I've created a Registration form and I'm using ng-messages for validation. The problem is that I need to validate the username, does it already exist in the JSON server that we are using or it's available. Of course, if it's taken the warning pops out in the HTML where the username input is, if it's available the submit button is no more disabled (because the form will be $valid) and the user can register. I want to use angular-sanitize because I found this (I don't know if they are related):
ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
var value = modelValue || viewValue;
// Lookup user by username
return $http.get('/api/users/' + value).
then(function resolved() {
//username exists, this means validation fails
return $q.reject('exists');
}, function rejected() {
//username does not exist, therefore this validation passes
return true;
});
};
Here is the code I use now (reg form, controller and service):
// Controller:
export default class registerPageController {
constructor(userService, authenticationService, $location) {
this.register = "Register";
this.userService = userService;
this.$location = $location;
this.authenticationService = authenticationService;
this.hasLoggedIn = false;
}
onSubmit(user) {
let self = this;
let {
name,
age,
email,
username,
password
} = user;
self.userService.register(name, age, email, username, password).then((res) => {
self.userService.login(username, password).then(function (response) {
let data = response.data;
if (data.length) {
let user = data[0];
self.hasLoggedIn = true;
self.authenticationService.setCredentials(username, password);
self.$location.path('/');
}
});
})
.catch(err => {
// WHAT TO PUT HERE AFTER THE USERNAME EXIST VALIDATION ?
})
}
}
// Service:
export class UserService {
constructor($http) {
this.$http = $http;
}
login(username, password) {
return this.$http({
method: 'GET',
url: 'http://localhost:3000/users',
params: {
username: username,
password: password
}
});
}
register(name, age, email, username, password) {
return this.$http({
method: 'POST',
url: 'http://localhost:3000/users',
data: {
name: name,
age: age,
email: email,
username: username,
password: password
}
});
}
// SHOULD I PUT HERE THE USERNAME EXIST VALIDATION LOGIC ?
}
<div class="container main-content">
<form class="registrationForm" name="registerForm" ng-submit="register.onSubmit(register.user)" novalidate="novalidate">
<!-- Enter Name -->
<div class="form-group">
<label for="name" class="control-label"><span id="reqInfo">*</span> Name</label>
<input type="text" name="name" class="form-control" ng-model="register.user.name" ng-pattern="/[a-zA-Zа-яА-Я]+/" id="name"
required="" placeholder="Example: Petar Petrov">
<div ng-messages="registerForm.name.$error" ng-show="registerForm.name.$touched" style="color:maroon" role="alert">
<div ng-message="required">Your name is required</div>
</div>
</div>
<!-- User Age-->
<div class="form-group">
<label for="age" class="control-label"><span id="reqInfo">*</span> Age</label>
<input type="number" name="age" class="form-control" ng-model="register.user.age" ng-min="18" min="18" id="age" required=""
placeholder="Enter your age">
<div ng-messages="registerForm.age.$error" ng-show="registerForm.age.$touched" style="color:maroon" role="alert">
<div ng-message="min">You must be at leats 18 years old</div>
</div>
</div>
<!-- Enter E-mail -->
<div class="form-group">
<label for="email" class="control-label"><span id="reqInfo">*</span> E-mail</label>
<input type="email" name="email" class="form-control" ng-model="register.user.email" ng-pattern="/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+#)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+#)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%#\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/"
id="email" required="" placeholder="Example: mail#mail.net">
<div ng-messages="registerForm.email.$error" ng-show="registerForm.email.$touched" style="color:maroon" role="alert">
<div ng-message="required">Your valid e-mail is required</div>
</div>
<br>
<!-- Enter Username -->
<div class="form-group">
<label for="username" class="control-label"><span id="reqInfo">*</span> Username</label>
<input type="text" name="username" ng-minlength="5" ng-maxlength="20" class="form-control" ng-model="register.user.username"
ng-pattern="/^[A-Za-z0-9_]{1,32}$/" ng-minlength="7" id="username" required="" placeholder="Enter your username">
<div ng-messages="registerForm.username.$error" style="color:maroon" role="alert">
<div ng-message="minlength">Your Username must be between 7 and 20 characters long</div>
</div>
<br>
<!-- Enter Password -->
<div class="form-group">
<label for="password" class="control-label"><span id="reqInfo">*</span> Password</label>
<input type="password" name="password" class="form-control" ng-model="register.user.password" ng-minlength="7" id="password"
required="" placeholder="Enter your password">
<div ng-messages="registerForm.password.$error" style="color:maroon" role="alert">
<div ng-message="minlength">You Password must be at least 7 symbols long</div>
</div>
</div>
<!-- Register button -->
<div class="form-group">
<button class="btn btn-primary" type="submit" ng-disabled="!registerForm.name.$valid || !registerForm.age.$valid || !registerForm.email.$valid || !registerForm.username.$valid || !registerForm.password.$valid">Register</button>
</div>
<p>Fields with <span id="reqInfo">*</span> must be filled.</p>
</form>
</div>
Important is to know that I have being told explicitly to write it in ES6.
I have problem with the logic so look at my code and please fill it for me so I can use it and most important - learn it :S
Thank you so so much in advance!
I have implemented a directive for different kind of validations (sync Async), and it supports warning as well.
You may check it from
`https://plnkr.co/2WQHOo`
If this is what you needed and need more information, let me know I will try my best to answer.

Angular validations: Restrict server request if user enters invalid email or password

<form name="LPform" novalidate>
<div class="form-row clearfix">
<label class="lbl-fld" style="margin-left: 12%;width:20%;">Email ID</label>
<input class="mob-adj-inpbx " type="email" name="uemail" ng-model="useremail" placeholder=" me#example.com" ng-required="true"/>
<div class="valid-chk validation-loginpopup" ng-show="LPform.uemail.$dirty && allow_Invalid">
<i style="font-size: 1.15em;padding:0px;" ng-class="{'false':'icon-close', 'true': 'icon-correct'}[LPform.uemail.$valid]" class="icon-correct"></i>
</div>
<div class="error-prompt" ng-show="LPform.uemail.$dirty && allow_Invalid">
</div>
</div>
<div class="form-row clearfix">
<label class="lbl-fld" style="margin-left: 12%;width:20%;">PASSWORD</label>
<input class="mob-adj-inpbx" type="password" name="upassword" ng-model="userpassword" placeholder=" password" ng-required="true"/>
<div class="valid-chk validation-loginpopup" ng-show="LPform.upassword.$dirty && allow_Invalid">
<i style="font-size: 1.15em;padding:0px;" ng-class="{'false':'icon-close', 'true': 'icon-correct'}[LPform.upassword.$valid]" class="icon-correct"></i>
</div>
<div class="error-prompt" ng-show="LPform.upassword.$dirty && allow_Invalid">
</div>
</div>
<div id="server_message" class="form-row clearfix basic-error-msg-loginpopup" ng-show="server_message">
{{server_message}}
</div>
<div class="btn-container clearfix mobile-adj" style="margin-left:17.2%;">
<div class="btn-wrap btn-loginpopup">
<input style="max-height:40px;width:121%;" type="submit" name="commit" value="LOGIN" ng-click="login_request()"/>
</div>
</div>
</form>
This part is displayed to the user and the inputs are validated using angular validations. All validations are working fine.
$scope.login_request = function(){
if(LPform.useremail.$valid && LPform.userpassword.$valid) {
$scope.allow_Invalid = "true";
$http({
method: 'POST',
url: '/users/home_login',
data: {email: $scope.useremail, password: $scope.userpassword}
}).success(function (response) {
console.log(response);
window.location = response.location;
}).error(function (response) {
console.log(response);
$scope.server_message = response.server_message;
});
}
else if(!LPform.useremail.$valid) {
$scope.allow_Invalid = "true";
$scope.server_message = "Please enter valid email.";
}
else if(!LPform.userpassword.$valid) {
$scope.allow_Invalid = "true";
$scope.server_message = "Please enter valid password.";
}
else{
$scope.allow_Invalid = "true";
$scope.server_message = "Request Failed.";
}
};
This part is in javascript file where I want to use the validations to decide whether to send a request to the server or not. The conditions I have used in the if else clause is not working, which I randomly tried btw. I am aware that I can disable Login button, however, I don't want to implement this that way.
I believe your problem is that the form name is bound to $scope and isn't a global variable.
In controller change
LPform
To
$scope.LPform

Display error message depending on if user is disabled or if input is invalid using JS/HTML

I want to display an error message under the 'Email Address' input if the user is disabled and display a separate error message if the user is invalid under the 'Password' input. When debugging I found that if a user is disabled the "Status code is 503" and if the input is invalid the "Status code is 400".
HTML
<md-content id="login" layout="column" layout-align="center center" class="inputdemoErrors">
<div flex="25"></div>
<p class="m0">project</p>
<form id="loginForm">
<md-input-container>
<label for="username">Email Address</label>
</md-input-container>
<md-input-container class="email-field">
<input name="username" id="username" type="email" class="validate" ng-model="username" enter-key="submitLogin()" autocomplete="off" required>
<div ng-show="disabled" ng-messages="loginForm.username.$error" role="alert">
<div ng-message="required">User Account is Disabled</div>
</div>
</md-input-container>
<md-input-container>
<label for="password">Password</label>
</md-input-container>
<md-input-container class="password-field">
<input name="password" id="password" type="password" class="validate" ng-model="password" enter-key="submitLogin()" autocomplete="off" required>
<div ng-show="invalid" ng-messages="loginForm.password.$error" role="alert">
<div ng-message="required">Invalid Email or Password</div>
</div>
</md-input-container>
<a class="waves-effect waves-light btn-large" style="width: 100%; margin: 0; background-color: #29B6F6;" ng-click="submitLogin()">Login</a>
</form>
</md-content>
JS
angular
.module('login')
.controller('LoginCtrl', LoginCtrl);
function LoginCtrl($scope, $location, SecService, RecService, Service) {
var vm = this;
vm.ctrlName = 'LoginCtrl';
$scope.submitLogin = function() {
$scope.invalid = $scope.loginForm.$invalid;
if($scope.invalid) {
return;
}
else
$scope.dataLoading = true;
var creds = {
username: $scope.username,
password: $scope.password
};
SecService.login(creds).then(function (response) {
if (response.success) {
RecService.connect();
SecService.setCredentials($scope.username, $scope.password);
Service.loadCurrentUser();
$location.path('/main');
}
if (response = 503)
{
$scope.disabled = $scope.loginForm.$disabled;
if ($scope.invalid) return invalid;
}
if (response = 400)
{
$scope.invalid = $scope.loginForm.$invalid;
if ($scope.invalid) return invalid;
}
});
};
}
}());
I am trying to display "User Account is Disabled" if the user is disabled (503), and "Email or Password is Invalid" if they have an invalid input (400). This should happen when the login button is clicked.
Hard to give a good answer without knowing what functionality you want with the ng-messages.
If you omit ng-messages:
<div ng-show="showDisabled">
User Account is Disabled
</div>
<div ng-show="showInvalid">
Invalid Email or Password
</div>
The following doesn't look right, so remove it for now:
if (response = 503)
{
$scope.disabled = $scope.loginForm.$disabled;
if ($scope.invalid) return invalid;
}
if (response = 400)
{
$scope.invalid = $scope.loginForm.$invalid;
if ($scope.invalid) return invalid;
}
It doesn't look like the return values are used anywhere and it should be response === x, not response = x.
Replace with:
$scope.showDisabled = response === 503;
$scope.showInvalid = response === 400;
Another note, if you need to access the form like this:
ng-messages="loginForm.password.$error"
The form needs a name:
<form name="loginForm">
Instead of id:
<form id="loginForm">

Categories