Wednesday, August 25, 2010

how to ask user for confirmation before executing remoteLink

before:"if(!confirm('Are you sure?')) return false"

The trick is not to return "true". Credits go to this jira.

Wednesday, August 11, 2010

short reminder for stupid me

If the tag does not work, it is most probably because I forgot to add the braces to the variable:

 
never works!

 
usually does work!

Tuesday, August 10, 2010

grails and SVN

I added my grails projects to a SVN repository, in order to be able to work someplace else. When I tried to check my projects out however, they did not run.

I included .project and .classpath files as I already learned that they are needed for eclipse to recognize them as grails projects.

Problem: When I ran run-app I got error messages complaining that plugins could not be resolved (locally). Also the plugin manager in STS did not list any plugins. Nothing worked.

What I missed however was that you have to run grails upgrade to reinstantiate other missing files. Afterwards plugins are resolved correctly and downloaded from the internet. This solution was found here.

Wednesday, July 28, 2010

preventing grails-ui tooltip from disappearing

Today I tried to prevent the grails-ui tooltip from disappearing after 5 seconds when the mouse is not moved. From the YUI doc I knew I had to alter a parameter 'autodismissdelay', but I haven't found a way to pass this parameter with the taglib. Unfortunately the only way I succeeded was to alter the ToolTip.js in grails-ui-1.2-SNAPSHOT\web-app\js\grailsui where I changed the value from 5000 to -1.

Tuesday, July 20, 2010

making export plugin work with filterpane

The export plugin and the filterpane plugin for themselves work like a charm. If you try to export your filtered list however, you run into problems. The root of this problem has been recognized during an earlier discussion on the mailing list.

The problem: You have to extend the filter action to deal with the export. Therefore you have to apply the filterService.filter method with the same filter params as when you applied the actual filter.

The workaround (not a perfect solution): To solve this problem I save the filter params in the session. When export is applied on the filter action the filter params are retrieved from the session. That works well although I'm not very happy with storing so much information in the session permanently.

The Code:

Here I have modified the example from the plugin page. The export-part of the list action is extracted and gets its own export closure, which can then be used by the filter action as well. I also do not explicitly name the parameters as I am using this code in a scaffolded controller. Therefore a list is fetched of all properties, excluded those that are not really representative.

def export = {attrs ->
  
  def response = attrs.response
  println attrs.exportList
  
  def excluded = grails.persistence.Event.allEvents.toList() + ["mapping", "lastModifierId", "hasMany", "class", "belongsTo", "constraints", "searchable", "attached", "errors", "metaClass", "log", "object", "version", "beforeInsert", "beforeUpdate", "mappedBy", "springSecurityService", "type", "typeLabel"]
  List fields = ${className}.newInstance().properties.keySet().toList().findAll { !excluded.contains(it) && !isId(it)}

  response.contentType = org.codehaus.groovy.grails.commons.ConfigurationHolder.config.grails.mime.types[attrs.format]
  response.setHeader("Content-disposition", "attachment; filename=${className}.\${attrs.extension}")
  
  exportService.export(attrs.format, response.outputStream, attrs.exportList, fields, [:], [:], [:])
 }
 
 def isId(def label)
 {
  label.reverse().startsWith("dI")
 }

 def filter = {  
  if(!params.max) params.max = 10
  println "out:" +params
  if(params?.format && params.format != "html" && session.filterParams)
  {
   def exportList = filterService.filter( session.filterParams, ${className} )
   println "list:" + exportList
   export(response: response, extension: params.extension, format: params.format, exportList: exportList)
  }
  
  session.filterParams = params
  
  render( view:'list',
   model:[ ${propertyName}List: filterService.filter( params, ${className} ),
   ${propertyName}Total: filterService.count( params, ${className} ),
   filterParams: com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params),
   params:params ] )
 }

EDIT: Steve made me aware that it is easy to extract the necessary parameters with a helper method. One should therefore rather modify the export taglib to pass the correct parameters to the filter action. Also see Steve's comment below.

EDIT: Please forget about most of the crazy stuff I have done here :-) You can pass the filterParams with the export tag like this:


Thursday, July 15, 2010

just some notes about working with scaffolding code

