Skip to main content

Resolving CSS Issues With Grails UI Plugin

I'm working on another Grails application and am using the fantastic Grails UI plugin for a lot of the UI controls. Grails UI is a really nice Grails-friendly wrapper around the YUI components and includes things like a dialog box, calendar controls, a rich text editor, and a whole lot more. This was my first real foray into using this plugin, so I started with a simple modal dialog box that would show the contact information details for people in a simple list.

The main point of this post is to outline the simple resolution to the CSS issues I was seeing because it took me a while to figure out what was going on, but I thought I'd outline some Grails and Grails UI magic along the way.

First, in order to use the Grails UI plugin you of course have to install it, which is as simple as:

grails install-plugin grails-ui

Next, on any view page on which you wish to use any Grails UI resources, you have to indicate which resources you're going to use on the page. The nice thing about this is it will only load the JavaScript for the specific UI resources you need on each page. In the case of this example I'm only using a dialog box, so I have this line in the head section of my view page:

<gui:resources components="dialog" />

Also in my head section I need to tell Grails I'll be using some AJAX on this page, so I use the javascript tag to load the Prototype library:

<g:javascript library="prototype" />

With Protoype loaded, pulling the contact details to be shown in the dialog box is dead simple using the Grails remoteLink tag:

<g:remoteLink controller="person"
               action="showDetail"
               id="${person.id}"
               update="personDiv"
               onComplete="showPersonDialog();">${person}</g:remoteLink>

If you're not familiar with Grails, what this does is tells Grails to make an AJAX call to the person controller, call the action showDetail, and pass the ID of the person object. We'll see what's returned by the AJAX call in a moment. The update attribute of the remoteLink tag tells Grails what DOM object to update with the results of the AJAX call, and the onComplete attribute indicates a JavaScript function to call when the AJAX call is complete.

If all I was doing was updating a DIV on the page I wouldn't need this, but since I need to show the Grails UI dialog box after I pull the contact details, I need a JavaScript function to handle that, so I added this to the head section of the view page:

<script type="text/javascript">
    function showPersonDialog() {
        GRAILSUI.personDialog.show();
    }
</script>

Next, let's check out the showDetail action in my Person controller to see what it's doing when the AJAX call is made:

def showDetail = {
    def personInstance = Person.get(params.id)
    if (!personInstance) {
        def message = "No person found with ID ${params.id}"
        render(view:"personDetail", model: [message : message])
    } else {
        render(view:"personDetail", model: [personInstance : personInstance])
    }
}

Here's the simple view that's rendered in the controller action above:

<g:if test="${message}">
    <p>${message}</p>
</g:if>

<g:if test="${personInstance}">
    <p>
        <strong>${personInstance.firstName} ${personInstance.lastName}</strong><br />
        ${personInstance.email}<br />
        Phone: ${personInstance.phone}<br />
        Cell: ${personInstance.cell}
    </p>
</g:if>

And finally, here's the code for the Grails UI dialog box and the DIV that is populated with the view above:

<div class="yui-skin-sam">
    <gui:dialog id="personDialog"
                width="400px"
                title="Contact Details"
                draggable="true"
                update="personDiv"
                modal="true">
        <div id="personDiv"></div>
    </gui:dialog>
</div>

This is all pretty straight-forward. What was happening, however, is when the dialog box was shown, there was no CSS being applied to it. The YUI components that are used by the Grails UI plugin have stylesheets associated with them, but when I checked the source code of the rendered page they seemed to be getting included just fine, and as you can see above I wrapped the dialog box in a div with the correct CSS class, which is yui-skin-sam.

At this point it's important to remember that when a Grails page is rendered it uses SiteMesh, which is basically a templating/page decoration framework. As many Grails applications do, I was using a main.gsp layout page, and each individual view page gets woven into this main template.

Therein lies the problem. As I said above this was simple enough in the end but since it took me a while to figure out I thought I'd share. Even though the YUI CSS was being included in the individual view page with the dialog box code on it, for some reason the CSS wasn't getting applied. I decided to experiment and put the yui-skin-sam class in the body tag in my main.gsp layout page, and this solved the problem.

In my case I didn't have any conflicting CSS involved so this solution didn't cause any issues, but if you have other CSS involved and applying a class to the body tag in the main layout page will cause issues, you can add the additional CSS references after the <g:layoutHead /> tag in the main layout page, and this will allow you to override any CSS that came earlier.

With all this in place the Grails UI components are being styled correctly and they're extremely nice additions to any Grails app.

Comments

Popular posts from this blog

Running a Django Application on Windows Server 2012 with IIS

This is a first for me since under normal circumstances we run all our Django applications on Linux with Nginx, but we're in the process of developing an application for another department and due to the requirements around this project, we'll be handing the code off to them to deploy. They don't have any experience with Linux or web servers other than IIS, so I recently took up the challenge of figuring out how to run Django applications on Windows Server 2012 with IIS.

Based on the dated or complete lack of information around this I'm assuming it's not something that's very common in the wild, so I thought I'd share what I came up with in case others need to do this.


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Assumptions and CaveatsThe operating system is Windows Server 2012 R2, 64-bit. If another variant of the operating system is being used, these instructions may not work properly.All of the soft…

Installing and Configuring NextPVR as a Replacement for Windows Media Center

If you follow me on Google+ you'll know I had a recent rant about Windows Media Center, which after running fine for about a year suddenly decided as of January 29 it was done downloading the program guide and by extension was therefore done recording any TV shows.

I'll spare you more ranting and simply say that none of the suggestions I got (which I appreciate!) worked, and rather than spending more time figuring out why, I decided to try something different.

NextPVR is an awesome free (as in beer, not as in freedom unfortunately ...) PVR application for Windows that with a little bit of tweaking handily replaced Windows Media Center. It can even download guide data, which is apparently something WMC no longer feels like doing.

Background I wound up going down this road in a rather circuitous way. My initial goal for the weekend project was to get Raspbmc running on one of my Raspberry Pis. The latest version of XBMC has PVR functionality so I was anxious to try that out as a …

Fixing DPI Scaling Issues in Skype for Business on Windows 10

My setup for my day job these days is a Surface Pro 4 and either an LG 34UC87M-B or a Dell P2715Q monitor, depending on where I'm working. This is a fantastic setup, but some applications have trouble dealing with the high pixel density and don't scale appropriately.
One case in point is Skype for Business. For some reason it scales correctly as I move between the Surface screen and the external monitor when I use the Dell, but on the LG monitor Skype is either massive on the external monitor, or tiny on the Surface screen.
After a big of digging around I came across a solution that worked for me, which is to change a setting in Skype's manifest file (who knew there was one?). On my machine the file is here: C:\Program Files\Microsoft Office\Office16\LYNC.EXE.MANIFEST
And the setting in question is this:
<dpiAware>True/PM</dpiAware>
Which I changed to this: <dpiAware>False/PM</dpiAware>
Note that you'll probably have to edit the file as administr…