tudor-malene/Easygrid

How to use the List datasource?

Closed this issue · 7 comments

I am new to grails and to EasyGrid. Sorry in advance for the long post. I have written a service to return data from my models and I want to display the results in an EasyGrid. Here is the service:

def listCustomers(params) {
    def result = [:]

    params.max = Math.min( params.max ? params.max.toInteger() : 10,  100)

    def user = springSecurityService.currentUser

    result.customers = Order.executeQuery('select distinct c.company company, c.id id from Customer c join c.orders o join o.mergeLists m join m.broker b where b.id = ? order by 1', [ user.dbID ], params )
    result.count = Order.executeQuery('select count(distinct c.company) from Customer c join c.orders o join o.mergeLists m join m.broker b where b.id = ? order by 1', [ user.dbID ], params )

    if (!result.customers) {
        result.error = [code: 'Query-Failed', args:'listCustomers']
        result.count = 0
    }
    else
    {
        result.error = [code: 0, args:'']
    }

    return result
}

I return a result map with three keys (customers, count and error). My controller looks like this:

def broker_mailers() {

    def result = brokerAccessService.listCustomers(params)
    if (result.error.code == 0) {
        render(template: "broker_level1", model: [ customerList: result.customers, count: result.count ])
        return
    }

    flash.message = g.message(code: result.error.code, args: result.error.args)
    flash.error = result.error.code

    render (template: 'broker_level1')

}

I am at a loss on how to configure the EasyGrid. I have tried this:

def brokerMailersGrid = { dataSourceType 'List' context 'model' attributeName 'result' enableFilter true inlineEdit false columns { id { type 'id' hidden } customers { label 'Mailers' } } }

The error I currently get is:
| Error 2014-03-18 11:44:24,413 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: assert gridConfig.dataSourceService
| |
| null
GridConfig{brokerMailers}

What is a dataSourceService? I don't see it in the documentation.

I can't find a good example of taking the data from the Model of a render. Is this a case for a custom service implementation instead?

Hi,
the main error I could spot in your example is that the datasource should be 'list':

 dataSourceType 'list'

not 'List'.

Otherwise, I think you can use the 'gorm' datasource in this case. ( the main use case for 'list' is when you have a non persistent list of objects stored in the session or servlet context )

Try this:

def brokerMailersGrid = {
    dataSourceType 'gorm'
    domainClass Customer
    initialCriteria{
        def user = springSecurityService.currentUser
        orders{
            mergeLists{
                broker{
                    eq('id',user.dbID)
                }
            }
        }
    }
    enableFilter true
    inlineEdit false
    columns {
        id {
            type 'id'
            hidden
        }
        customers {
            label 'Mailers'
        }
    }
}

Thanks -- it is starting to work. I actually got some output after a little tweaking. I had to inject springSecurityService into my controller, for example.

I am using this grid in an ajax context (the template is the target of a g:remoteLink). Is that OK? My first attempt is not showing all the entries it should, as compared to the query results of my service.

Also, how can I sort the initialCriteria? The query in the service has an "order by" clause. Is your InitialCriteria section documented anywhere?

I will also be adding another remoteLink as a button on each row, updating another div in the template. It's similar to your Pet Store example, but with ajax updates. Anything I need to look out for?

Oh -- sorry -- there is also a DISTINCT clause in the query, which is very important. How do I add that to the initialCriteria as well?

Q: I am using this grid in an ajax context (the template is the target of a g:remoteLink). Is that OK?
A: Yes. You can even load the entire grid via an ajax call

Q: My first attempt is not showing all the entries it should, as compared to the query results of my service.
A: I didn't understand

Q: Also, how can I sort the initialCriteria? The query in the service has an "order by" clause.
A: I would recommend using jqgrid's support for this. Like this:

 def brokerMailersGrid = {
     dataSourceType 'gorm'
     domainClass Customer
     jqgrid{
        sortname  "customers"
        sortname "asc"
     }
     initialCriteria{
      .....

Q: Is your InitialCriteria section documented anywhere?
A: Not very good. I will have to update the docs. This criteria is basically used to initialize the DetachedCriteria that is used by the Gorm Datasource.

Q: I will also be adding another remoteLink as a button on each row, updating another div in the template. It's similar to your Pet Store example, but with ajax updates. Anything I need to look out for?
A: Not really, you will probably have to study jqgrid a little.

Q: Oh -- sorry -- there is also a DISTINCT clause in the query, which is very important. How do I add that to the initialCriteria as well?
A: This is indeed a problem. I will fix it in the next version. You can't add the distinct clause in the initialCriteria at this moment

LOL! Thanks very much. I've been puzzling that one (DISTINCT) for the last hour or so. After I made the leap that your initialCriteria is just a GORM criteria structure, I tried it like this:

initialCriteria { def user = springSecurityService.currentUser orders { mergeLists { broker { eq ('id', user.dbID) } } } projections { distinct(["id","company"]) } }

As you no doubt know, it did not work. I got a 404 error back, which I guess means that the query failed somehow. Let me know if there is anything I can provide from this end to help.

Yes, it's a limitation of Criteria

http://grails.org/doc/2.3.x/ref/Domain%20Classes/createCriteria.html
see: listDistinct

I will add this in the next release ( probably this week )

Thanks very much. I will watch for it.