When I modify scaffolding templates I always wonder how to obtain different properties like e.g. the class name or the id of the current instance. A general remark: What confused me most in the beginning was notation like \${${...}}. What you have to know is that \$ is escaped and is therefore what you can normally achieve in GSPs with a $. The unescaped $ within that clause is for the template. When actual code is generated from the template those $ are resolved immediately. You can therefore only use properties that are kown at this stage. Here are a few examples.

\${${className}}
This resolves the long version of the current class name

You often see that properties of an instance are iterated. The variable name of a property is then 'p':

${p.name}
This is the name of the property as it is used in the current instance. You need this value if you want to access that property in a controller (similar to this: domainClassInstance."${params.propertyName}").

${p.referencedDomainClass?.propertyName}
This one gives you the propertyName of the referenced domain class, thus the domain class of the property p. The propertyName is equal to the controller name if you stick to the convention.

${p.referencedDomainClass?.fullName}
Sometimes you need to have the full class name with the whole package notation. This can be useful for domain class instantiation (see my last post).

${p.referencedDomainClass?.shortName}
This is the actual class name omitting the package notation.

how to get a domain class instance from a class string (e.g. via params)

I had the problem that I could pass the class name from my gsp to my controller, but I didn't know how to work with that being a String. Luckily I stumpled about the solution in a code example somewhere on the web:

def grailsApplication
grailsApplication.getDomainClass(params.className).newInstance()

Wednesday, July 7, 2010

creating custom grails artefacts

I wanted to create my own kind of artefacts, in order to make easy extension of my application easier. I already had an interface called "Module" that has been implemented by classes that add new content to my sites. There were two problems that artefacts could solve for me:
  1. Dynamic reloading on code change won't work in non-artefact classes :-(
  2. Whenever I introduce a new module, I have to manually register it with a service handler.
As an artefact a module is automagically added and corresponding classes are hot-swapped if changed. I followed the great instructions on this page to get started.

The only thing I have done differently was in the last step, when I access the modules like this:

def grailsApplication

def modules = grailsApplication.getModuleClasses().collect { 
 it.referenceInstance
}

The thing is, getModuleClasses() returns 'GrailsClasses' and not java.lang.classes. At first I took the wrong road from there, trying to use it.class, which is then the DefaultModuleClass that you had to define with no abilities. I wondered how to obtain the underlying 'real' module class. Looking into the properties of the GrailsClass I found out that you can get the class of the module by accessing 'class'. But you can do even better: A instance is already attached and can be accessed by it.referenceInstance.

Happy artefacting!

closures in bootstrap.groovy not working

Just a note: Closures are currently (I believe since 1.2.2) not working in Bootstrap.groovy. This is also documented in JIRA. What you can do however, is use methods instead.

Monday, July 5, 2010

richui:treeView, expand and select

I extended the richui:treeView component a little bit as I wanted to be able to have a little control about extending and selecting nodes depending on what was happening on the rest of my page. I therefore followed the instructions on:

http://6by9.wordpress.com/2009/06/18/62/

Additionally to the extended attribute, I also added the selected attribute to the code:

builder.yieldUnescaped "    function createNode(text, id, icon, pnode, expand, select){\n"
builder.yieldUnescaped "        var n = new YAHOO.widget.TextNode(text, pnode, false);\n"
builder.yieldUnescaped "        n.labelStyle=icon;\n"
builder.yieldUnescaped " if(expand == \"true\"){\n"
builder.yieldUnescaped "  n.expanded = true;\n"
builder.yieldUnescaped " }\n"
builder.yieldUnescaped " if(select == \"true\"){\n"
builder.yieldUnescaped "  n.selected = true;\n"
builder.yieldUnescaped " }\n"

and a few lines later this one had to be modified twice:

builder.yieldUnescaped "    createNode(\"" + it.@name + "\", \"" + it?.@id + "\", \"" + it.@icon + "\", $parent, \"" + it.@expanded + "\", \"" + it.@selected + "\");\n"

Afterwards I was able to set the expanded and the selected property during XML generation as node properties. The expanded attribute is immediately accepted by the YUI widget, but selected is not. I found out that you have to look for the selected property yourself and then use the focus method to apply your selection to the actual node:

var selectedNode = YAHOO.widget.TreeView.getTree('tree').getNodeByProperty('selected',true);
if (selectedNode){
 selectedNode.focus();
}

With this, I was able to create the YUI treeView with nodes expanded and selected as I wanted.

