Render password value using f:field in Grails - grails

I’m using f:field in order to render a custom Cmd object.
class CustomCmd implements Validateable {
String user
String password
static constraints = {
user blank: false, email: true
password blank: false, password:true
}
}
Then in my gsp page I use
<fieldset class="form">
<f:with bean="${cmd}">
<f:field property="user"/>
<f:field property="password"/>
</f:with>
</fieldset>
The password is not shown on the page (with the standard **** bullets): the field has no value, but the user field is filled with the right value.
There is a way to fill the password field using f:field tag?

This seems to be the wanted behaviour:
https://github.com/grails-fields-plugin/grails-fields/issues/60
I'm not agree with the developers... BTW this is not a bug

Related

Grails best practice on form redirection/rendering

If I have an action def formPage(), I want to be able to save the form on that page, show the form with the previously entered values if there's an error, and show a blank form if it's a success.
My question is: Is it best practice for formPage to call something like saveFormPage(FormPageCommand fpc)? saveFormPage can then render formPage with or without the previously entered values. The problem with this approach is that the user can click the address bar, press enter, and then get a slew of errors since the form hasn't been filled in, and the command object sees all the null or blank values.
Another approach might be to just have a def formPage(FormPageCommand fpc), and ignore errors and just show a blank form if none of the values are filled in.
One might also call saveFormPage(FormPageCommand fpc) and redirect back to formPage() if none of the values are filled in.
What is the best practice here?
Try this example:
Your controller
class MyFormController {
def formPage() {
[cmd: new FormPageCommand()]
}
def saveFormPage(FormPageCommand cmd) {
if (cmd.hasErrors()) {
render view: "formPage", model: [cmd: cmd]
} else {
// Process form
// ......
// Redirect back formPage() to display a new form
redirect action: "formPage"
}
}
}
Your command object
class FormPageCommand {
String optionalValue
String requiredValue
static constraints = {
optionalValue(nullable: true, blank: true)
requiredValue(nullable: false, blank: false)
}
}
Your formPage.gsp
<g:form controller="myForm" action="saveFormPage" method="POST">
<label>Required value *</label>
<g:textField name="requiredValue" value="${cmd.requiredValue}"/>
<g:if test="${cmd.errors.getFieldError('requiredValue')}">
<g:message error="${cmd.errors.getFieldError('requiredValue')}"/>
</g:if>
<label>Optional value</label>
<g:textField name="optionalValue" value="${cmd.optionalValue}"/>
<g:submitButton name="submit"/>
</g:form>
It should serve your need.
Cheers.
I'm not sure I fully understand your question, but to get you started I recommend the book "Grails in Action". It contains a lot of best practices and chapter 7 on data binding and error handling may give you some good advice and ideas.
I encountered this problem before and solved it this way:
My registration form has a button:
<g:submitButton name="register" value="Register" />
So the incoming params map should have the "register" key with "Register" value.
Then I check the existence of this parameter in my controller:
def register(UserRegisterCommand urc) {
if (params.register) {
//some registration actions
}
}
In other words I check in the controller if the "Register" button was clicked, if yes - then perform registration actions. If no - the "register.gsp" is rendered.
I hope this will help.

Get name of username with SpringSecurity and JSP

I wonder how to get the username by springsecurity, for example, my user table looks like this:
username - password - name
Authentication is done by the username + password, if I use these two options:
<%= request.getUserPrincipal().getName() %>
<%= SecurityContextHolder.getContext().getAuthentication().getName() %>
He will show me the username value, but in case my username is a value personal document, so I would only show the value of the field name.
Is how to do this? I'm using JSP + JSTL. Thank you.
You can use the spring security JSTL tags :
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
and put in your JSP code the following code :
<sec:authentication property="principal.username" />
you will have acess to all Principal properties .

How do I display all selected options from multiselect listbox in edit view on Grails?

I am new to Grails development and have been having issues with <g:select> when it is used for a multi-select list. In my form, users can select between 1 to 6 options in a multi-select list box. They can then go back to an edit view to make changes.
The form successfully saves all the options that were selected, but if more than one option was selected, the listbox won't display that any were selected in the edit view. If only one option was selected however, it is displayed in the edit view correctly.
Could someone please give me some idea of how to fix it so that all selected options are displayed in edit view? (Running Grails 2.0.3)
Here is my <g:select> code in the GSP:
<g:select selected="true" multiple="true" name="securityGroup"
from="${['Mainframe', 'Finance', 'EDI', 'Item Master', 'Risk Management', 'Telecomm']}"
value="${MFAdminInstance?.securityGroup}"/>
Domain:
class MFAdmin {
static constraints = {
name(nullable:false, blank:false, unique:true)
briefDetail(nullable:false, blank:false)
details(blank:false)
recsz(nullable:false, blank:false)
securityGroup(nullable:false, blank:false)
files(nullable:false, blank:false)
begJCL(nullable:false, blank:false)
addJCL1(nullable:true, blank:true)
addJCL2(nullable:true, blank:true)
endJCL(nullable:false, blank:false)
}
String name
String briefDetail
String details
String recsz
String securityGroup
Integer files
String begJCL
String addJCL1
String addJCL2
String endJCL
}
Try being more explicit to the g:select tag that your value ${MFAdminInstance?.securityGroup} is a list. I'd suggest something like this:
${MFAdminInstance?.securityGroup?.toList()}
I was able to mock your code with something like:
<g:form action="update">
<g:select selected="true" multiple="true" name="securityGroup"
from="${['Mainframe', 'Finance', 'EDI', 'Item Master', 'Risk Management', 'Telecomm']}"
value="${bars}"/>
<g:submitButton name="submit" />
</g:form>
And within my action foo2 that handles the post:
def update() {
render(view: 'foo', model: [
bars: params.securityGroup.toList()
])
}
As you can see when I defined the list bars to be used in the gsp, I had to explicitly tell it that params.securityGroup is a list. Without that toList() at the end, the behavior was the missing selection for multiple select.
EDIT:
..inMFAdminInstance...
List<String> securityGroup
In your controller, you could store the selected post values to your domain with something like...
def mf = new MFAdminInstance()
mf.securityGroup = params.securityGroup?.toList()

