To-do list in Grails
In the previous issue of JavaExpress I showed how to start working with Grails; install the environment, create the first project, domain classes with restrictions and how to use dynamic scaffolding. Now let us create a simple to-do list in Grails bottom-up. You will see how to develop a controller, use basic facilities of GORM and create custom views – crafting a CRUD application manually, without generating anything.
Creating a project and a domain class
Let us begin with creating a new project named ToDo. As we all remember from     the previous article, this is all you need to do to start working with a     Grails project – HSQLDB and Jetty bundled with Grails are ready to work.     Let us create a domain class named Task. The task will have a     subject, a due date and a “finished” flag.
    class Task {
        String subject
        Date dueDate
        Boolean completed
        static constraints = {
        }
    }
Creating a controller
The next step is creating a Task controller (like with a domain class, a     controller can be created using the context menu of the project or using the     command line). Let us define the following methods in it: list,     edit, save, delete. They will be     responsible for: displaying a list of tasks, displaying     a form to add/edit a record, saving a record (a new or modified one) and     deleting a record accordingly.
Retrieving records
Let us take the list action first. Passing data from a controller to a view in Grails is done by returning a map from an action. Keys of the map will represent variables available in the view. Our action can look like this:
    def list = {
        [tasks:Task.findAll()]
    }
The map is created using the square brackets notation. There will be a list of tasks retrieved from the database under the key tasks. You may notice a Groovy language feature – the lack of the return keyword. By default the result of the last executed statement is returned, in the above case the created map.
To make things complete we need a GSP file which will render our tasks. Select Views and Layouts -> task from the project, New -> GSP File from the context menu and type list as the name. Grails uses the convention-over-configuration principle, so the view file is named exactly the same as the action. If needed Grails could render any other view, but now the out-of-the-box functionality is sufficient.
Let us add the following code to our view:
    <g:each in="${tasks}" var="task">
        ${task}
    </g:each>
We are using here a tag bundled with Grails which lets us to iterate over a     collection of elements in the view. The in attribute holds the variable over     which we will iterate. The var attribute defines the name of the element in     the iterations. Without setting this attribute the element will be named it,     just like the default parameter in closures. You could add a status attribute     which will be the name of a variable storing a counter of the iterations     (useful when creating numbered lists etc.)
You could try and run the project to test it, but we do neither have any records nor a view to add them.
BootStrap.groovy
We will get a little help from the BootStrap.groovy file. It     contains the init section which is executed during the application     start-up. We can add the following code to it:
    new Task(subject:"Pranie", priority:1, dueDate:new Date(), completed:false).save()
This code will create one task and store it in the database. The example shows also how to create class instances passing values of its attributes – it is another nice feature of Groovy. Grails also gives us the ability to create an instance of a domain class with an automatic assignment of HTTP request parameters to attributes. We will use it later in saving a new task.
After such a modification of the BootStrap file our application should display the first task on the list.
Adding and editing a record
Adding and editing a record will be done using a shared view. If no identifier     is passed, the application will display an empty form to add a new task. In     the case when there is an identifier, before displaying the form the application     will retrieve the appropriate record to edit it. Storing the records will be     done in a shared method save.
Let us prepare the edit view (similarly to the list     view). You do not have to write anything in the controller in the edit action,     because we want only to add a new record. An empty form will be sufficient.     It may look like this:
    <g:form name="addForm" action="save" id="${task?.id}">
        Subject: <g:textField name="subject" value="${task?.subject}"/><br/>
        Due Date: <g:datePicker name="dueDate" value="${task?.dueDate?:(new Date())}"/><br/>
        Completed: <g:checkBox name="completed" value="${task?.completed}"/><br/>
        <g:submitButton name="save" value="Save" />
    </g:form>
A new g:form tag is show here. It is used to build HTML forms     together with g:textField, g:datePicker, g:checkbox     and g:submitButton. I encourage to read the documentation     regarding the possible attributes used to configure these tags. Two new     interesting Groovy features appear in this code as well: the ?.     safe navigation operator which prevents a NullPointerException     to be thrown (when the left operand is null the whole     expression returns null as well) and ?: which works     similar to its counterpart in Java (if the expression on the left is null     or false the right expression is returned, otherwise it stays     the same). Thanks to handling the null and default values the     form can be used to both editing records and adding new ones.
The form sends data to the save action which stores a new record:
    def task = new Task(params)
    task.save()
    redirect(action:"list")
This action creates a new Task object based on the passed map of     HTTP request parameters (params). Then it stores the record and     performs a redirect to the list action.
Let us add a link allowing us to edit a record and modify the edit     action to retrieve a record before displaying the form. Start with the list view:
    <g:each in="${tasks}" var="task">
        <g:link action="edit" id="${task.id}">${task}</g:link><br/>
    </g:each>
The g:link tag is introduced here which allows us to create links.     As you might have noticed Grails supports passing names of controllers,     actions and identifiers in forms and links. Adhering to the Grails convention     simplifies work, but it is possible to control it if needed.
The modified edit action looks like this:
    if (params.id) {
        [task:Task.get(params.id)]
    }
If the request parameter named id is passed, the application is retrieving a     Task record with that id. The condition used here     looks quite interesting. The params variable is a map containg the HTTP request     parameters which are of type String. How does it work then? It     is another interesting feature; Groovy Truth. Not only     boolean type expressions can be used in conditions. 0 (zero), an empty string,     null, an empty array on an empty map are also treated as false in conditions.     It simplifies many expressions.
The only remaining thing is modifying the save action. Before     it only created a new record based on the request parameters, now it will     have to update an existing record as well:
    def task
    if (params.id) {
        task = Task.get(params.id)
        task.properties = params
    } else {
        task = new Task(params)
    }
    task.save()
    redirect(action:"list")
Deleting a record
In order to delete record let us add a new link next to each record which would     trigger the delete action. Everyone will manage to create it by     himself.
And how will the controller action look like? Not to complex as expected:
    def task = Task.get(params.id)
    task.delete()
    redirect(action:"list")
Similarly to the save action the application retrieves a record based on the request parameter. Next it is deleted and the list of tasks is displayed.
Summary
In this article I have shown how to create a simple Grails application with all CRUD operations. This time no scaffolding was used and everything was done manually. The application is not very complex, but it is fully functional and what is most important – it did not take too much time. The basic features of GORM (Grails Object Relationship Mapping) were introduced which allowed us to retrieve, store and delete records. We know what a domain class, a controller and views (the basic components of Grails) look like. At the same time some interesting features of the Groovy language were mentioned.
What next
It is widely known that solving problems improves learning. As an exercise I suggest performing the following tasks:
- modifying the task list to be more readable and user-friendly;
 - introducing data validation (e.g. the task subject not being empty).         As a hint: the constraints section of a domain class and validate method.         The 
g:renderErrorstag will be useful as well; - adding a sidebar menu on the page. As a hint: modifying the page layout by adding an additional element which is the menu.
 
The source code is located at http://code.google.com/p/javaexpress-grails-todo/. Maybe some of the readers would like to contribute to this project. Best wishes and have fun.
Translation by Paweł Cegła

            
Odniosłem wrażenie, że artykuł napisany jest po łebkach :/ Wykonuje instrukcje krok po kroku i niestety pierwsze uruchomienie w moim przypadku kończy się błędem. I to jeszcze w NB w którym wszystko działa out of the box.
Udało mi się uruchomić przykład, ale dalej mam wrażenie, że niektóre punkty można napisać jaśniej (np. gdzie dokładnie utworzyć list.gsp).
Super, że się udało. W każdej chwili możesz skorzystać z grupy dyskusyjnej JAVA exPress. Na 100% znajdzie się ktoś, kto będzie Ci w stanie pomóc. Czasami ciężko jest trafić do każdego. Z jednej strony są ludzie tacy jak Ty, którzy potrzebują dokładnych instrukcji (co jest zrozumiałe w przypadku technologii której nie znasz), a z drugiej strony pojawiały się głosy (z tego co pamiętam to na dzone), że przykład jest zbyt uproszczony.
W przypadku dalszych problemów spróbuj napisać na naszą grupę dyskusyjną. Na 100% znajdą się osoby, co będą chciały Ci pomóc.
Spoko :) Dzięki za zainteresowanie. Jasne, że ciężko trafić do każdego, ale dobrze, że przynajmniej podejmuje się próbe. Fakt, że Grails nie znam zupełnie. No i wielkie szacun za JavaExpress!