Tuesday, June 29, 2010

XMLSlurper trying to annoy me

Just a little note: If you ever wonder why you're iteration of XMLSlurper elements does not work: Try inserting a .children() before the .each(). Have a look at this code, where you have one case where it works without and in the second place only with .children():

ncbiXML.GBSeq.'GBSeq_feature-table'.GBFeature.each{feature ->
 if((feature.GBFeature_key as String) == "CDS")
 {                   
  feature.GBFeature_quals.children().each{qual ->
  }
 }

Parsing XML: two stumbling blocks and a problem with params

Today I wanted to parse some XML content from NCBI into my grails application. I followed the instructions on:

http://www.ibm.com/developerworks/java/library/j-grails05208/index.html

Although the connection did not seem to have any problems, the parsing from a XMLSlurper object to a map did. There were in fact two problems I had to face and luckily I found the solution for both of them here:

http://stackoverflow.com/questions/1849547/groovy-xmlslurper-not-parse-my-xml-file

The first problem was that you cannot have a dash in your XML node unless you embrace it with hyphens like this:
ncbiXML.GBSeq.'GBSeq_accession-version' as String

I guess dashes are otherwise interpreted like dots (separators). I imagined something like that when I encountered the error "no property like that".

After fixing this the code ran through. The tests however still failed as only empty values were returned. The solution was to ignore the top node of the XML input. Starting one node below everything worked fine.

Now, equiped with a nice map I wanted to create domain objects following the helpful steps at the end of this article:

http://thediscoblog.com/2009/02/19/restful-grails-services-in-3-steps/

To make the properties editable before submission, I added a new action to a controller that redirects to "create" and hands over the xml parsed map from XMLSlurper as params.

That would probably have worked if it hadn't been for one property that was not a string, but an object. I thought no problem, all I have to do is use a dynamic finder to get my object with the string. This produces errors as grails interpreted this parameter as String and threw conversion exceptions when trying to parse a string to my object:

Cannot convert value of type [java.lang.String] to required type

I have googled for hours and tried everything, but finally I found the very simple solution. You have to put it like this to convince grails that it has to look up for a domain object itself via id:

ncbiMap.'organism.id' = organism.id

Again, the hyphens are very important. In the beginning I tried different things without them and then grails tries to resolve the dot instead of letting the parameter go.

Now everything works fine and I hope someone can use this to get started real fast on this (not like me :-)

Monday, June 28, 2010

grails-ui autocomplete with "onSelect" event

Today I had my first try in integrating an autocomplete feature. I was more successful than expected due to the very easy to use grails-ui library. You have to put code like that in your controller to serve data to the taglib:
def searchResultsAsJSON = {
     def jsonList = Gene.list().findAll{it.name.startsWith(params.query)}.collect{[id: it.id, label: it.name]}
     
     def jsonResult = [
         results: jsonList
     ]
     render jsonResult as JSON
 }

As you can see you need to provide your data JSON formatted. You also have to use the parameter "query" to filter results that fit what the user has already typed in. Furthermore you can collect only those properties of your domain class that are really necessary for the autocomplete. These are namely an id and a label to display and search. Okay now that we've seen this part, let's have a look at the GSP:

<gui:autoComplete
            minQueryLength="3"
         queryDelay="0.5"
         id="quickSearch"
         resultName="results"
         labelField="label"
         idField="id"
         controller="quickSearch"
         action="searchResultsAsJSON"
  />

Here you can see different options that you can influence, e.g. how many letters one has to type in before the taglib starts AJAX-calling. Although more or less self-explaining, I will say a few words about those properties:
  • idField is the name of the ID field in the JSON output
  • labelField is the name of the label that is displayed for search in the JSON output
  • resultName is the name of the top node used in JSON. In the above example this was results.
At this stage I was already quite happy with my results, but I wanted one more feature that was unfortunately not included. I wanted to define some action when a selection has been made by the user. Therefore I added some javascript to the page:

YAHOO.util.Event.onDOMReady(function() {
   GRAILSUI.quickSearch.itemSelectEvent.subscribe(function(type, args) {
      ${remoteFunction(controller:"quickSearch", action:"showResult", params: '\'name=\'+GRAILSUI.quickSearch.getInputEl().getValue()', update: [success:'body',failure:'body'])};
   });
 });

It took some time to find out how to do this, but finally it worked. What one has to know is:

What event do I have to subscribe to and even more complicated how do I access information about the selected entry? The event's name was itemSelectEvent and I managed to access the DOM element to get the selection's value, but I would be very interested to access the ID of the selected entry, too. Up until now, I could not find the ID anywhere in the DOM. Any comments on this problem are welcome!

Wednesday, June 23, 2010

add drag and drop functionality to GRAILS-UI datatable editors

In my application I have added a GRAILS-UI datatable with in-line cell editing functionality at the bottom of my page. Problem was that the date picker element, which is a big fat, didn't fit onto the page and was unusable though. I asked the mailing list for help about that and Matthew Taylor adviced me to try and manipulate the position via CSS. That did not work for me as I figured out that the position was hard-coded in the style property of the div tag.


When I googled for a solution I found a post where it is explained how drag and drop functionality can be added to a YUI calendar widget. I adapted the solution here. Unfortunately I found no better way as to manipulate GRAILS-UI's source code. I edited DataTableTagLib.groovy around line 215 like this:

case 'date':
 editorConstruction += """
  var ${editorName} = 
  new YAHOO.widget.DateCellEditor();\n
  ${editorName}.subscribe('showEvent', function()
  {var dd = new YAHOO.util.DD(
  ${editorName}.getContainerEl());});\n"""
break;

With this, the date picker has become draggable and can be of use for my users again.

Wednesday, June 16, 2010

grails-ui menubar and ajax with remoteFunction

I wanted to turn the links of the grails-ui menubar into ajax remoteFunctions or remoteLinks. This was - once more - far more complicated than I had anticipated. Fortunately almighty google brought me to the solution. The ugly thing: One has to change the code like stated in the jira. Now another ugly thing about the solution is - as indicated by the author - that one still has to provide a url. Not a problem I thought, but the whole thing did not work at all. I had to spend some time, before I could figure out what was going on:

Both - the URL and the remoteFunction - are executed. The remote function comes first (which is a good thing as we will see), but then the URL kicks in and you have a double page change behaviour. The fix is as easy as you can imagine (I wish someone had told me). You have to add 'return false' at the end of the remote function. This stops the URL href feature from being executed at all. Voilà remote function can reign in peace now.

javascript event mechanism for my application

The more and more I ajaxify my grails application,the harder it gets to keep all information on a site up-to-date. In my worst-case scenario there are dozens of dependencies and it is impossible to think of all of them. So the time for a event mechanism has finally come. Why haven't you done that a long time ago, you might ask. Well, I am not really familiar with javascript and as there is no in-editor correction like in my early Java days on Eclipse, I have had a hard time finding bugs in my code.

Lucky me: the cool guys from the YUI project have already taken the worst complexity of the problem of my shoulders. This means that I have used the YUI2 event utility. There are benefits I can not even imagine as a newbie, but features like automatic scope correction, object pass-throughs, etc. sound very cool and benefitial to me. Here is how I have set the whole thing up:

I have modified the main.gsp to introduce an event handler object. Putting it here makes sure that it will be available on every page:


I have not imported any js files as the necessary files have already been included by other grails plugins (mainly grails-ui). Read the doc if you have to.

One a page where I want to have event functionality I first declare an event (in this case it was within a taglib):


Now, whenever necessary I declare a callback function and register it with the event handler as listener:


The callback functions then usually make use of ${remoteFunction} to update a specific part of the page. I would not have guessed it, but if you got rid of spelling mistakes it works like a charm!

Bookmark TagLib

Today I have created a taglib for creating bookmarks. It needs two attributes attrs.type and attrs.id, where type corresponds to the class name. There is only JS code for Internet Explorer and Firefox included, so unfortunately it won't work on other browsers (yet).

def includeBookmarkThisPageLink = {attrs ->
  def url = request.getRequestURL().toString().replaceFirst(".dispatch", "").replaceFirst("/grails", "") + '/' + attrs.id
  def title = attrs.type.get(attrs.id)
  
  out << """"""
 }

springsource STS hangs on startup

I'm using springsource STS for developing my grails application. Usually it works fine, but today when I started it up, it hung up completly. I had to force quit, but even restarting brought no further result. I looked into workspace/.meta/.log


!ENTRY com.springsource.sts.ide.ui 4 0 2010-06-16 08:09:04.833
!MESSAGE An unexpected error occurred while retrieving feed content.
!STACK 1
org.eclipse.core.runtime.CoreException: Download of http://springide.org/blog/feed/ failed: Unexpected HTTP response 404
at com.springsource.sts.internal.core.net.HttpClientTransportService.toException(HttpClientTransportService.java:205)
at com.springsource.sts.internal.core.net.HttpClientTransportService.stream(HttpClientTransportService.java:187)
at com.springsource.sts.core.HttpUtil.stream(HttpUtil.java:112)
at com.springsource.sts.internal.ide.ui.editors.AggregateFeedJob.run(AggregateFeedJob.java:76)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
!SUBENTRY 1 com.springsource.sts.core 4 0 2010-06-16 08:09:04.833
!MESSAGE Download of http://springide.org/blog/feed/ failed: Unexpected HTTP response 404

From this I knew that there was a problem loading a feed. Google found this for me

http://forum.springsource.org/showthread.php?t=85770

Somebody with the same problem found a workaround: One of the projects is causing the block, god knows why. Rename this project's folder -> Start STS -> Close STS -> Name folder back -> Start STS -> WORKS AGAIN! *YES*

Hopefully, someone finds a solution for this and for another bug for which I don't have a solution (I get update source failed errors with string index out of bounds exception (-34)).

Tuesday, June 15, 2010

grails-ui datatable in-line cell editing and dropdowns

Another post about almost the same topic. How to feed the dropdown options for the in-line editing with values from the database. It is quite simple, although I was running in the wrong direction for some time and I was not the first one with this problem.

The simple answer is: you have to add a groovy collection to your model like this (I wanted to be able to choose a user, so I collected user names from the spring security core user class)

def userNames = User.list().collect{it.username}
render(template: '/layouts/template', model: [userNames: userNames])

Now you can do it like this:

..., config:[dropdownOptions: userNames, disableBtns:true]],...

