Table Responsiveness Tip #2: Using shy for soft-hyphens

As a colleague pointed out regarding the optional line-breaks in previous article, a more natural way of breaking up a compound word visually is using a hyphen (-).

More specifically, an optional hyphen, aka the soft hyphen which in HTML can be used as $shy; ­

Apply them where you wish the break to occur:

<thead>
 <tr>
 <th>Voor&shy;naam</th>
 <th>Achter&shy;naam</th>
 <th>Geboorte&shy;datum</th>
 </tr>
</thead>

And the result is now shown with optional hyphens:

According to QuirksMode $shy; is supported now by all the major browsers.

Table Responsiveness Tip: Adding Line-Breaks in Table Headers

You might all know the <br> tag which causes a hard line-break, but did you know you could also use an optional line-break?

It’s called <wbr>

I causes a potentional line-break if you have long words in your HTML which the browser can use to break on. This has been finalized in HTML 5.

Where could you possibly use this? Well, for table headers for instance.

Most of the longest English words are not likely to occur in general text, and headers with multiple, small words – such as Start Date, First Name etc – are pretty common.

When using business- or technical lingo, or non-technical present-day text in other languages, you might not be so fortunate. Take the same labels in Dutch (NL).

<thead>
    <tr>
        <th>Voornaam</th>
        <th>Achternaam</th>
        <th>Geboortedatum</th>
    </tr>
</thead>

The Dutch just tend to use compound words – which are words such as grandmother, footprints, weatherman etc – a lot. Labels can become longer than the associated content in the table cells, which causes the table not to be that responsive anymore on smaller screens because the browser doesn’t know how to break long words anywhere.

Let’s adjust to a smaller screen size:

The browser naturally wraps the English words at the space between the words, so the English First Name and Last Name headers wrap perfectly onto multiple lines. Although the content of the table still fits the screen, the Dutch compound headers do not wrap and horizontal scroll bar appears earlier than needed :-)

Now this is where <wbr> comes in – you can add these in the compound words where you naturally would want to break it up if space becomes sparse.

Let’s see the new HTML:

<thead>
    <tr>
        <th>Voor<wbr>naam</th>
        <th>Achter<wbr>naam</th>
        <th>Geboorte<wbr>datum</th>
    </tr>
</thead>

And the result is what we want: a non-visible break which kicks in when needed.

Grails’ JSONObject.NULL More or Less Equal To Null

Since Groovy 1.8 we can check if a Map is equal to another Map if the keys and values are the same. Very convenient in tests for example.

def someMap = [age: 34, name: "Ted"]
assert someMap == [name: "Ted", age: 34] 

Today I kept staring at a failure, while testing some x and y graph data points returned by a Grails controller, where two Maps were somehow not equal according to Spock, while even the assertion’s output looked ‘equal’.

when:
controller.milkYield()

then:
response.json

and: "series are present"
def series = response.json
series.size() == 2

and: "realized series is correct"
...
and: "predicted series is correct"
def predictedSeries = series[1]
predictedSeries.values.size() == 2
predictedSeries.values[0] == [y:null, x:'Mar']
predictedSeries.values[1] == [y:121, x:'Apr']

resulted in:

Condition not satisfied:
predictedSeries.values[0] == [y:null, x:'Mar']
|               |     |   |
|               |     |   false
|               |     [y:null, x:Mar]
|               [[y:null, x:Mar], [y:121, x:Apr]]
[values:[[y:null, x:Mar], [y:121, x:Apr]]]

Why isn’t [y:null, x:Mar] equal to [y:null, x:Mar]?

After having checked explicitly with

predictedSeries.values[0].x == 'Mar'
predictedSeries.values[0].y == null // <- better be null!

I remembered again I was dealing with JSON data in Grails, which uses the Null Object pattern. Keeps biting me every now and then :-)

Condition not satisfied:
predictedSeries.values[0].y == null
|               |     |   | |
|               |     |   | false
|               |     |   null (org.codehaus.groovy.grails.web.json.JSONObject$Null)
|               |     [y:null, x:Mar]
|               [[y:null, x:Mar], [y:121, x:Apr]]
[values:[[y:null, x:Mar], [y:121, x:Apr]]]

