Is there a way for me to strip away div classes and other CSS stuff when generating grails views? - grails

Well, there goes my question. I really don't like the UI, and if there was a way to auto generate only the essential things like the fields but no divs and classes. I know about removing the css, but I really just want the raw html like what rails gives me. Anybody know how?
For example, grails generate-views myStuff generates code that looks like this:
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="name">Name:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:feedback,field:'name','errors')}">
<input type="text" id="name" name="name" value="${fieldValue(bean:feedback,field:'name')}"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label for="feedback">Feedback:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:feedback,field:'feedback','errors')}">
<input type="text" id="feedback" name="feedback" value="${fieldValue(bean:feedback,field:'feedback')}"/>
</td>
</tr>
</tbody>
</table>
When I'm only interested in getting this:
<input type="text" id="name" name="name" value="${fieldValue(bean:feedback,field:'name')}"/>
<input type="text" id="feedback" name="feedback" value="${fieldValue(bean:feedback,field:'feedback')}"/>
Well, I could always do stuff manually and not auto-generate, but, no it's not practical when the fields are too many. :(

Use the install-templates command to install the templates. Then you can edit/modify the templates to meet your needs.

Related

URL found in auth.gsp - beginner

I need to know the following. I copied the following code from auth.gsp. I need to know what:
1.) I need to know what '${postUrl}' means?
2.) I did copy this code and paste it in another GSP called index.gsp, but the page didn't login successfully.
<form action='${postUrl}' method='POST' id="loginForm" name="loginForm" autocomplete='off'>
<div class="sign-in">
<h1><g:message code='spring.security.ui.login.signin'/></h1>
<table>
<tr>
<td><label for="username"><g:message code='spring.security.ui.login.username'/></label></td>
<td><input name="j_username" id="username" size="20" /></td>
</tr>
<tr>
<td><label for="password"><g:message code='spring.security.ui.login.password'/></label></td>
<td><input type="password" name="j_password" id="password" size="20" /></td>
</tr>
<tr>
<td colspan='2'>
<input type="checkbox" class="checkbox" name="${rememberMeParameter}" id="remember_me" checked="checked" />
<label for='remember_me'><g:message code='spring.security.ui.login.rememberme'/></label> |
<span class="forgot-link">
<g:link controller='register' action='forgotPassword'><g:message code='spring.security.ui.login.forgotPassword'/></g:link>
</span>
</td>
</tr>
<tr>
<td colspan='2'>
<s2ui:linkButton elementId='register' controller='register' messageCode='spring.security.ui.login.register'/>
<s2ui:submitButton elementId='loginButton' form='loginForm' messageCode='spring.security.ui.login.login'/>
</td>
</tr>
</table>
</div>
</form>
Spring security work on filters. If you print postUrl in your gsp file then it looks like /myApp/j_spring_security_check, only /j_spring_security_check URL is processed by Spring Security filter.
If you past auth.gap and not sending this url then cannot login. Change your gsp slightly to make this run, replace ${postUrl} with ${createLink(uri: '/j_spring_security_check')}.

Convert automatically all forms to Grails Fields Plugin

With Grails Fields Plugin you can write an actually shorter, cleaner, DRY code:
<bean:withBean beanName="person">
<bean:field property="username" label="Login Name:"/>
<bean:field property="userRealName" label="Full Name:"/> >
</bean:withBean>
The code above would do the same than the following:
<tr class="prop">
<td valign="top" class="name"><label for="username">Login Name:</label></td>
<td valign="top" class="value ${hasErrors(bean: person, field: 'username', 'errors')}">
<input type="text" id="username" name="username" value="${person.username?.encodeAsHTML()}"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name"><label for="userRealName">Full Name:</label></td>
<td valign="top" class="value ${hasErrors(bean: person, field: 'userRealName', 'errors')}">
<input type="text" id="userRealName" name="userRealName" value="${person.userRealName?.encodeAsHTML()}"/>
</td>
</tr>
But, must I change all my already written code manually?
If I were you, I would have stuck to one word
CONSISTENCY
I would rather convert all of them using the plugin or do not use the plugin and convert none. So that in future, I would not have to deal with two types of handling. On the other hand, if you have a lot of views to be converted and you have a short deadline, then I would add this task to my backlog.
But again, it differs from person to person. This was my opinion. I hope this could be useful.
Grails fields plugin have an option for scaffolding, so at least you can regenerate your scaffolded code.
I agree with #dmahapatro about the consistency of the code, if you choose to use the plugin, it's an effort that must be made, to make all your views have the same pattern.

How to define in Grails an uploadForm and 2 different actions?

I have a gsp view, with an , and 2 input text.
I have a button to save and submit.
Now I would like to add another button with a new action, in my case a button to schedule save.
Note : in my controller I have define : def save (corresponding to button action save) and def schedule (corresponding to button action schedule).
What is the best way to add Schedule in this gsp view :
<g:uploadForm action="save" method="post" >
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="payload">File:</label>
</td>
<td valign="top">
<input type="file" id="payload" name="payload"/>
</td>
<td valign="top">
<input type="file" id="payload2" name="payload2"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label for="lvalue">Lvalue:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:rmmInstance,field:'lvalue','errors')}">
<input type="text" id="lvalue" name="lvalue" value="${fieldValue(bean:rmmInstance,field:'lvalue')}" />
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label for="wvalue">Wvalue:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:rmmInstance,field:'wvalue','errors')}">
<input type="text" id="wvalue" name="wvalue" value="${fieldValue(bean:rmmInstance,field:'wvalue')}" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><input class="save" type="submit" value="Run Now" /></span>
</div>
</g:uploadForm>
I have just one form, but 2 different actions.
Thanks !
With an actionSubmit:
Purpose
Creates a submit button that maps to a
specific action, which allows you to
have multiple submit buttons in a
single form. Javascript event handlers
can be added using the same parameter
names as in HTML.
From the Grails reference docs.