how to show some text in html.LabelFor?

I am doing int like this:
Hello <%= Html.LabelFor(user => user.UserName)%>
But iam getting not a value which is in Property but something strange like this:
Hello User Name,
How can do it to give some value in label out?
Add DataAnnotations to your model/viewmodel:
public class Customer
{
[Display(Name = "Email Address", Description = "An email address is needed to provide notifications about the order.")]
public string EmailAddress { get; set; }
[Display(ResourceType=typeof(DisplayResources), Name="LName", Description="LNameDescription")]
public string LastName { get; set; }
}
Source: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute(v=VS.95).aspx
If you don't provide a display name by the DisplayAttribute then Html.EditorFor(...) uses the properties name, spliting it on upper case letters:
PropertyName --> Label text
Email --> Email
EmailAdress --> Email Address
The reason for this is because Html.LabelFor will do just that - create a label for the property. In this case, it is producing a label of 'User Name' since the property name is UserName.
You just need to look at the model (or whatever your passing to the view) to return the property value: Html.Encode(Model.UserName)
Update (since this was nearly 3 years ago but people have recently upvoted):
You can just use <%: Model.UserName %> to get the HTML encoded value (<%= writes it as raw and <%: writes it encoded).
If you're using a Razor view engine, then #Model.Username will write it out already encoded.

ASP.NET MVC Html.RadioButton Exception

I haver a simple radio button list on my page that I render with the following in my view:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender") %>
Note that when the user initially sees this input, neither button is selected.
The validation is there to force them to choose and not accept a default.
Therefore, these two radio buttons are bound to a nullable int property in my model declared as:
public int? gender { get; set; }
So if they do not select a button, and submit the page, the gender property will be null indicating that they did not select. The following validation is called by the controller during the post:
if (!gender.HasValue)
ModelState.AddModelError("gender", "gender required");
But, if the validation fails (they did not choose), then during the rendering phase, the following exception is thrown by the MVC framework:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
In searching for for a solution to this problem, I noted several had this problem.
I am using ASP.NET MVC 1.0. I found the place in the code where this error is thrown using .NET Reflector.
The question is how to make this work correctly?
EDIT: to add stacktrace:
System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="System.Web.Mvc"
StackTrace:
at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType)
at System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes)
at System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value)
at ASP.views_vbs_register_aspx.__RenderregisterContent(HtmlTextWriter __w, Control parameterContainer) in c:\Users\David\Documents\BellevueProject\Bellevue\BellevueTeachers\Forms\Views\VBS\Register.aspx:line 42
I just tried something that makes this work.
The problem does not occur if I do not do the validation step but of course I need the validation.
That gave me a clue for the solution.
The ValidationMessage HtmlHelper method takes a string argument that is the name of the property or model object being validated.
I just changed that name to be "gender2" as follows:
<label for="gender">Gender</label>
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.ValidationMessage("gender2") %>
And I changed the validation code to refer to this new name (even though that property does not exist, it still works):
if (!gender.HasValue)
ModelState.AddModelError("gender2", "gender required");
This works as desired.
I would have thought the other should have worked, but this is a simple workaround and I am documenting that here.
EDIT:
By the way I tried changing the gender property to a string instead of a nullable int, and the same exact problem occurs.
The work around still seems to be in using a different key name for the Validation Message.
This is very similar, if not equal to the checkbox issue: The Html.Checkbox() helper method generates a hidden field with a false value. If this field were missing, the browser would not send any data for uncheked boxes.
A radiobutton, however, is supposed to have a value, and the possible values can be more than one. In this case it is not so easy to handle the non-selection case, which I guess is the reason it isn't.
The workaround for me was to add a hidden field as follows:
<%= Html.RadioButton("gender", 1) %> Male
<%= Html.RadioButton("gender", 2) %> Female
<%= Html.Hidden("gender", null) %>
You might want to try changing gender to a string (M/F) instead of an int and see if that works.
If you absolutely must have it as an int, you could always translate on the back end.
private int? gender { get; set; }
public string displayGender
{
get
{
return this.gender.HasValue
? (this.gender.Value == 1 ? "M" : "F" )
: null;
}
set
{
this.gender = null;
if (value == "M")
this.gender = 1;
else if (value == "F")
this.gender = 2;
}
}
<label for="gender">Gender</label>
<%= Html.RadioButton("displayGender", "M") %> Male
<%= Html.RadioButton("displayGender", "F") %> Female
<%= Html.ValidationMessage("displayGender") %>
Base on your comment, you may want to add:
<%= Html.RadioButton("displayGender",
string.Empty,
true, // this is the default
new { #style = "display: none;" } ) %>
This will ensure that displayGender gets posted back (there will always be a chosen radio) and I think the value will be string.Empty instead of a null reference. If this works, you may want to try switching back to the nullable int.
Try adding the following line of code after the ModelState.AddModelError():
ModelState.SetModelValue("gender", ValueProvider["gender"]);
If you want to wire in client-side validation. Skip the html helper and hand-write your radios, giving them attributes for data-val and data-val-required. Like this.
<input type="radio" name="displayGender" id="displayGender" value="1" data-val="true" data-val-required ="The gender field is required."/>
<input type="radio" name="displayGender" id="displayGender" value="2" data-val="true" data-val-required ="The gender field is required."/>

Resources