Grails JSONObject null

It’s a JSONObject$Null instance. It exists because it’s equivalent to the value that JavaScript calls null, whilst Java’s null is equivalent to the value that JavaScript calls undefined.

There are some long time posts already describing this behaviour that JSONObject.NULL was not equal to null

JSONObject.NULL.equals(null) // true
JSONObject.NULL == null // false!!

and some meta-class changes you could do were suggested at the time. Seems reported GRAILS-7739 (Wrong == and asBoolean behavior for JSONObject.Null) says it’s been fixed a few years back in Grails 2.2.

Atleast something has been fixed. Although you still can not do JSONObject.NULL == null, you can change the assertion to using Groovy Truth since !JSONObject.NULL does work.

!predictedSeries.values[0].y
// or predictedSeries.values[0] == [y: JSONObject.NULL, x:'Mar'] if you like

And of course I should remember null in (console) output is always a String representation leading to “null” – such as JSONObject.NULL‘s toString() returns.

Grails 3 Released: Installing Gradle and Groovy 2.4 Support in Eclipse/GGTS

Grails 3 has been released with a ton of new features.

GGTS logoIf you’re used to adding a new Grails distribution in Eclipse or Groovy/Grails Tool Suite, you’ve might have experienced that your good old IDE might not support Grails 3 projects right out of the box.

You might be missing:

  • Grails 3 support at all :-)
  • Gradle support
  • Groovy 2.4 support

Here’s how I think you can fix some of these things.

Grails 3 support

As you regularly do with new Grails distributions is to add it in GGTS under Preferences > Groovy > Grails. But dang!…it doesn’t recognize the grails-3.0.x-directory you just unzipped a minute ago.

GGTS doesn't recognize Grails 3

No worries! We have Gradle now.

Gradle is the new Grails 3 build system, in favor of Gant. If you’ve created e.g. the helloworld-application as used in the Getting Started section of the manual, you see a few files like build.gradle and gradle.properties.

Because of this we don’t need a specialized IDE plugin perse, since existing Gradle tooling can do the trick! So we skip adding a Grails 3 distribution and we look for…

Gradle support

It is possible that GGTS doesn’t know to import a Grails 3 project into your workspace, because of missing Gradle support. You can:

Generate Eclipse/GGTS…

  1. … files with gradlew eclipse.
  2. This will generate .project and .classpath which will allow you to “import it as an existing project” into your workspace

or install Gradle support

  1. Open Eclipse Marketplace, search for “gradle”
  2. Choose e.g. the Gradle IDE pack or just the Gradle Integration plugin
  3. Now you can find and import your project too

In GGTS your Grails 3 project is just a “regular” Gradle project.

Hello world!

The above screenshot is possibly an idealized view – it might as well that you have some red markers! I did.

Grails 3 comes with Groovy 2.4, and if you don’t have the correct version set, you get:

Groovy: compiler mismatch Project level is: 2.4 Workspace level is 2.3
Groovy compiler level expected by the project does not match workspace compiler level.

It’s similar as when you had to install Groovy 2.3 into GGTS :-) You can fix the project level to 2.3 but then you get

Groovy:Unexpected problem with AST transform: The Spock compiler plugin cannot execute because Spock 1.0.0-groovy-2.4 is not compatible with Groovy 2.3.10. For more information, see http://versioninfo.spockframework.org

You’ll have to get…

Groovy support

Assuming you don’t already have it, we have to install the Groovy Compiler 2.4 Feature into GGTS.

1. Go to Help > Install New Software and use the update site http://dist.springsource.org/snapshot/GRECLIPSE/e4.4/

2. Select the Groovy 2.4 compiler and Next.

GRECLIPSE update site

3. If there’s a conflict, just press on – it’ll install Groovy 2.4 next to the other versions.

GRECLIPSE update site - just continue!

4. Continue all the way. Finish, restart.

5. Switch the compiler for the workspace. Go to Preferences > Groovy > Compiler and switch to 2.4.3.

Switch to Groovy 2.4.3 compiler

Done.

Happy programming!