Execute controller function in Grails via Ajax

1.8k views Asked by At

I am a novice with ajax in Grails. I want to try to execute a controller method from gsp-code from ajax.

This is part of my gsp-code:

<g:select
  optionKey="id" name="region.id" id="region" from="${region}" noSelection="[null:' ']"
  onchange="categoryChanged(this.value);"
></g:select>
<div>
  <b>Sub-Category: </b>
  <span id="subContainer"></span>
</div>
                <script>
                    function categoryChanged(regionId) {
                        $.ajax({type:'POST',data:'regionId='+regionId, url:'restorator/region/categoryChanged',success:function(data,textStatus){jQuery('#subContainer').html(data);},error:function(XMLHttpRequest,textStatus,errorThrown){}});
                    }
                </script>

In the url parameter of the $ajax call: restorator is a package, region is a controller in it and categoryChanged is an action.

This is my controller:

class RegionController {

    def ajaxGetCities = {
        println "hello"
        def region = Region.get(params.id)
        render region?.cities as JSON
    }

    def categoryChanged(long regionId) {
        println "test"
        Region region = Region.get(regionId)
        def subCategories = []
        if ( region != null ) {
            subCategories = City.findAllByRegion(region, [order:'cityName'])
        }
        render g.select(id:'subCategory', name:'subCategory.id',
            from:subCategories, optionKey:'id', noSelection:[null:' ']
        )
    }
}

In the head part I've added <g:javascript library='jquery' /> When I try to change option in the select tag I don't see the output to console, which should be shown from theprintln "test" line inside the controller. This means that the controlloer function is never actually called, what am I doing wrong ? How do I make sure this function call actually happens ?

2

There are 2 answers

0
Vivek Sadh On BEST ANSWER

Right click on the page,Inspect Element and see if there are any errors in console.

Also, you should specify URL this way:

url: '${createLink(controller: 'region', action: 'categoryChanged')}',
0
Jay Prall On

It will be less code if you use the grails remoteLink function.

<g:remoteLink action="makeProduct" id="${productInstance.id}" before="showSpinner('#spinner1')" onComplete="hideSpinner('#spinner1')" update="product_status">Make Product</g:remoteLink>
<div id="product_status"></div>

This code will request the action asynchronously and update the product_status div with the resulting HTML from the action. You can also add spinners on the page to give the user some feedback.