grails-ui datatable in-line cell editing and dates

Today I am playing with the cool in-line cell editing feature of gui:datatable. I wasn't able to get the datePicker working however until I found the solution in a comment on Matthew Taylor's blog.

Apparently, one has to transform the date into a JSON compatible shape. Lucky for us, Matthew has already provided us with such a method:

grailsUITagLibService.dateToJs(myDateObject)

Okay, parsing the String back to a date in the controller was hard work for me. What has been suggested by Matthew in his DemoController produces exceptions. I had to put some own effort into this:

else if(params.field == "date")
         {
          def simpleDateFormat = new java.text.SimpleDateFormat("E MMM dd yyyy HH:mm:ss ZZZZZZZ", Locale.ROOT);

          Date date = simpleDateFormat.parse(params.newValue)
          passage.date = date
         }

externalize datasource settings

Although common practice, it is not so easy to find out how to externalize your settings in a good way. I found the solution in combination of two posts:

How the property file has to look like:
http://stackoverflow.com/questions/970133/externalizing-grails-datasource-configuration

How it should be included by grails:
http://phatness.com/2010/03/how-to-externalize-your-grails-configuration/comment-page-1/#comment-1484

Wednesday, June 9, 2010

take care when using it in groovy each loop

One mistake I am making over and over is the following situation:

 def someCollection = [...]
 someCollection.each{
   println it // it works here
   doSomethingWithClauses{
     println it // it cannot be resolved here
   }
 }

