Code Junkie
Code Junkie

Reputation: 7788

Grails updating values in form using Ajax

I have two groups of radio buttons, the first group represents size and the second group represents quantity along with price.

I'm trying to update the price next to quantity with Ajax when changing the size radio has been changed.

What I have thus far.

<script>
     $(document).ready(function(){
        $("input[name*='size']").click(function() {
            ${remoteFunction(
                controller:'product', 
                action:'ajaxSize',
                params:'\'size=\' + this.value')}
        })  
     });
</script>
<g:formRemote name="myForm"
    url="[controller:'product', action: 'save']" update="updateMe">

    <input type="radio" name="size" value="2x2">2x2<br>         
    <input type="radio" name="size" value="4x4">4x4<br><br>

    <input type="radio" name="quantity" value="15">15 ${price}<br>
    <input type="radio" name="quantity" value="16">16 ${price}<br>
    <input type="radio" name="quantity" value="17">17 ${price}<br>

</g:formRemote>

controller

def ajaxSize = {
    println params
    render params
}

@Transactional
def save(Product product) {
}

Upvotes: 1

Views: 1435

Answers (1)

cantoni
cantoni

Reputation: 3122

I have wrote an example using Grails 2.5.0. This example uses GSP Templates to render the price changing in an AJAX call, see the details below.

Create a GSP template called _price.gsp

The template is a GSP file that must start with the underscore character and don't have the HTML and BODY tags. In this case, the GSP is simply the code below:

<input type="radio" name="quantity" value="15">15 ${price}<br>
<input type="radio" name="quantity" value="16">16 ${price}<br>
<input type="radio" name="quantity" value="17">17 ${price}<br>

Create a GSP called ajaxSize.gsp

This is the main GSP and is a full HTML file.

Note that this GSP includes the _price.gsp template using the g:render taglib.

It's also important to note that I put the g:render inside a DIV called updateMe. This is the DIV that the g:remoteFunction updates with the return (render) of setPrice method.

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <asset:javascript src="application.js"/>
    <asset:stylesheet src="application.css"/>
    <title></title>
</head>

<body>
        <input type="radio" name="size" value="2x2">2x2<br>
        <input type="radio" name="size" value="4x4">4x4<br><br>

        <div id="updateMe">
            <g:render template="price"></g:render>
        </div>
</body>

<g:javascript>
    $(document).ready(function(){
        $("input[name*='size']").click(function() {
            ${remoteFunction(
                controller:'test',
                action:'setPrice',
                update: "updateMe",
                params:'\'size=\' + this.value')}
        })
    });
</g:javascript>

</html>

Create a controller called TestController.groovy

When the template is rendered you don't need to put the underscore character in front of the name. You have just to write the name of template without underscore, see below the render call in setPrice.

class TestController {

    def index() {}

    def ajaxSize() {
       return
    }

    def setPrice() {
        def price

        if (params.size=="2x2")
            price = "100"
        if (params.size=="4x4")
            price = "200"

        render template: "price", model: [price:price]
    }
}

Testing the solution

http://localhost:8080/myApp/test/ajaxSize

When the ajaxSize action is called the content of the ajaxSize.gsp is rendered. After that, a click in any radio button (name="size") will generate an Ajax call to the action setPrice. This action will receive the value of the radio button that was clicked and will render the _price.gsp template sending the price calculated as the model.

Upvotes: 1

Related Questions