How to set multiple value in select box using grails - grails

I am using grails 2.1.1. I have a table named audit firm. There are two types of firm. Audit review firm and ca firm. I am saving the value of audit review firm in parent table and ca firm in child table that's why ca firm is a multiple select box. But when I want to edit the audit review firm is selected but ca firms are not selected in the multiple select box. I have searched for it and applied some things but no luck. Can anyone please help me on this please ??!!! Here are my attempts below ::
my parent domain >>>
class DistrictAssignToAuditReviewFirm {
static mapping = {
table('ADT_DIST_ASSN_TO_ADT_RV_FIRM')
version(false)
caFirm cascade: 'all'
}
AuditFirm auditReviewFirm
long CREATED_BY=0
Date CREATED_DATE=new Date()
long UPDATED_BY=0
Date UPDATED_DATE=new Date()
static hasMany = [caFirm: DistrictAssignToAuditReviewFirmDetails]
static constraints = {
auditReviewFirm(nullable: false, blank: false)
CREATED_BY(nullable:true)
CREATED_DATE(nullable:true)
UPDATED_BY(nullable: true)
UPDATED_DATE(nullable: true)
}
String toString(){
return auditReviewFirm
}
}
my child domain >>>
class DistrictAssignToAuditReviewFirmDetails {
static mapping = {
table('ADT_DIST_ASSN_TO_ADT_RV_DETL')
version(false)
}
AuditFirm caFirmDetails
DistrictAssignToAuditReviewFirm distAssnToAdtRevFirm
static constraints = {
caFirmDetails(nullable: false, blank: false)
distAssnToAdtRevFirm(nullable: false, blank: false)
}
String toString(){
return caFirmDetails
}
}
my view page >>>
<div class="col-xs-6">
<div class="form-group">
<label for="auditReviewFirm">
<g:message code="dl" default="Audit Review Firm" />
</label>
<g:select id="auditReviewFirm" name="auditReviewFirm.id" from="${auditReviewFirm}" optionValue="auditFirmName" optionKey="id" noSelection="['':'Select One']" required="" value="${districtAssignToAuditReviewFirmInstance?.auditReviewFirm?.id}" class="form-control"/>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="caFirm">
<g:message code="dl" default="CA Firm" />
</label>
<g:select id="caFirm" name="caFirm.id" from="${caFirm}" optionValue="auditFirmName" optionKey="id" multiple="true" required="" value="${districtAssignToAuditReviewFirmInstance?.caFirm?.caFirmDetails?.id}" class="form-control"/>
</div>
</div>

Related

ASP.NET MVC - Multiple Radio Buttons selections being allowed, why?