As soon as you use the it in encapsulated code {}, it cannot be resolved anymore. It took me ages to find that mistake in the first place, but unfortunately I produce something like that quite often and then I wonder what the hell is wrong.

What you have to do to make it right is giving the iteration variable another name:

 def someCollection = [...]
 someCollection.each{ someItem ->
   println someItem // it works here
   doSomethingWithClauses{
     println someItem // hey cool it works here too
   }
 }

Tuesday, June 8, 2010

How to get rid of compiler errors

Today I stumbled about a page that gives a pretty cool introduction in how to setup grails 1.1 in eclipse:

http://www.objectpartners.com/2009/05/27/eclipse-setup-for-grails-11-development/

The author also explains how to get rid of compiler errors that are due to the acegi plugin. This helped to erase almost all of them, for the rest I think I should check whether the grails path is set correctly.

including javascript in gsp

Today I have tried out at least a hundred different ways for including js files into my main.gsp by hand. My approach looked like that:



I tried ${resource} first, but then I found this in grails Q&A:

Q: Why won't XXX Javascript Library Display Properly?

A: Sometimes third party javascript libraries depend upon other resources loaded directly from the javascript files themselves like stylesheets. Examples of libraries that do this would be the Yahoo UI libraries and niftycube. When the javascript attempts to load the URL Grails changes the URL so that the resource is not found. Try adding a link using the createLinkTo tag for the particular resource.