Grails GSP doesn't generate intended HTML under Geronimo

When running my Grails 1.1-M2 app as a WAR under Geronimo 2.1.4 (jetty6, javaee5), the HTML generated from the GSPs do not include my dynamic content.
Specifically, this GSP snippet:
<tr class="prop">
<td valign="top" class="name">
<label for="type">
<g:message code="album.type.label" default="Type" />
</label>
</td>
<td valign="top" class="value ${hasErrors(bean:albumInstance,field:'type','errors')}">
<g:select from="${AlbumType?.values()}" value="${albumInstance?.type}" name="type" ></g:select>
</td>
</tr>
...produces this HTML when running under Geronimo:
<tr class="prop">
<td valign="top" class="name">
<label for="type">
Type
</label>
</td>
<td valign="top" class="value ">
<select name="type" id="type" ></select>
</td>
</tr>
...however when running as 'grails run-app' or 'grails run-war', this, correct HTML is produced:
<tr class="prop">
<td valign="top" class="name">
<label for="type">
Type
</label>
</td>
<td valign="top" class="value ">
<select name="type" id="type" >
<option value="EP" >EP</option>
<option value="LP" >LP</option>
<option value="SINGLE" >SINGLE</option>
</select>
</td>
</tr>
AlbumType.groovy is defined in src/groovy as:
public enum AlbumType {
EP,
LP,
SINGLE
}
I've turned on all logging within Grails and don't see any error or exceptions. This issue is confusing as I only see it while running my Grails WAR under Geronimo. Granted, I haven't tried any other app servers though it is curious that everything works fine with 'grails run-app' and 'grails run-war'.
Any ideas as to the problem?
I would highly recommend keeping code out of the the default package and putting it into a good package structure. I suspect this is your issue.

Grails dynamic scaffold with hasMany: is it a bug or am I misconfiguring?

I'm a Grails noob and running into something that seems to be a bug, but it is entirely possible I'm not configuring everything correctly.
I've got two simple Domain Classes:
class Player {
String firstName
String lastName
static constraints = {
firstName(blank:false)
lastName(blank:false)
}
String toString() { lastName + ", " + firstName }
}
and
class Team {
String mascot;
static hasMany = [players:Player]
static constraints = {
mascot(blank:false)
}
}
I have controllers for both that do nothing beyond dynamic scaffold these two Domain Classes.
But even when I have a list of Players in my DB, I don't get a multi-select box for them when creating a new Team.
However, the multi-select shows up when I go to edit a Team
Is this a bug in the dynamic scaffolding for new items, do I misunderstand how this is supposed to work, or is there something else I need to declare here?
Any help is hugely appreciated! I've got screenshots that StackOverflow won't let me add because of my newness, but I'd be happy to show them another way if that'll help.
I finally figured this out and wanted to pass on what I did just in case someone else runs into it.
When I generated the views for Team, the form block in edit.gsp looks like this:
<input type="hidden" name="id" value="${teamInstance?.id}" />
<input type="hidden" name="version" value="${teamInstance?.version}" />
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="mascot">Mascot:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:teamInstance,field:'mascot','errors')}">
<input type="text" id="mascot" name="mascot" value="${fieldValue(bean:teamInstance,field:'mascot')}"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label for="players">Players:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:teamInstance,field:'players','errors')}">
<g:select name="players"
from="${Player.list()}"
size="5" multiple="yes" optionKey="id"
value="${teamInstance?.players}" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><g:actionSubmit class="save" value="Update" /></span>
<span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span>
</div>
</g:form>
but the form block in create.gsp looks like this:
<g:form action="save" method="post" >
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="mascot">Mascot:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:teamInstance,field:'mascot','errors')}">
<input type="text" id="mascot" name="mascot" value="${fieldValue(bean:teamInstance,field:'mascot')}"/>
</td>
</tr>
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><input class="save" type="submit" value="Create" /></span>
</div>
</g:form>
In other words, for this corner case, the default Create view omits the widget to properly display the multi-select list. When I did a copy and paste of the missing code, the dynamically scaffolded controller picked it up and persisted it as expected. So, it's definitely a bug in the view generation code.
Yes, the default scaffolding puts a parent selector in the child class' create/edit page.
I'm guessing it was just easier for them this way. It shouldn't be a multi-select though, just a pull-down single-select, as it's a One-to-Many.
As you've explained you wanted more of a Many-to-Many relationship, you might try adding:
static hasMany = [teams:Team]
to your Player class. I've found that Grails does better with bi-directional relationships. It's also useful to have when building search queries, and shouldn't require more than the one relationship table you'd already need.
If you're using Grails pre-v1.1, Many-to-Many relationships aren't directly supported, so even adding the static hasMany above won't be the complete solution, as you'll need to manage adding to the other list when you add to one direction. I haven't used v1.1 yet, so I can't talk about what is needed to specify the Many-to-Many in it.
I encountered the same problem using current version (v1.3.4) of Grails. Had to manually modify the create.gsp

Resources