I'm new in Grails. I would like to use custom validator for matching two passwords during registration in my application. Unfortunetly doesn't work it.
Account.groovy
#Validateable
class Account {
String login
String password
String confirm
String passwordHashed
char active
static transients = ['password', 'confirm']
static belongsTo = Employee
static hasMany = [role:Role]
static constraints = {
login unique:true, blank: false
active nullable: true
password blank: false, size: 5..15, validator:{ val, obj ->
if(obj.password != obj.confirm ){
return ['dontmatch']
}
}
}
static mapping = {
id generator: 'increment'
}
}
AuthenticationController.groovy
class AuthenticationController {
def signUp(Account accountInstance){
if(accountInstance!= null){
if (accountInstance.hasErrors()) {
respond accountInstance.errors, view:'signUp'
return
}
else{
accountInstance.save(flush: true)
}
}
}
}
signUp.gsp
<%# page import="com.sarna.entity.Account"%>
<%# page import="com.sarna.entity.Employee"%>
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="bootstrap-main" />
<title>SARNA</title>
</head>
<body>
<br />
<div class="container">
<div style="margin-top: 50px"
class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Sign Up</div>
<div
style="float: right; font-size: 85%; position: relative; top: -10px">
<a id="signinlink"
href="${createLink(uri: '/authentication/signIn') }">Sign In</a>
</div>
</div>
<div class="panel-body">
<g:form class="form-horizontal" role="form"
url="[resource: accountInstance]"
method="POST" controller="Authentication">
<g:hasErrors bean="${accountInstance}">
<div class="alert alert-danger">
<g:renderErrors bean="${accountInstance}" />
</div>
</g:hasErrors>
<div class="form-group">
<label for="email" class="col-md-3 control-label">Email</label>
<div class="col-md-9">
<input type="text" class="form-control" name="email"
placeholder="Email Address">
</div>
</div>
<div class="form-group">
<label for="icode" class="col-md-3 control-label">Login</label>
<div class="col-md-9">
<g:textField type="text" class="form-control" name="login"
required="" value="${accountInstance?.login }"
placeholder="Login" />
</div>
</div>
<div class="form-group">
<label for="password" class="col-md-3 control-label">Password</label>
<div class="col-md-9">
<g:passwordField name="password"
class="form-control ${hasErrors(bean:accountInstance,field:'password','errors')}"
placeholder="Password" />
</div>
</div>
<div class="form-group">
<label for="icode" class="col-md-3 control-label">Confirm</label>
<div class="col-md-9">
<g:passwordField
class="form-control ${hasErrors(bean:accountInstance,field:'password','errors')}"
name="confirm" placeholder="Confirm Password" />
</div>
</div>
<div class="form-group">
<!-- Button -->
<div class="col-md-offset-3 col-md-9">
<g:actionSubmit action="signUp"
class="btn btn-lg btn-success btn-block" value="Sign Up" />
</div>
</div>
</g:form>
</div>
</div>
</div>
</div>
</body>
</html>
messages.properties
account.password.dontmatch=Podane hasła muszą się zgadzać
I don't understand it. I enter two different passwords and I click signUp button, I don't see errors messages which should be display when validation failed. Could you help me?
The call of validate() is missing:
if (!accountInstance.validate() || accountInstance.hasErrors()) {
...
}
Match the actual value from the validator with the confirm property from the actual object.
password blank: false, size: 5..15, validator:{ val, obj ->
if( obj.confirm && val != obj.confirm ) { // val is password
return ['dontmatch']
}
}
I think instead of the respond in the controller you want
render (view: "signUp", model: [accountInstance: accountInstance])
Your view expects an accountInstance object in the view model to render the errors, so you have to provide it.
You can also just do
return [accountInstance: accountInstance]
If there is a gsp that has the same name as the current action grails will automatically render it.
Related
I'm working on a use case in my animal shelter web application where customers are able to register one or more animals at the same time. Ideally I'd like a button on the bottom left that generates another instance of the same form when clicked, so that multiple animal registrations can be saved to the database at once.
NewAnimalRegistration.cshtml:
#model NewAnimalRegistrationViewModel
<html>
<head>
<title>Register an animal</title>
<link rel="stylesheet" href="~/css/style.css"/>
</head>
<body>
<div class="container py-5">
<div class=" row">
<div class="col-md-10" mx-auto>
<div asp-validation-summary="All"></div>
<h1>Animal registration</h1>
<p>
We are happy to hear that you are interested in placing your animal in our shelter. Please fill in the fields below and our system will
check if there is room for your animal.
</p>
<form asp-action="RegistrationForm" method="post">
<div class="form-group row mt-5">
<div class="col-sm-6">
<label asp-for="Name">Name</label>
<input asp-for="Name" class="form-control"/>
</div>
</div>
<div class="form-group row mt-5">
<div class="col-sm-4">
<label asp-for="Gender" class="mr-3">Gender</label>
<select class="form-group" asp-for="Gender" asp-items="#ViewBag.Genders"></select>
</div>
<div class="col-sm-4">
<label asp-for="Type" class="mr-3">Animal type</label>
<select class="form-group" asp-for="Type" asp-items="#ViewBag.AnimalTypes"></select>
</div>
<div class="col-sm-4">
<label>Neutered</label>
<div class="form-check">
<input asp-for="IsNeutered" class="form-check-input" type="radio" value="true">
<label class="form-check-label" asp-for="IsNeutered">
Yes
</label>
</div>
<div class="form-check">
<input asp-for="IsNeutered" class="form-check-input" type="radio" value="false">
<label class="form-check-label" asp-for="IsNeutered">
No
</label>
</div>
</div>
</div>
<div class="form-group mt-5">
<label asp-for="Reason">Why are you deciding to put this animal up for adoption?</label>
<textarea class="form-control" asp-for="Reason" rows="6"></textarea>
</div>
<div class="float-right">
<a asp-controller="Home" asp-action="Index" class="btn btn-primary px-4">Cancel</a>
<button class="btn btn-primary px-4">Save</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Is there a way to do this in .NET Core MVC? If yes, will I simply receive a list of all animal registrations through which I can simply loop and add them all to the database?
I made a demo based on your description, you can refer to it:
Model:
public class NewAnimalRegistrationViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string Type { get; set; }
public bool IsNeutered { get; set; }
public string Reason { get; set; }
}
Index.cshtml:
#model NewAnimalRegistrationViewModel
<html>
<head>
<title>Register an animal</title>
</head>
<body>
<div class="container py-5">
<div class=" row">
<div class="col-md-10" mx-auto>
<div asp-validation-summary="All"></div>
<h1>Animal registration</h1>
<p>
We are happy to hear that you are interested in placing your animal in our shelter. Please fill in the fields below and our system will
check if there is room for your animal.
</p>
<form asp-action="RegistrationForm" method="post">
<div class="float-right">
<a asp-controller="Home" asp-action="Index" class="btn btn-primary px-4">Cancel</a>
<button class="btn btn-primary px-4">Save</button>
</div>
</form>
<a id="add" href='#' class="text-danger">register another animal</a>
</div>
</div>
</div>
</body>
</html>
#section scripts{
<script>
var count = 0;
$(function () {
var actionUrl = "/Home/AddRegistrationForm?count=" + count;
$.get(actionUrl).done(function (data) {
$('body').find('.float-right').before(data);
});
})
$("#add").on("click", function (e) {
e.preventDefault();
count++;
var actionUrl = "/Home/AddRegistrationForm?count=" + count;
$.get(actionUrl).done(function (data) {
$('body').find('.float-right').before(data);
});
})
</script>
}
_RegisterPartial.cshtml:
#model NewAnimalRegistrationViewModel
#{
int i = ViewBag.Count;
}
<h3>Anaimal #i</h3>
<div class="form-group row mt-5">
<div class="col-sm-6">
<label asp-for="Name">Name</label>
<input asp-for="Name" name="[#i].Name" class="form-control" />
</div>
</div>
<div class="form-group row mt-5">
<div class="col-sm-4">
<label asp-for="Gender" class="mr-3">Gender</label>
<select class="form-group" asp-for="Gender" name="[#i].Gender" asp-items="#ViewBag.Genders"></select>
</div>
<div class="col-sm-4">
<label asp-for="Type" class="mr-3">Animal type</label>
<select class="form-group" asp-for="Type" name="[#i].Type" asp-items="#ViewBag.AnimalTypes"></select>
</div>
<div class="col-sm-4">
<label>Neutered</label>
<div class="form-check">
<input asp-for="IsNeutered" name="[#i].IsNeutered" class="form-check-input" type="radio" value="true">
<label class="form-check-label" asp-for="IsNeutered">
Yes
</label>
</div>
<div class="form-check">
<input asp-for="IsNeutered" name="[#i].IsNeutered" class="form-check-input" type="radio" value="false">
<label class="form-check-label" asp-for="IsNeutered">
No
</label>
</div>
</div>
</div>
<div class="form-group mt-5">
<label asp-for="Reason">Why are you deciding to put this animal up for adoption?</label>
<textarea class="form-control" asp-for="Reason" name="[#i].Reason" rows="6"></textarea>
</div>
Controller:
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult AddRegistrationForm(int count)
{
ViewBag.Count = count;
ViewBag.Genders = new List<SelectListItem>
{
new SelectListItem{ Text = "Female", Value="Female"},
new SelectListItem{ Text = "Male", Value="Male"}
};
ViewBag.AnimalTypes = new List<SelectListItem>
{
new SelectListItem{ Text = "Cat", Value="Cat"},
new SelectListItem{ Text = "Dog", Value="Dog"}
};
return PartialView("_RegisterPartial");
}
[HttpPost]
public IActionResult RegistrationForm(List<NewAnimalRegistrationViewModel> model)
{
return View();
}
Result:
I am trying to get values of form inputs on action method.
MVC View
#using (Html.BeginForm("Report", "Home"))
{
<div class="common_input Volunteer_input">
<div class="row">
<div class="col-sm-12">
<label for="firstName">Reporter:</label>
<div class="select_option_one">
<input type="text" id="ReporterCountries" class="ct-select2 ReporterCountriesList" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<label for="firstName">Partner:</label>
<div class="select_option_one">
<input type="text" name="PartnersCountries" id="PartnersCountries" class="ct-select2 CountryList" />
</div>
</div>
</div>
<h3>Comparators</h3>
<div class="row">
<div class="col-sm-12">
<label for="firstName">Partner:</label>
<div class="select_option_one">
<input type="text" name="CompareCountryList" id="CompareCountryList" class="ct-select2 CountryList" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<label for="firstName">Rank Growth:</label>
<div class="select_option_one">
<input type="text" name="RankGrowth" id="RankGrowth" class="ct-select2 RankGrowth" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="sub_submit">
<button type="submit" class="common_btn hvr-sweep-to-bottom">View<i class="fa fa-long-arrow-right"></i></button>
</div>
</div>
</div>
</div>
}
Action Method for Home Controller
public ActionResult Report(FormCollection form)
{
ViewData["ReporterCountries"] = Request.Form["ReporterCountries"];;
return RedirectToAction("Index","data");
}
When I try to retrieve the values of input on action controller I am receving all the control on the view but values are coming as null.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
Below is my partial view call:
<div id="div-reviewgrid">
#Html.Partial("_ReviewList", ViewBag.RewiewLists as List<Pollit.Data.Review>)
</div>
this is my partial view inside shared folder under Partial:
#using Pollit.Data;
#{
List<Review> reviewList = ViewBag.RewiewLists;
}
<br /><br />
#if (reviewList != null)
{
foreach (var review in reviewList)
{
<div class="col-lg-12">
<div id="#review.Id">
<div class="col-lg-1 col-md-1 col-xs-12 col-sm-12">
#if (review.Rating != null)
{
<img src="/images/ratings/#review.Rating.Number-bars.png" class="pull-left" style="max-height: 50px; max-width: 50px; margin-left: 30px" />
}
</div>
<div class="col-lg-11 col-md-11 col-xs-12 col-sm-12">
<span>#review.Creator.Name #String.Format("{0:d}", review.Created)</span>
<br />
<h4 class="custum-memphisfontmediumitalic ">#review.Content</h4>
#*<input type="submit" value="Like" class="btn btn-info" />
<input type="submit" id="click" value="Comment" class="btn btn-info" />
<input type="text" id="comment" placeholder="Enter your comment" class="form-control" />*#
</div>
</div>
<br />
#if (Request.IsAuthenticated == true)
{
if (review.Replys != null)
{
foreach (var reply in review.Replys.OrderBy(c => c.Created))
{
<div id="reply_#reply.ReplyID" class="col-lg-8 col-md-10 col-xs-12 col-sm-12 col-lg-offset-1 ">
<span>Reply By:#reply.Creator.Name #String.Format("{0:d}", #reply.Created)</span>
<br />
<h4 class="custum-memphisfontmediumitalic">#reply.ReplyContent</h4>
</div>
}
}
<div class="col-lg-8 col-md-10 col-xs-12 col-sm-12 col-lg-offset-1 form-group ">
<input type="text" id="txtReply_#review.Id" placeholder="Enter your reply" class="form-control" />
</div>
<div class="col-lg-2 form-group"><div class="demo">
Reply
<img src="/Images/Comment rate up.png" class="img-responsive" width="40px" ><img src="/Images/Comment rate down.png" class="img-responsive" width="40px" ></div>
</div>
}
</div>
}
}
<br /><br />
Above is my partial view code so guys let me know if I am doing something wrong. Please help me. Thanks in advance for help
when you are calling your partial view the way you have written its wrong. each time you call it the new model is generating and your model goes empty`
#Html.Partial("_ReviewList", ViewBag.RewiewLists as List<Pollit.Data.Review>)
write Model instead of ViewBag.RewiewLists as List<Pollit.Data.Review>
I was trying to make a signup page, which takes the username and password as from the user and stores it in my database, but the problem here is, the data is not going to the database only
you can see the image here
[https://drive.google.com/file/d/0B9gjSzsLSnClR1VvU0RUa3liRWs/view?usp=sharing][1]
save method look likes this
#Transactional
def save(){
if(params == null){
redirect(action:"index")
flash.message=''
return
}
def employee = findByUsername(params.username);
System.out.println(employee.username);
if(employee!=null){
flash.message="username already exist"
render(view:"signup")
}
else{
def newEmp = new Employee();
newEmp.username=params.username
newEmp.password=params.password
if(newEmp.save(flush:true)){
flash.message="Employee created"
render(view:"index")
}
else{
flash.message="Please enter valid data"
render(view:"signup")
}
if(newEmp.save(flush:true)) {
flash.message = "User Created. Please Login"
render(view:"index")
} else {
flash.message = "Please enter valid data";
render(view:"signup")
}
}
}
View page look like this
<form id="signupform" action="./save" method="POST" class="form-horizontal" role="form">
<g:if test="${flash.message}">
<div class="alert alert-danger" role="alert">${flash.message}</div>
</g:if>
<div class="form-group">
<label for="username" class="col-md-3 control-label">Username</label>
<div class="col-md-9">
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
</div>
<div class="form-group">
<label for="password" class="col-md-3 control-label">Password</label>
<div class="col-md-9">
<input type="password" class="form-control" name="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<!-- Button -->
<div class="col-md-offset-3 col-md-9 text-center">
<button id="btn-signup" type="submit" class="btn btn-info"><i class="icon-hand-right"></i>Sign Up</button>
</div>
</div>
</form>
Replace this:
def employee = findByUsername(params.username);
with:
def employee = Employee.findByUsername(params.username);
All dynamic finder methods must be called statically on the type you expect them to return
I've created this elements form:
<div class = "ui-grid-a">
<div class= "ui-block-a">
<div data-role="fieldcontain" class = "ui-hide-label">
<label for="birth-place">Birth Place</label>
<input type="text" name="birth-place" id="birth_place" value="" placeholder="Birth Place" />
</div>
</div>
<div class = "ui-block-b">
<div data-role = "fieldcontain" class="ui-hide-label">
<label for="province">Province</label>
<input type="text" name="province" id="province" value="" placeholder="PR" />
</div>
</div>
</div>
and I want to align the element province to the right. How can I do that?
Try this:
<span style="float:right"><label for="province">Province</label></span>
(of course you can put this also in a external css file)
Just do the following...
Apply this custom CSS to your code...
label[for="province"] { text-align:right; }
If it doesn't run they supply the label with a class name and do the following..
label.className { text-align:right; }
Apply a style of text-align:right;to the input field directly, as in this fiddle.
http://jsfiddle.net/den232/Fw2yA/
Good luck!
.floatright {
text-align:right;
}
<div data-role="page" class="type-home">
<div data-role="content">
<div class = "ui-grid-a">
<div class= "ui-block-a">
<div data-role="fieldcontain" class = "ui-hide-label">
<label for="birth-place">Birth Place</label>
<input type="text" name="birth-place" id="birth_place" value="" placeholder="Birth Place" class='floatright' />
</div>
</div>
<div class = "ui-block-b">
<div data-role = "fieldcontain" class="ui-hide-label">
<label for="province">Province</label>
<input type="text" name="province" id="province" value="" placeholder="PR" />
</div>
</div>
</div>
</div>
</div>