So it tried ${createLink}, but in the end nothing worked. I finally succeeded when I discovered that there was an extra taglib to do the trick with YUI JS files, which I was interested in:



The solution can be found in the most obvious place: http://www.grails.org/YUI+Plugin

Really wish I had looked there sooner :-)

Now I wonder if the problem was YUI specific and if my approach would work on other files. Maybe I'm going to find out some day...

Monday, June 7, 2010

grails, sql, datasource

If you are trying to use groovy.sql.Sql to formulate your own queries: don't use the Sql.executeInsert() method as it won't work on HSQLDB. executeInsert() produces an exception claiming "unknown function". But if you use Sql.execute() you won't encounter such a problem.

Before you ask: the advantage of executeInsert would have been that you get the ids of auto-generated columns as return value(s).

Wednesday, June 2, 2010

Querying simple collections in grails

Imagine a domain class has a collection of simple types like e.g.

class Domain
{
static hasMany[strings: String]
}

What would you do if you wanted to have a set of all instances of Domain that have a string called "blabla". Well my first guess was to use the dynamic method findBy, but this does not work. The same goes for using Domain.withCriteria{}. I found the solution in a jira where you can find a feature request about that. Meanwhile you have to do the querying yourself. I have included a static method within my Domain class to avoid DRYness:

static def match(String matchThis)
{
Domain.executeQuery('from DBUser where :name in elements(strings)', [name: matchThis])
}

Problem solved...

Tuesday, June 1, 2010

datasources plugin for grails

In my current project I wanted to have content and security information separated from application specific settings. I therefore wanted to store the information into separate databases. This was far easier than expected with the datasources plugin from grails. I only had to install the plugin and add the file datasources.groovy to /grails-app/conf/

datasources = { 
 datasource(name: 'ds2'){
  domainClasses([org.openlab.settings.GlobalSetting, org.openlab.settings.UserSetting, org.openlab.security.Requestmap])
  pooled(true)
  driverClassName('org.hsqldb.jdbcDriver')
  url('jdbc:hsqldb:mem:devDB')
  username('sa')
  password('')
  dbCreate('create-drop')
  hibernate {
   cache {
    use_second_level_cache(false)
    use_query_cache(false)
   }
  }  
 } 
}

The usual datasource configuration remains intact and is the core or default database. In datasources.groovy you can define as many additional databases as you like. You only have to follow this pattern where the hibernate information is included as well as the definition of domain classes you wish to store in the new database.

The clear distribution of domain classes to datasources makes this approach easy and the only thing you have to consider are foreign key relations when separating the wrong domain classes.

Monday, May 31, 2010

in-line editing in scaffolded show.gsp

In the default pages created by the scaffolding mechanism of grails, it is quite cumbersome that whenever you want to change a value of a domain class you have to go to the edit page and afterwards back to the show page. Two complete site loads that do not fit into the web 2.0 paradigm.

Usually one would apply in-line editing to bring in a cool and useful AJAX feature and in fact every JS library seems to have built-in support. It is however quite labourous if you have to add this feature manually to every field even if you make things easier with a tag lib as suggested in the book "Beginning Groovy and Grails" by Christopher M. Judd, Joseph Faisal Nusairat and James Shingler.

I thought about the problem and then decided to try to combine scaffolding with this technique. I used the example from the book as a guideline.

I changed the following entry within show.gsp:

<td valign="top" class="value">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>

to:
<td>
 <g:editInPlace 
  id="${p.name}"       
  url="[action: 'editField', id:${propertyName}.id]"
  rows="1"
  cols="10"
  paramName="${p.name}">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}
 </g:editInPlace>
</td>

One can use the TagLib given by the book, but you have to modify the action in order to work with arbitrary fields. Add the following method to the scaffolded Controller.groovy (/src/templates/scaffolding):

