Skip to content

Instantly share code, notes, and snippets.

@zikozee
Forked from Coder-ACJHP/ErrorMessage.java
Created July 31, 2020 11:16
Show Gist options
  • Save zikozee/fd8cf731f1e020488545eb21db781265 to your computer and use it in GitHub Desktop.
Save zikozee/fd8cf731f1e020488545eb21db781265 to your computer and use it in GitHub Desktop.
How to use Bootstrap Modal login form with Spring MVC (included form validation) & Ajax.
public class ErrorMessage {
private String fieldName;
private String message;
public ErrorMessage(String fieldName, String message) {
this.fieldName = fieldName;
this.message = message;
}
//Getters and setters
//Constructors with fields etc.
<!DOCTYPE html>
<html>
<head>
<!-- BOOTSTRAP DEPENDENCIES -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/bootstrap-theme.min.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"></script>
<!-- BOOTSTRAP DEPENDENCIES END-->
</head>
<body>
<!-- INCLUDE SEPERATE MODAL PAGE TO THIS PAGE -->
<jsp:include page="login-modal.jsp" />
<!-- TRIGGER THE MODAL WITH THIS FUNCTION (function located in 'login-modal.jsp') -->
<a class="href-link" onclick="openModal();">Login with Bootstrap modal</a>
</body>
</html>
<!-- INCLUDE YOUR OWN CSS CLASS -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/login-modal.css">
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content" style="width: 450px;">
<div class="modal-header">
<img src="${pageContext.request.contextPath}/resources/images/miniLogo.png" width="50" height="50"><label style="font-size: 1.5em;">You already a member?</label>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-12">
<div class="input-group" style="height:40px;">
<span class="input-group-addon">@</span>
<input type="email" name="Email" id="Email" class="form-control"
title="We'll never share your email with anyone else."
placeholder="Email address" required="required" style="height:40px;">
</div>
</div>
</div><br>
<div class="row">
<div class="col-sm-12">
<div class="input-group" style="height:40px;">
<span class="input-group-addon"><b>*</b></span>
<input type="password" name="Password" id="Password" class="form-control"
placeholder="Password" required="required" style="height:40px;">
</div>
</div>
</div><br>
<div class="row">
<div class="col-sm-12">
<button type="button" class="modal-outline" id="login">Login</button>
</div>
</div>
<div id="generalErrorMessage" class="error-lbl" style="display:none;"></div>
</div>
<div class="modal-footer" style="padding: 8px;">
<div class="col-lg-4">
<button type="button" class="modal-close" data-dismiss="modal">Close</button>
</div>
<div class="col-lg-3"></div>
<div class="col-lg-5">
<p></p><!-- Give some white spaces -->
<a href="${pageContext.request.contextPath}/ForgotPassword">
<font style="color:black; font-size:15px;">Forgot password ?</font>
</a>
</div>
</div>
</div>
</div>
</div>
//Modal trigger function.
<script type="text/javascript">
function openModal() {
$('#exampleModal').modal('show');
}
</script>
<!-- AJAX LOGIN (POST) -->
<script type="text/javascript">
$(document).ready(function() {
clearError();
$('#login').click(function(event) {
event.preventDefault();
var EMAIL = $("#Email").val();
var PASSWORD = $("#Password").val();
$.ajax({
type : "POST",
url : "ModalLogin",
data : "EMAIL=" + EMAIL + "&PASSWORD=" + PASSWORD,
success : function(response) {
if(response.status == 'FAIL') {
showFormError(response.errorMessageList);
} else {
//everything is O.K. user logged in successfully.
$('#exampleModal').modal('hide');
window.location.reload();
}
},
error : function(ex) {
console.log(ex);
}
});
});
var PasswordField = $('#Password');
var EmailField = $('#Email');
var GeneralErrorField = $('#generalErrorMessage');
function showFormError(errorVal) {
//show error messages that comming from backend and change border to red.
for(var i=0; i < errorVal.length; i++) {
if(errorVal[i].fieldName === 'EMAIL') {
clearForm();
EmailField.attr("placeholder", errorVal[i].message).css("border", " 1px solid red");
}
else if(errorVal[i].fieldName === 'PASSWORD'){
PasswordField.val('');
PasswordField.attr("placeholder", errorVal[i].message).css("border", " 1px solid red");
}
else if(errorVal[i].fieldName === 'FORM FAIL'){
clearForm();
GeneralErrorField.css("display", "block").html(errorVal[i].message);
}
}
}
//remove error warning tags and change tips
function clearError() {
//clear all and return it as default.
$('#Email').focus(function() {
clearForm();
EmailField.css("border", "1px solid lightgrey");
EmailField.attr("placeholder", "Email address");
});
$('#Password').focus(function() {
PasswordField.val('');
PasswordField.css("border", "1px solid lightgrey");
PasswordField.attr("placeholder", "Password");
});
}
//clear fields and hide error tag.
function clearForm() {
EmailField.val('');
PasswordField.val('');
GeneralErrorField.css("display", "none");
}
});
</script>
@Controller
public class MainSpringController {
@Autowired
private CommunityService communityService;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@PostMapping(value="ModalLogin")
public @ResponseBody ValidationResponse loginViaAjax(Model model,
@ModelAttribute(value="user") @Valid Users user,
BindingResult result, HttpServletRequest request) {
//Special class created for JSON response
ValidationResponse res = new ValidationResponse();
if(result.hasErrors()){
res.setStatus("FAIL");
List<FieldError> allErrors = result.getFieldErrors();
final List<ErrorMessage> errorMesages = new ArrayList<ErrorMessage>();
for (FieldError objectError : allErrors) {
errorMesages.add(new ErrorMessage(objectError.getField(), objectError.getDefaultMessage()));
}
res.setErrorMessageList(errorMesages);
} else {
//There is no binding errors, fetch user from database if exist.
Optional<Users> theUser = communityService.findUserByEmailOptional(user.getEMAIL());
final List<ErrorMessage> errorMessagelist = new ArrayList<>();
if(theUser.isPresent()) {
//User is exist, compare the passwords are equals?
if(passwordEncoder.matches(user.getPASSWORD(), theUser.get().getPASSWORD())) {
uploadUserAttributesToSession(theUser, request);
res.setStatus("SUCCESS");
} else {
res.setStatus("FAIL");
errorMessagelist.add(new ErrorMessage("PASSWORD", "Invalid password!"));
}
//In this part user doesn't exist send error to frontend.
} else {
res.setStatus("FAIL");
errorMessagelist.add(new ErrorMessage("FORM FAIL", "Incorrect Email or Password!"));
}
//Everything is O.K. and all odds controlled
//if there any error add it to errorlist and send it.
res.setErrorMessageList(errorMessagelist);
}
return res;
}
public class Users {
@Email(regexp="^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$", message="Invalid email!")
@NotEmpty(message="Email cannot be empty!")
private String EMAIL;
@NotEmpty(message="Password cannot be empty!")
private String PASSWORD;
public Users(){}
//Getters and setters
//Constructors with fields etc.
package com.community.web.util;
import java.util.List;
public class ValidationResponse {
private String status;
private List<ErrorMessage> errorMessageList;
//Getters and setters
//Constructors with fields etc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment