How to implement Master/Detail forms using Spring Roo

I jumped in the Spring Roo wagon since version 1.1.0M1. The first thing I wanted to do after got used to it. It was to try typical requirements that come very often in the work of a Web Developer. I needed a wep app to work on, so I came up with World Alamac by jD. Basically, WorldAlmanac web site is an experimentation test bed for using Roo. You can visit World Almanac and other Roo-based showcases at https://pragmatikroo.org/showcases. I created a list of things that I wanted to try: master/detail forms, reports creation, pdf generation, images rendering and SEO to mention a few. Let’s start with the first item of the referred list. The article assumes the Reader is a Developer with familiarity with Spring Roo. For information about Spring Roo please visit the project web site: http://www.springsource.org/roo.

World Almanac Master/Detail Form

The web application uses a database with data of the Countries, Cities and Languages spoken in the Earth. I selected the Country/City entitiesto build a master/detail web form. You can try the web form at http://pragmatikroo.org/worldAlmanac/ on the Cities menu. As I formalized the master/detail implementation, I realized that it could be get it, as the composition of two list.jspx from the tagx library included with Roo. A top list.jspx for the upper grid (Countries) and another one for the lower (Cities). Some basic grid events are required as well: independent upper and lower navigation, Cities rendering -after country selection- and grids state management.

Countries Web Form

Master Grid View

The master/detail form is rendered using a customized form created by a finder Roo command. The upper grid code is shown below: Master Grid Client Code
<page:list id="pl:org.josean.rooworld.domain.Country" items="${countrys}" z="fmh1dw5QkHal9+wnb0JDqVvC1f8="> <tblchooser:tblchooser data="${countrys}" maxPages="${upperTblMaxPages}" page="${upage}" size="${usize}" pageid="upage" sizeid="usize" anchorURL="${upperTblAnchorURL}" id="l:org.josean.rooworld.domain.Country" path="/citys" typeIdFieldName="${upperTypeIdFieldName}" z="1FSBfbX2cD9Hf48J/CgEpgGqM5I="> <table:column id="c:org.josean.rooworld.domain.Country.name" >Detail Grid Client View</h2>
<img src="//www.viralpatel.net/app/uploads/2011/01/spring-roo-country-selection-form.png" alt="" title="spring-roo-country-selection-form" width="661" height="446" class="size-full wp-image-2147" />

Countries/Cities Web Form after a country selection (Australia)