def editField = {
  // Retrieve member
  def ${propertyName} = ${className}.get(params.id)
  if(${propertyName})
      {
      ${propertyName}.properties = params
      ${propertyName}.save()
      // Render a new page.
      render params.get(params.editorId)
  }
    }

Thursday, May 27, 2010

Microsoft SQL Server 2005 with GRAILS

Today I found a blog that helped me setting up MS SQL 2005 Express with Grails in a few minutes.

http://lsonline.de/blog/2009/11/grails-with-microsoft-sql-2005/

Sunday, May 16, 2010

Use grailsui Menubar in taglib

The common way of using the grailsui menubar is to incorporate the offered tags like or directly into a template. For my purposes, where I wanted to create a menu based on database properties, I wanted to build a menubar within my own taglib. Although tags can be easily accessed like for example g.createLink(), I had to study the source code of MenuTagLib.groovy to find out what parameters were expected of me. The example shows how it works:

out << gui.menubar(id: 'topMenuBar', renderTo:'top1'){ gui.submenu(label: 'Links'){ gui.submenu(label: 'Search'){ gui.menuitem(url:'http://www.google.de', helpText: 'Google'){ 'Google' } } } }


Here is what caused me some problems: You have to define the parameter helpText (can also be ''). A url is needed, to trigger some controller action you can use createLink. Still have to figure out how to use remoteLink here. The label of the menuitem is not a parameter, but the body of the menuitem {}.

And a last remark: As the menubar did not work properly with my yui layout manager, I had to change two things. First I had to add the parameters zIndex:1 and scroll:null to the layout definition:

{ position: 'top', height: 24, body: 'top1', zIndex: 1, scroll: null },

zIndex tells the layout manager which element overlaps and the default is 0. As this is my onley zIndex higher than 0, the menu will overlap all other parts. Furthermore, scroll: null enables the menu to escape the borders of the div container.

I mentioned a second thing to change: Only if you add the parameter renderTo: 'top1' to the menubar definition, the menubar becomes active.

Friday, May 14, 2010

RichUI TreeView onLabelClick does not work with current YUI

Running into this problem again and again, I decided to finally write down what one has to change in order to make the onLabelClick work again:

The root of the problem is that in the current YUI the name of the action has changed. This is why you have to open the TreeViewRenderer.groovy in the src folder of the RichUI Plugin.

There you have to look for line 36 and switch "labelClick" with "clickEvent". Voilà.

Just a remark: If you want to access the id of the node late - please don't ask why - access node.node.additionalId in contrary to node.id or node.additionalId. Further change that line 37 accordingly.

Thursday, May 6, 2010

YUI layout manager



Yesterday I discovered the YUI layout manager. It is a javascript solutions dividing your browser viewport into up to 5 parts (top, bottom, left, right and center). If you ask, why should I use that thing and not rely on div/css. Here are some advantages I can immediately see here:
  1. It is super easy to produce the basic layout you like in <>
  2. You get cool js effects like resizing, toggling, etc.
  3. You can be sure that the layout works in every browser (YUI is reliable in this).
  4. It looks super cool and is skinnable via CSS.
Here is what you have to do:

Include the following resources:
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.0r4/build/utilities/utilities.js&2.8.0r4/build/container/container-min.js&2.8.0r4/build/resize/resize-min.js&2.8.0r4/build/layout/layout-min.js&2.8.0r4/build/menu/menu-min.js"/>
Include the following script:
<script type="text/javascript">
YAHOO.util.Event.onDOMReady(function() {
var layout = new YAHOO.widget.Layout({
units: [
{ position: 'top', height: 28, body: 'top1' },
{ position: 'right', header: 'Right', width: 300, resize: false, collapse: true, scroll: true, body: 'right1', animate: true, gutter: '5' },
{ position: 'bottom', height: 28, body: 'bottom1' },
{ position: 'left', header: 'Left', width: 200, body: 'left1', gutter: '5', resize: true, scroll: true, animate:true, collapse:true},
{ position: 'center', body: 'center1', gutter: '5 0', scroll: true }
]
});

layout.render();
});
</script>
The options are self-explaining and make the whole thing easy to configure. You can even nest layouts like in the attached screenshot.

Wednesday, May 5, 2010

access templates belonging to plugins - file not found exception

