data binding « Intelligrape Groovy & Grails Blogs

Posts Tagged ‘ data binding ’

Getting started with knockout.js

Posted by on September 26th, 2012

Recently, I learnt something very new e.g. Knockout.js. It is quite a advanced form of javascript. It just simplifies the structure of the javascipt in your application. It basically follows MVVM pattern(Model View View Model). It is quite fast and easy to use as comparison to jquery.

Some of it’s key features are :-

1. Declarative bindings
2. Automatic UI refresh
3. Free, open source (MIT license)
4. Pure JavaScript — works with any web framework
5. Supports all mainstream browsers
6. Templating(Quickly generate sophisticated, nested UIs as a function of your model data)

I’ll be covering the very basics of it in this article. In this, you need to deal with KO’s (Knockout objects). These are used to bind data with your model objects.

For using it add knockout-x.y.z.js in your application. Now, Moving towards how to use it :-
For example, Declaring model as below :-
E.g

  var firstModel = {
    empName: 'Gaurav',
    empWeight: 72
};

Then we need to create view for this e.g.

 Weight of emp <span data-bind="text: empName"> is <span data-bind="text: empWeight"> kgs.

Here KO wil bind the model object to these data-bind attribute and you will get the required details. But, this will not display the data as such, You need to activate the KO’s for binding the data.
e.g

<script>
  ko.applyBindings(firstModel);
</script>

After this you will be having the desired results.e.g Weight of emp Gaurav is 72 kgs.

So, You can see the declarative data binding of knockout.js. It is having lot more features. I’ll come up with all those.
Just give it a try. :)

Thanks & Regards,
Robin Sharma,
Intelligrape.
@er.robinsharma

Grails 2.0 action arguments data binding

Posted by on February 20th, 2012

One feature that I really like in Grails 2.0 is action arguments databinding. While reading more about it I also found a nice grails.web.RequestParameter annotation. When you know something you always find its use case. In my recent project I need to take radius and height as params for creating a cylinder so my action looks like

def save(float radius, float cylinder){
....
}

but now I have changed my action as

def save(@RequestParameter('r')float radius, @RequestParameter('h')float height){
....
}

Now radius will initialize with params.r and height will initialize with params.h. It made my urls short and my code more readable.
I believe that the real benefit of this annotation would be in a scenario where an external API returns some result whose fields are not that intuitive.
However I have a wish here, that if we could use this annotation on command object fields as well then it will be more useful.


Hope it helps
Uday Pratap Singh
uday@intelligrape.com
https://twitter.com/meudaypratap
http://in.linkedin.com/in/meudaypratap

Posted in Design Pattern, Grails

Grails Custom Data Binding in 3 Simple Steps

Posted by on December 29th, 2011

The other day, Farid came with an interesting problem of binding a Time String to java.sql.Time. We straight away found the answer in using a CustomTimeEditor and registering it using a CustomPropertyEditorRegistrar bean. We were able to come arrive at this solution, thanks to this StackOverflow thread.

This set me thinking into using a CustomProperty Editor for, say a Cost object, which could contain a unit and an amount


class Cost{

String unit //Could be constrained to belong to some range of values

BigDecimal amount

}

I was able to solve this issue in 3 simple steps which I would like to share with you. I felt that this would take a lesser amount of time compared to the Extended Data Binding Plugin(my gut feeling)

1. Add a CustomCostEditor to src/groovy


import java.beans.PropertyEditorSupportimport org.springframework.util.StringUtils
class CustomCostEditor extends PropertyEditorSupport {    private final boolean allowEmpty
        CustomCostEditor(boolean allowEmpty) {
               this.allowEmpty = allowEmpty
        }
        @Override
        void setAsText(String text) {
               if (this.allowEmpty && !StringUtils.hasText(text)) {
                     // Treat empty String as null value.
                     setValue(null);
               } else {
                      setValue(parse(text))
               }
        }
        @Override
        String getAsText() {
                Cost cost = (Cost) getValue()
                return "${cost.unit} ${cost.amount}"
        }
       Cost parse(String text){
                try{
                     new Cost(unit: text.substring(0, text.indexOf(" ")), amount: text.substring(text.indexOf(" ") + 1).toBigDecimal())
                } catch(Exception exception){
                     throw new IllegalArgumentException("Cost should be of the format 'Unit Amount'")
                }
       }
}

The methods which we need to override are setAsText() and getAsText()
2. Add a CustomPropertyEditorRegistrar class, which has a registerCustomEditorMethods

import org.springframework.beans.PropertyEditorRegistrar
import org.springframework.beans.PropertyEditorRegistry

class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar{
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Cost.class, new com.intelligrape.example.CustomCostEditor(true));
    }
}

3. Add a spring bean to add an instance of this custom property editor registrar
Finally, we create a spring bean by adding the following line in resources.groovy

beans = {
    customPropertyEditorRegistrar(CustomPropertyEditorRegistrar)
}

Now, assuming that we have an embedded field cost of type Cost in a domain class Item, we can simply use

<input type="text" name="cost" value="${fieldValue(bean: item, field:'cost')}"/>

and input “$ 123″ to store $ in the cost.unit and 123 in the cost.amount.

I believe that the possibilities with such an approach are infinite!

Posted in Grails

Grails bindData to collections

Posted by on October 24th, 2011

Recently, I was stuck with a scenario where I was trying to bind a list of objects in my controller. While trying the way as suggested in the grails docs I was getting some weird IndexOutOfBoundException. Luckily I found a good solution on the grails mailing list: http://grails.1312388.n4.nabble.com/Databinding-Collection-of-non-domain-objects-tp3260578p3260856.html
Thanks to mkwhit for asking this and Dana for suggesting this solution.

There is a Car class in my src/groovy. There is a create.gsp that should create n number of cars at a time. The problem is to bind this data to a List of Car objects.

Here is how I got it done:

I ensured in my gsp that the car parameters are passed as car.1.name, car.1.brand, car.2.name, car.2.brand ….. So, when I did a params.car I get a Map like this:

1: [name:'carA', brand:'brand1']
2: [name:'carB', brand:'brand2']
3: [name:'carC', brand:'brand2']
1.name:'carA'
1.brand:'brand1'
2.name:'carB'
2.brand:'brand2'
3.name:'carC'
3.brand:'brand3'
def carParams = params.car.values().findAll {it instanceof GrailsParameterMap}
List<Car> carList = carParams.collect {
   def car = new Car()
   bindData(car, it)
   car
}

So, we have a list of Car objects out from the params.

Hope this helps.

-Mohd Farid-

Posted in Grails