Sometimes Groovy is just so sweet.
So, I’m working on some new functionality in a Grails app and I wanted to reuse a previously created widget. For purposes of this discussion, a widget is just a snippet of code for a UI control such as a dropdown box.
That widget was actually two widgets packaged as one: it was one dropdown dependent on, or chained to, another dropdown. If I change the value in the first dropdown, the available values in the second dropdown change. That functionality is driven by some simple jQuery and is easily used via <g:render>.
But in the course of trying to reuse it, I hit upon an interesting dilemma:
- in one context, the object graph had 3 levels (Asset >> Unit >> Agency)
- in a second context, the object graph had only two levels (Unit >> Agency)
(Slightly less problematic was that in one context, the Agency dropdown was a required field and in all other contexts, it was optional. That’s why the requiredAgency variable was used — to drive whether to display a “*” next to the dropdown label).
Here’s the resulting solution:
<div>
<label for="agency">
<g:message code="agency.label"/><g:if test="${requiredAgency}"><span>*</span></g:if>
</label>
<div>
<div id="agencyDiv"> %{--Needed for IE9--}%
<g:select id="agency"
name="agency.id"
from="${Agency.list()}"
optionKey="id"
optionValue="name"
value="${parentInstance?.agency?.id}"
noSelection="${['null':'--Select One--']}"
/>
</div>
</div>
</div>
The “trick”, which is really elegant in its simplicity, is to pass in a parentInstance variable to the dropdown. If present, it’ll make use of it. If not passed in, it’s null. And if it’s null, this piece…
value="${parentInstance?.agency?.id}
…will cause agency to just “slide to the left”.
Here’s how it’s called in a context where I do use parentInstance:
<g:render template="/includes/widgets/chainedAgencyUnitDropdownsUsingUnit"
model="${[parentInstance: assetInstance?.unit, theInstance: assetInstance]}"/>
And here’s how it’s called without parentInstance:
<g:render template="/includes/widgets/chainedAgencyUnitDropdownsUsingUnit"
model="${[theInstance: employeeInstance, requiredAgency: true, requiredUnit: true]}"/>
Now, I’ve used the ?. operator a ton of times. It’s indispensable. I cry when I have to work on a raw Java project and do some silly Utils.isNullOrBlank(object) call. But I guess I never considered how the ?. operator would act when governing the very first object. I didn’t expect only that portion to “disappear” while leaving the rest of the line to be evaluatable.
The more I use Groovy the more attached I get to it. It’s so brilliant in terms of usability.