My current web project is split up into several parts. The best way to achieve this was utilizing the plugin mechanism of grails. Unfortunately grails (1.2 SNAPSHOT) is not able to find templates that are part of a plugin. I am quite sure I installed the plugins properly, as controllers, etc. are found.

Apparently, this is a known bug and lucky for me there is also a work-around presented:

render(template:"/bla/foo", plugin:"name-of-plugin", ...) and for gsp <g:render template="/bla/foo" plugin="name-of-plugin" ... />


Works perfectly as soon as you find out what the correct sPelLinG of your plugin is. In the end I used "grails list-plugins" to answer that question.

changing the style of yui treeview



In my project I make use of the YUI-TreeView widget. The CSS files of YUI are - let's say overwhelming. I found a nice description of how to find the correct style classes with Firebug. Here is an example where the developers explain how to obtain a folder style tree view.

I really just wanted to perform a small little change: The focus bg color of the selected tree nodes. This is what you have to override in your CSS:

.ygtvfocus{background-color:#B4CCFF;}

Tuesday, May 4, 2010

passing javascript parameters with remoteFunction

There have been a lot of examples where I needed to pass javascript variables through a remoteFunction in order to Ajax-Update a part of my web application.

I had almost given up when I found the solution in a blog entry. I wasn't able to guess the correct escaping of ' signs on my own, but this solution obviously got it right:

${remoteFunction(controller:'myController',
action:'someAction',update:'targetDiv',
params:'\'oneParameter=\'+jsOneParameter+\'&anotherParameter=\'+jsSecondParameter')};

service dependency injection does not work in scaffolded controllers

When I wanted to access user information in the scaffolding code of the controller (/src/scaffolding/Controller.groovy) my first guess was to define the authenticateService and let dependency injection do the trick. Unfortunately, this approach did not work.

def authenticateService is never injected and therfore a useless null object.

I spent some time on google and it turned out that this is an open issue and that others had stumbled about the same problem. I was happy to see that someone had found a workaround:

def authenticateService = org.codehaus.groovy.grails.commons.ApplicationHolder.application.mainContext.getBean("authenticateService")


Using this approach arbitrary services can be injected into the scaffolded controllers.

session.user does not work with grails acegi plugin

Most tutorials and books introducing grails security concepts tell us that you can access information concerning the user by accessing the session.user object.

As I installed the acegi security plugin to get more advanced security features, this approach didn't work anymore. The documentation provided the solution.

If you are operating on GSPs you can use:

${loggedInUserInfo(field:'userRealName')}, which tells you the real name of the user. The field 'username' would provide you with the login name.

There are also the tags ${isLoggedIn} and ${isNotLoggedIn} to ensure that some content is only available to authenticated users.

But what happens if you want to access this information within a taglib or a controller? You have to include the authenticateService and use it:

Use authenticateService.isLoggedIn() to find out, whether a user is logged in, or not.

And use the following to access the user credentials:
def principal = authenticateService.principal()
println principal.getUsername()//get username
println principal.getAuthorities()//get authorities

Keep attention: If you want to obtain the User object you can no longer search for 'login', but for 'username':

User.findByUsername(principal.getUsername());

Monday, May 3, 2010

missing js files (bubbling library)

As javascript is not entirely my mother tongue, I am using the wonderful GrailsUI plugin to bring some magic to my web project. The plugin itself is making heavy use of the YUI library and the bubbling extension. Therefore, it needs the respective js files in the web-app/js directory.

Today, I messed up my plugin configuration (Subclipse decided to ruin my day) . As a consequence I reinstalled all plugins,. I was quite unhappy with the result, as the GSPs just ignored all the components. Using Firebug, I found out that the js files of bubbling were all missing.

It turned out that the files that were expected to be in the subfolder web-app/js/yui-cms/2-1 were actually in 2.1. Renaming the folder solved that problem.

sharing my thoughts

Hi folks,

just a few words about this blog:

I started developing a new grails application a few weeks ago, and although grails is a great technology that made a lot of things easier for me, there have been a lot of problems I ran into. I could however solve most of them up until now. Most of the solutions I had found with the help of google and often they were blog entries. So I thought I could start to give some of my own solutions or solutions I found on the web, back to the community. The main purpose however, is to remind myself how I had solved a particular problem, so please be forgiving if I am cheap on examples.