Question Background:
I have two groups of Radio buttons in a menu. One group features 2 Radio buttons that allow a user to select a group of items to being sorted and displayed by their price either from 'High To Low' or 'Low To High'.
The second group of Radio buttons allows users to search for results from 3 different online marketplaces.
The Issue:
Currently the first group of Radio buttons (the price sort group) is working fine, if I click 'High To Low' then that Radio buttons will be selected, if I then select 'Low To High' this will be selected.
The second group with the 3 radio buttons for the marketplaces is causing me issues. This is allowing all three radio buttons to be checked instead of just one, and once all checked the user cannot unchecked them, as shown:
The Code:
this is the MarkUp in my View. I am using RadioButtonsFor Razer controls binding each Radio button to a specific property from the ViewModel.
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButtonFor(model => model.amazonAndEbay, true, new { id = "amazonEbayBox", #checked = "true" })<img class="originPic" src="#Url.Content("~/Images/amazon.png")" /> <img class="originPic" src="#Url.Content("~/Images/ebay.png")" /> Amazon & Ebay</label>
</div>
</div>
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButtonFor(model => model.amazonOnly, true, new { id = "amazonCheckBox" })<img class="originPic" src="#Url.Content("~/Images/amazon.png")" /> Amazon Only</label>
</div>
</div>
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButtonFor(model => model.ebayOnly, true, new { id = "ebayCheckBox" })<img class="originPic" src="#Url.Content("~/Images/ebay.png")" /> Ebay Only</label>
</div>
</div>
The HomePageVM:
public class HomePageVM
{
public bool highToLow { set; get; }
public bool lowToHigh { set; get; }
public bool amazonAndEbay { set; get; }
public bool amazonOnly { set; get; }
public bool ebayOnly { set; get; }
}
The Radio Buttons as rendered in Chrome:
<div class="form-group">
<div class=" maxPricePad">
<label>
<input checked="true" data-val="true" data-val-required="The amazonAndEbay field is required." id="amazonEbayBox" name="amazonAndEbay" type="radio" value="True"><img class="originPic" src="/Images/amazon.png"> <img class="originPic" src="/Images/ebay.png"> Amazon & Ebay</label>
</div>
</div>
<div class="form-group">
<div class=" maxPricePad">
<label>
<input data-val="true" data-val-required="The amazonOnly field is required." id="amazonCheckBox" name="amazonOnly" type="radio" value="True"><img class="originPic" src="/Images/amazon.png"> Amazon Only</label>
</div>
</div>
<div class="form-group">
<div class=" maxPricePad">
<label>
<input data-val="true" data-val-required="The ebayOnly field is required." id="ebayCheckBox" name="ebayOnly" type="radio" value="True"><img class="originPic" src="/Images/ebay.png"> Ebay Only</label>
</div>
</div>
Any help determing why I am getting all 3 checkboxes to select would be much appreciated.
Very sill lapse in concentration and just realized I'm using different models values for each property instead of one common one.
If you want only one selection from the group of radio buttons then you have to give them a common name, which will group them together and allow you to select only one from the group. The example lets you choose either Camaro or Mustang, but not both of them, since they have the same name, which means that they belong to the same group of items:
<input type="radio" name="car"/> Camaro <br/>
<input type="radio" name="car"/> Mustang <br/>
This example will let you choose one car (Camaro or Mustang) and one color (Yellow or Green):
<input type="radio" name="car"/> Camaro <br/>
<input type="radio" name="car"/> Mustang <br/>
<input type="radio" name="color"/> Yellow<br/>
<input type="radio" name="color"/> Green<br/>
The reason you are getting all three checkboxes selected in the Marketplaces group is that you're using separate names for each radio button in this button group. All buttons that ought to be mutually exclusive should be part of one group represented by one label. Also, since you're declaring each radio button separately and individually, I think there's no need to use HtmlRadioButtonFor. Simply try the following changes to your code. Note that I named your radio button group as, "Marketplaces":
The Code:
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButton("Marketplaces", model.amazonAndEbay, new { id = "amazonEbayBox", #checked = "true" })<img class="originPic" src="#Url.Content("~/Images/amazon.png")" /> <img class="originPic" src="#Url.Content("~/Images/ebay.png")" /> Amazon & Ebay</label>
</div>
</div>
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButton("Marketplaces", model.amazonOnly, new { id = "amazonCheckBox" })<img class="originPic" src="#Url.Content("~/Images/amazon.png")" /> Amazon Only</label>
</div>
</div>
<div class="form-group">
<div class="maxPricePad">
<label>#Html.RadioButton("Marketplaces", model.ebayOnly, new { id = "ebayCheckBox" })<img class="originPic" src="#Url.Content("~/Images/ebay.png")" /> Ebay Only</label>
</div>
</div>

g:checkbox does not save checked items individually for list items

I am relatively new to grails and have been trying to configuring a check box to set a boolean value to true when it is checked for a number of list items.
The relationship is a hasMany between two domains where the boolean canEdit is set in the work domain. The other domain is called role.
I have set up the relationship so that work hasManyRoles and I would like my domain to reflect the boolean canEdit being set to true for some of these roles based on what gets checked in the checkbox list.
I have managed to get the gsp working displaying the list with checkboxes beside each one but am unsure as to how to save the boolean as true once some of these roles are checked as currently they are all getting set to true regardless of which is checked.
Any assistance would be greatly appreciated. I will post my code below:
class Work {
static hasMany = [canEditRole: Role]
String name = "Default"
Boolean canEdit = false
static constraints = {
name blank: false, unique: true
canEdit nullable: true
}
boolean canEdit(Role role){ // not sure the best way to check for if the role is associated, this was something I tried with te default add method.
if(canEdit){
addToCanEditRole(role)
}
return canClose
}
}
class WorkController{
def save(Long id, String canEdit) {
def work = Work.get(params.id)
def roleToCheck = Role.findByName(params.roleNames)
Boolean roleCanEdit = canEdit ? true : false
if(roleCanEdit){
workflow.canEdit(roleToCheck)
println "role is " + roleToCheck
}else{
println "no roles added"
}
}
}
GSP Code Snippet:
<tr class="prop">
<td valign="top" class="name">
<label for="canEdit">Allow Role to Edit</label>
</td>
<td valign="top" style="text-align: left;"
class="value ${hasErrors(bean: WorkInstance, field: 'canEdit', 'errors')}">
<ul>
<g:each in="${roleNames}" var="role">
<li>
<g:checkBox name="canEdit" value="${WorkInstance?.canEdit}"/> <label>${role.name}</label>
</li>
</g:each>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><g:actionSubmit class="save" action="save"
params="[roleName: roleNames.name]"
value="${message(code: 'default.button.update.label', default: 'Update')}"/></span>
</div>
Have you looked at grails.plugin.springsecurity.ui.UserController
? It seems that the functionality that you want is already there.
protected Map buildUserModel(user) {
Set userRoleNames = user[authoritiesPropertyName].collect { it[authorityNameField] }
def granted = [:]
def notGranted = [:]
for (role in sortedRoles()) {
String authority = role[authorityNameField]
if (userRoleNames.contains(authority)) {
granted[(role)] = userRoleNames.contains(authority)
}
else {
notGranted[(role)] = userRoleNames.contains(authority)
}
}
[roleMap: granted + notGranted, tabData: tabData, user: user]
}
Then in your gsp, you can access roleMap like:
<g:each var="entry" in="${roleMap}">
<div class="form-group">
<label class="col-xs-4">
<g:link controller='role' action='show' id='${entry.key.id}'>
${entry.key.authority.encodeAsHTML()}
</g:link>
</label>
<div class="col-xs-8">
<g:checkBox name="${entry.key.authority}" value="${entry.value}"/>
</div>
</div>
</g:each>

Could not find matching constructor Grails error

I have a User domain with a flag for security officer and a Location domain to hold all locations in my web app. I want to allow an administrator to assign a primary and secondary security officer to any location from a pick list of all users with the security officer flag checked. I have this working in a hand-made MVC structure, but I'm currently playing with scaffolding and have run into a strange error I can't figure out. My Location domain is coded as
class Location {
static hasMany = [users:User]
Integer id
...
String address
String city
State state
String zip
...
User primarySecurityOfficer
User secondarySecurityOfficer
static mapping = {
table 'location'
id generator: 'identity'
sort "state"
version false
}
static constraints = {
...
address(blank: false, nullable: false)
city(blank: false, nullable: false)
state(blank: false, nullable: false)
zip(blank: false, nullable: false, size: 5..5)
...
primarySecurityOfficer(blank: true, nullable: true)
secondarySecurityOfficer(blank: true, nullable: true)
}
}
and I generated the views with grails generate-all Location. I modified the security officer selection in the generated _form.gsp to
<div class="fieldcontain ${hasErrors(bean: locationInstance, field: 'primarySecurityOfficer', 'error')}">
<label for="primarySecurityOfficer">
<g:message code="location.primarySecurityOfficer.label" default="Primary Security Officer" />
</label>
<g:select id="primarySecurityOfficer" name="primarySecurityOfficer" value="${locationInstance?.primarySecurityOfficer?.employeeNumber}" from="${securityOfficers}" optionKey="employeeNumber" optionValue="${{it.firstName + ' ' + it.lastName}}" noSelection="${['null':' ']}" disabled="${disabled}"/>
</div>
<div class="fieldcontain ${hasErrors(bean: locationInstance, field: 'secondarySecurityOfficer', 'error')}">
<label for="secondarySecurityOfficer">
<g:message code="location.secondarySecurityOfficer.label" default="Secondary Security Officer" />
</label>
<g:select id="secondarySecurityOfficer" name="secondarySecurityOfficer" value="${locationInstance?.secondarySecurityOfficer?.employeeNumber}" from="${securityOfficers}" optionKey="employeeNumber" optionValue="${{it.firstName + ' ' + it.lastName}}" noSelection="${['null':' ']}" disabled="${disabled}"/>
</div>
and the controller's create and save auto-generated actions (modified to send the view the security officer list) are
def create() {
def securityOfficers = User.findAll("from User as u where u.securityOfficer='1'")
println params
respond new Location(params), model: [ securityOfficers:securityOfficers ]
}
#Transactional
def save(Location locationInstance) {
def securityOfficers = User.findAll("from User as u where u.securityOfficer='1'")
if (locationInstance == null) {
notFound()
return
}
if (locationInstance.hasErrors()) {
respond locationInstance.errors, view:'create', model: [ securityOfficers: securityOfficers ]
return
}
locationInstance.save flush:true
request.withFormat {
form {
flash.message = message(code: 'default.created.message', args: [message(code: 'locationInstance.label', default: 'Location'), locationInstance.id])
redirect locationInstance
}
'*' { respond locationInstance, [status: CREATED], model: [ securityOfficers:securityOfficers ] }
}
}
The error I'm getting is that if I select any security officers and try to save a new location, I get the error Could not find matching constructor for: User(java.lang.String). If I leave the selector blank, the location will save successfully. Any ideas why?
Edit 1: Interesting find from tinkering around. I can successfully save security officers to locations if I change the view code to
<div class="fieldcontain ${hasErrors(bean: locationInstance, field: 'primarySecurityOfficer', 'error')}">
<label for="primarySecurityOfficer">
<g:message code="location.primarySecurityOfficer.label" default="Primary Security Officer" />
</label>
<g:select id="primarySecurityOfficer.employeeNumber" name="primarySecurityOfficer.employeeNumber" value="${locationInstance?.primarySecurityOfficer?.employeeNumber}" from="${securityOfficers}" optionKey="employeeNumber" optionValue="${{it.firstName + ' ' + it.lastName}}" noSelection="${['null':' ']}" disabled="${disabled}"/>
</div>
<div class="fieldcontain ${hasErrors(bean: locationInstance, field: 'secondarySecurityOfficer', 'error')}">
<label for="secondarySecurityOfficer">
<g:message code="location.secondarySecurityOfficer.label" default="Secondary Security Officer" />
</label>
<g:select id="secondarySecurityOfficer.employeeNumber" name="secondarySecurityOfficer.employeeNumber" value="${locationInstance?.secondarySecurityOfficer?.employeeNumber}" from="${securityOfficers}" optionKey="employeeNumber" optionValue="${{it.firstName + ' ' + it.lastName}}" noSelection="${['null':' ']}" disabled="${disabled}"/>
</div>
But now I cannot save WITHOUT a security officer. The error I get if I attempt to is Unparseable number: "null".

grails saving object with hasmany relation through form

I'm trying to create simple form for saving post with it's relations.
Here is my domain models;
Post Model;
class Post {
String title
String teaser
String content
static belongsTo = [author: Person, category: Category]
static hasMany = [tags: Tag]
static constraints = {
}
}
Tag Model;
class Tag {
String name
static belongsTo = Post
static hasMany = [posts: Post]
static constraints = {
}
}
I've created a form for saving post object through html form;
<g:form controller="posts" action="save" method="post">
<div class="input">
<label for="post.title">Title:</label>
<g:textField name="post.title" />
</div>
<div class="input">
<label for="post.teaser">Teaser:</label>
<g:textField name="post.teaser" />
</div>
<div class="input">
<label for="post.content">Content:</label>
<g:textArea name="post.content" />
</div>
<div class="input">
<label for="post.content">Category:</label>
<g:select optionKey="id" optionValue="name" name="post.category" from="${categories}" noSelection="['':'-Choose Category-']"/>
</div>
<div class="input">
<label for="post.tags">Tags:</label>
<g:select optionKey="id" optionValue="name" name="post.tags" from="${tags}" noSelection="['':'-Choose Tags-']" />
</div>
<div class="input">
<g:submitButton name="Create" value="Create" />
</div>
</g:form>
And here is the controller logic;
def save() {
def post = new Post(params.post)
post.author = springSecurityService.currentUser
if(post.save()){
flash.message = "Post created successfully..."
redirect(action: "index", method: "GET")
}
else{
flash.error = "Something went wrong, please check the form again!"
[tags: Tag.list(), categories: Category.list()]
render(view: "create")
}
}
With this way i can't save tags for post object.
I solved the problem with
post.save(flush: true)
here is the documentation about
gorm save

How to use transients domain attributes with Grails Fields Plugin

I'm trying to add the field confirm password to an user register form. This is an extract of my domain class:
package usuario
class Usuario {
transient springSecurityService
String password
String confirmarPassword
static constraints = {
password blank: false, password: true, size:5..15, matches:/[\S]+/
confirmarPassword blank:false, password: true, size:5..15, matches:/[\S]+/, validator:{ val, obj ->
if (obj.password != obj.confirmarPassword)
return 'usuario.password.dontmatch'
}
}
static transients = ['confirmarPassword']
static mapping = {
password column: '`password`'
}
Set<Rol> getAuthorities() {
UsuarioRol.findAllByUsuario(this).collect { it.rol } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
obj.confirmarPassword is always null so the constraint is never accomplished.
I installed the Grails Templates as it is suggested here. I changed the attribute persistentProperties, but it is only at _form.gsp, and _form.gsp is not used by Grails Fields Plugins. Therefore, the transients attributes don't appear in the Internet Browser.
I copied the generated transients attributes of the _form.gsp to create.gsp:
<fieldset>
<g:form class="form-horizontal" action="create" >
<div class="fieldcontain ${hasErrors(bean: usuarioInstance, field: 'confirmarPassword', 'error')} required">
<label for="confirmarPassword">
<g:message code="usuario.confirmarPassword.label" default="Confirmar Password" />
<span class="required-indicator">*</span>
</label>
<g:field type="password" name="confirmarPassword" maxlength="15" pattern="${usuarioInstance.constraints.confirmarPassword.matches}" required="" value="${usuarioInstance?.confirmarPassword}"/>
</div>
<fieldset>
<f:all bean="usuarioInstance"/>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
<g:message code="default.button.create.label" default="Create" />
</button>
</div>
</fieldset>
</g:form>
</fieldset>
The transients attributes appear on the screen, but obj.confirmarPassword is still null
The last approach I thought is to modify views_fields\default_field.gsp to also use these transients attributes, but I didn't find how. This is the documentation. This is the content of that file:
<%# page defaultCodec="html" %>
<div class="control-group ${invalid ? 'error' : ''}">
<label class="control-label" for="${property}">${label}</label>
<div class="controls">
<%= widget %>
<g:if test="${invalid}"><span class="help-inline">${errors.join('<br>')}</span></g:if>
</div>
</div>
Is it possible with Grails Fields Plugin? Where are the conditions tested, on client or server side? (I think part of the checking is on client side, but all the restrictions are checked again on server side).
Oh that i have i encountered it before .
Declaring
String confirmarPassword
and making it traniset it doesn't work me like this
static transients = ['confirmarPassword']
But
transient confirmarPassword
As you did it for the springService...i don't now why that doesn't work and this , some one may have a better clarification ...
In latest versions of Grails, transient attributes are not binded with form by default. This is the documentation of the bindable constraint. This is how my code would become (I just added bindable: true):
static constraints = {
password blank: false, password: true, size:5..15, matches:/[\S]+/
confirmarPassword bindable: true, blank:false, password: true, size:5..15, matches:/[\S]+/, validator:{ val, obj ->
if (obj.password != obj.confirmarPassword)
return 'usuario.password.dontmatch'
}
}
However, transient attributes are not shown with <f:all bean="usuarioInstance"/>, We have to add these attributes manually: <f:field bean="${usuarioInstance}" property="confirmarPassword" />. It is not an ideal solution. I'll keep this question open some days hoping that someone knows the answer.
UPDATE
In my case, the above solution didn't work either because I'm using Spring Security Core plugin. It gives the next error:
null id in usuario.Usuario entry (don't flush the Session after an exception occurs)
In that case, we have to use a command object. That issue is described (and solved) in this post.

Resources