idonaldson
idonaldson

Reputation: 475

Populate Grails g:select from function

Trying to populate a g:select from a function in my controller, is it possible?

Currently we have this:

def run(Long id) {

    def reportInstance = Report.get(id)

    def listPromptValues = populatePrompts(reportInstance)*.values()

    if (!reportInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'report.label', default: 'Report'), id])            
        return
    }
    [reportInstance: reportInstance, listPromptValues: listPromptValues]
}

def populatePrompts(Report rp){
    //for each prompt in the report, go out and get it's values
    rp.prompts.collectMany {
        reportService.listDatatypeValues(it.datatype)
    }

}

And then the g:select in question is

<li class="fieldcontain">
                <g:each var="prompt" in="${reportInstance.prompts}">
                    <span id="prompts-label" class="property-label">
                        <g:message code="report.prompts.label" default="${prompt.name}:" />
                    </span>
                    <g:if test="${prompt.datatype.type == 'DropDown'}">                         
                        <g:select id="prompt.name" from="${listPromptValues}" name="prompt.name" value="" noSelection="['':'']"/>
                        <br>                            
                    </g:if>
                </g:each>
            </li>

Which works just fine if there is only one prompt, however we need to be able to call the populatePrompt function directly from the gsp view if there is more than one prompt in the loop, possible sending the reportId and then getting back the listPromptValues. I can't seem to get the onChange(remoteFunction...) to work properly and am coming up empty handed in searching the vast Google webs.

Something like how createLink works

${createLink(controller:'report', action:'runReport', id:"${reportInstance.id}")}

But instead of createLink, it would be the from attribute of the select tag, something like:

<g:select id="prompt.name" from="{(controller:'report',action:'populatePrompt', id:"${reportInstance.id}")}" name="prompt.name" value="" noSelection="['':'']"/>

Any ideas, or direction to go?

Upvotes: 0

Views: 4522

Answers (1)

coderLMN
coderLMN

Reputation: 3076

I think @JamesKleeh proposed a viable solution in his last comment.

Given the fact that your gsp structure is quite static, it doesn't make sense to fetch the prompt select options to be dynamically loaded. Just return these options in a List package within listPromptValues from your controller and take it in the gsp directly.

Concerning your parameters like [prompt1: ['a','b','c'], prompt2: ['d','e','f']], you can get this map in your populatePrompts method and put each key-value pair into gsp select tags. Like this:

controller

{    ....
    def listPromptValues = populatePrompts(reportInstance)
    ....
}

def populatePrompts(Report rp){
    //for each prompt in the report, go out and get it's values
    def promptMap = [:]            //map to be returned
    rp.prompts.each {
        promptMap.put(it.name, reportService.listDatatypeValues(it.datatype))
    }
    return promptMap
}

gsp

                <g:each var="prompt" in="${reportInstance.prompts}">
                    <span id="prompts-label" class="property-label">
                        <g:message code="report.prompts.label" default="${prompt.name}:" />
                    </span>
                    <g:if test="${prompt.datatype.type == 'DropDown'}">                         
                        <g:select id="prompt.name" from="${listPromptValues[prompt.name]}" name="prompt.name" value="" noSelection="['':'']"/>
                        <br>                            
                    </g:if>
                </g:each>

Upvotes: 1

Related Questions