<h2>Detail Grid Client Code</h2> <!-- wp:code {"language": "xml"} --><pre class="wp-block-code"><code></code></pre><!-- /wp:code --> <page:list id="pl:org.josean.rooworld.domain.City" items="${citys}" z="?"> <table:table data="${citys}" id="l:org.josean.rooworld.domain.City" maxPages="${lowerTblMaxPages}" page="${lpage}" size="${lsize}" pageid="lpage" sizeid="lsize" typeIdFieldName="${lowerTypeIdFieldName}" anchorURL="${lowerTblAnchorURL}" path="/citys" select="false" z="fsLaGs5Dtou//oijKgETnKUig+Q="> <table:column id="c:org.josean.rooworld.domain.City.name" >Server Side code</h2> <!-- wp:code {"language": "java"} --><pre class="wp-block-code"><code></code></pre><!-- /wp:code --> @RequestMapping(params = { "find=ByIncountry", "form" }, method = RequestMethod.GET) public String CityController.findCitysByIncountryForm( @RequestParam(value = "upage", required = false) Integer upage, @RequestParam(value = "usize", required = false) Integer usize, @RequestParam(value = "lpage", required = false) Integer lpage, @RequestParam(value = "lsize", required = false) Integer lsize, @RequestParam(value = "ctryselected", required = false) String ctryselected, ModelMap modelMap) { modelMap.addAttribute("update", false); modelMap.addAttribute("delete", false); modelMap.addAttribute("create", false); if (upage != null || usize != null) { int sizeNo = usize == null ? 10 : usize.intValue(); modelMap.addAttribute( "countrys", Country.findCountryEntriesAllObj( upage == null ? 0 : (upage.intValue() - 1) * sizeNo, sizeNo)); float nrOfPages = (float) Country.countCountrys() / sizeNo; modelMap.addAttribute( "upperTblMaxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages)); modelMap.addAttribute("upperTblAnchorURL", "/citys?find=ByIncountry&form"); modelMap.addAttribute("upperTypeIdFieldName", "code"); modelMap.addAttribute("upage", upage); modelMap.addAttribute("usize", usize); } else { modelMap.addAttribute("countrys", Country.findAllCountrysAllObj()); } if (ctryselected != null) { int sizeNo = 10; lpage = lpage == null ? 0 : lpage.intValue(); int numOfCities = City.countCitiesByCountry(ctryselected); int nrOfPages = (int)Math.ceil(((double)numOfCities) / sizeNo); int from = ( lpage ==0? 0 : (lpage.intValue()-1) * sizeNo ); if (nrOfPages >= 1){ modelMap.addAttribute("citys",City.findCitysByIncountry(ctryselected,from, 10)); } else { modelMap.addAttribute("citys",City.findCitysByIncountry(ctryselected,0,numOfCities)); } modelMap.addAttribute("lowerTblMaxPages", nrOfPages); modelMap.addAttribute("lowerTblAnchorURL","/citys?find=ByIncountry&form&ctryselected=" + ctryselected+ "&upage=" + upage + "&usize=" + usize); modelMap.addAttribute("lowerTypeIdFieldName", "id"); modelMap.addAttribute("lpage", lpage); modelMap.addAttribute("lsize", lsize); } else { if (ctryselected == null) modelMap.addAttribute("citys", null); } return "citys/findCitysByIncountry"; }
Code language: HTML, XML (xml)
This method code handles the master/detail, countries/cities form of WorldAlmanac web app. As you can see it follows closely the client side. The upper section handles the countries grid population and its navigation. The ctryselected is a pivot the actives the lower section on country selection on the web form. There is not much else to explain here. Basically, it is a light customization of the source code generate by Roo. That is it!

Download Source

Click here to download source code (ZIP, 3kb)

Conclusion

This is WorldAlmanac master/detail implementation -using Spring Roo- in a nutshell. I sincerely look forward to helping some colleagues Developers that have requested details and source code of it. It is more a detailed description than a ready-to go code. However, I truly believe that the approach can be applied to any particular project. It is a simple implementation that uses nothing more than Spring Roo as it was wrapped in version 1.1.0M1. The components might need some tweak since Roo has evolve since code inception. Further questions would be handled using the blog.

View Comments

  • Hi Viral,

    This is nice, I want to create a grid in spring roo and set action ADD/UPDATE/DELETE in this grid so please help me

  • Hi Mr. JD

    I just wonder how far did you get on the springroo book you have mentioned sometime ago that you would be working latetlly. Shall we expect something to be released soon?

    • Hola leandro,

      Thank you very much for asking it...
      Bad news first:
      No luck so far... I thought the best way to get the attention of a book house was by getting the endorsement of VIP on the Spring Roo. I contacted them and initially it seemed that they might support me with it. But never happened. On the other hand it seems the book houses go first with theirs "traditional" authors first or I haven't introduce myself like a viable author for them.

      Good news:
      I am accumulating more solutions for recurrent questions shown in the Spring Roo forum and others. So now I have material for several books. Like SR and mobile web apps, SR and jQuery and others.

      Finally, I believe that eventually one of these book houses would realize that my approach of publishing books dedicated only on answering questions posted in the forums is a very-very good seller. Why because they are unique in some cases or very hard to find.

      I am open to suggestion too!
      B. Roogards
      jD

      • The referred letter was sent to VIP in the SR "Team." I missed the word team previously.

        I have to ask my friend Viral Patel how to edit a posted blog for the next time.

        Thank you
        jD

  • Thanks for posting these useful articles on Spring Roo. As I do not have access to Maven Central Repository I am unable to fully utilize the downloadable zip file you have provided us. Wondering if you might be able to have a full web project available for download?

    Please keep on sharing your valuable knowledge and experience. Thanking you again.

  • First of all, Thanks for this Article., it's gives us how far can we go with Spring Roo Technology.

    Now i am Beginner in Spring Roo and i want to implement your suggest solution in three level of relationships.

    therefor, I try many times to implement your solution only between to tables , but didn't work. The reasons are :

    To customize the generated Controller.
    To customize the JSPX Views, i had some difficultes , because of the Tags Elements and the complexity of generated code for the Web Interface.

    one another thing is about the "tablechooser " Tag. it's not working form me, it's give me some errors in the level of "findCitysByIncountry.jspx", because some of "jsp:directive.attribute" aren't found.

    I spend a lot of time, without any result, I ask you now for your Help, if you might.

    Best Regards,
    Yassin

  • Hello jD, Your articles are excellent. I have many years Java back ground, I'm interested in learning by doing some roo and rad stuff. Can you email me and I want to discuss a possible arrangement with you. I'm also on gtalk. - icancertify@gmail.com .

    Thanks and keep doing the great work,
    Ron

Recent Posts

  • Java

Java URL Encoder/Decoder Example

Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…

4 years ago
  • General

How to Show Multiple Examples in OpenAPI Spec

Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…

4 years ago
  • General

How to Run Local WordPress using Docker

Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…

4 years ago
  • Java

Create and Validate JWT Token in Java using JJWT

1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…

4 years ago
  • Spring Boot

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…

4 years ago
  • Spring Boot

Spring Boot DynamoDB Integration Test using Testcontainers

1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…

4 years ago