tudor-malene / Easygrid

Grails plugin - simple and declarative way of defining a DataGrid
Apache License 2.0
27 stars 24 forks source link

Select in filter based on values in the jqgrid #107

Open ericraskin opened 10 years ago

ericraskin commented 10 years ago

Hi:

I've got a grid with two fields declared like this:

            statusDesc {
                label "Status"
                jqgrid {
                    width "100"
                    align "center"
                }
                export {
                    width "100"
                }
            }
            broker {
                label "Broker"
                value { it.listBroker.company }
                sortProperty "listBroker.company"
                jqgrid {
                    width "150"
                }
                export {
                    width "150"
                }
            }

I would like to make Filters that are dropdowns containing all the DISPLAYED values that exist in these columns. I saw your Pet Clinic example, but that does a Specialty.list (ordered by the Name field). I don't have a table that contains the status descriptions by themselves. It is a Formula column in my table, defined like this:

        statusDesc formula: "decode(status,'1','Unreceived','2','Received','3','Testing','4','Running','5','Converted','6','OK','7','XLD','8','Errors','9','IAC-Out','A','IAC-Back')"

Note that these values change very rarely, and doing a query each time is pretty expensive. There are lots of rows in that table.

The broker column (an association) would change for every table displayed. We have many brokers, but only certain ones are represented in each table. I would like the dropdown to consist of only those values that actually exist in the grid. This would also be ideal for the statusDesc filter, although there are only a few possible values in this case.

How can I accomplish this? I think there are two separate solutions here. For the status field, is it best to just hardcode all possible values? That may be confusing to my users, since all values may not be represented in any particular displayed table. For the broker field, is this an example of AutoComplete?

Or do I have to do something along the lines of this post?

http://stackoverflow.com/questions/5328072/can-jqgrid-support-dropdowns-in-the-toolbar-filter-fields

That would require making a custom template for each grid?

ericraskin commented 10 years ago

As a follow up, I've pretty much given up on the javascript idea. Since you load data in pages, the javascript version would only be able to create a dropdown of the data on the page. I prefer that it contain a dropdown of data for the entire grid. So, javascript is out.

I realize that I didn't tell you the whole story, either. This is a child grid. I have a master grid mailerJobsGrid based on domainClass PASOrder. When you click on a row, the child grid mailerMergeGrid based on domainClass Mplist comes up via the following:

        globalFilterClosure{ params ->
            mergeOrder {
                eq('ordnum', params.jobId ? params.jobId as long: -1l)
            }
        }

So, I want my filter dropdown to only show the broker values (as described in the first post) for the rows that are displaying in this grid. I don't want the dropdown to show every broker in our system, as they don't all pertain.

I guess I need some kind of method call in my GSP:

            <grid:set col="statusDesc" stype="select"
                      searchoptions.sopt="['eq']"
                      searchoptions.value="${JsUtils.convertListToString{???}" />

to do this. What can I put in here? And, how do I pass the current params.jobId value into the method so I can get the correct list of brokers?

tudor-malene commented 10 years ago

This is from VetScheduleController in the petclinic sample:

            'pet.type.name' {
                label 'Type'
                filterDataType Long
                filterProperty 'pet.type.id'
                jqgrid {
                    stype = 'select'
                    searchoptions {
                        sopt(['eq'])
                        value(JsUtils.convertListToString { PetType.listOrderByName() })
                    }
                }
            }

You should try something similar.

         statusDesc{
                jqgrid {
                    stype = 'select'
                    searchoptions {
                        value(JsUtils.convertListToString { 
                                   //here you should try to call a service method, or something, and also access 'params' to get the master id 
                                    })
                    }
                }
           }
ericraskin commented 10 years ago

I see. It has to be in a service and not a controller? On Jul 24, 2014 5:48 PM, "Tudor Malene" notifications@github.com wrote:

This is from VetScheduleController in the petclinic sample:

        'pet.type.name' {
            label 'Type'
            filterDataType Long
            filterProperty 'pet.type.id'
            jqgrid {
                stype = 'select'
                searchoptions {
                    sopt(['eq'])
                    value(JsUtils.convertListToString { PetType.listOrderByName() })
                }
            }
        }

You should try something similar.

     statusDesc{
            jqgrid {
                stype = 'select'
                searchoptions {
                    value(JsUtils.convertListToString {
                               //here you should try to call a service method, or something, and also access 'params' to get the master id
                                })
                }
            }
       }

— Reply to this email directly or view it on GitHub https://github.com/tudor-malene/Easygrid/issues/107#issuecomment-50082991 .

tudor-malene commented 10 years ago

This is pretty tricky.

It can be anything as long as that closure returns a list of object or maps of type [name: 'name', id: 'id'] This list will be used to generate the selectbox

ericraskin commented 10 years ago

So, here's how far I've gotten. Created a service PASGridService with a method that returns a string of values I want to display. I put this in my GSP:

    <% def pasGridService = grailsApplication.mainContext.getBean("PASGridService"); %> 

This locates my service correctly. Then I call it like this:

          <grid:grid name="mailerMerge" masterGrid="mailerJobs" childParamName="jobId">
            <grid:set altRows="true"/>
            <grid:set width="auto" height="auto" caption="Lists in Merge"/>
            <grid:set col="pasnum" hidden="true" />
            <grid:set col="statusDesc" stype="select"
                      searchoptions.sopt="['eq']"
                      searchoptions.value="${JsUtils.convertListToString(pasGridService.getBrokersForOrder(params.jobId))}" />
            <grid:set col="sexcounts" label="Sex Count Report" align="center" formatter="f:sexcountViewButton" />
          </grid:grid>

I get into my service method, but the parameter is null when I get there. How do I pass the parameter for the child grid I am loading into the service method?

tudor-malene commented 10 years ago

Hi, I think searchoptions.value on statusDesc belongs in the controller.

Something like:

def mailerMergeGrid={
...
    columns{
...
         statusDesc{
....
                jqgrid {
....
                    searchoptions {
                        value(JsUtils.convertListToString{
                            pasGridService.getBrokersForOrder(EasygridContextHolder.params.jobId)
                        })
                    }
                }
         }
    }
}

It would work in the gsp too , but it's cleaner to call service methods from the controller.

What happens here is that the closure passed to converListToString is called during the rendering.

You will have to set jobId as an externalParam too