(Quick Reference)

actionSubmit

Purpose

Generates a submit button that maps to a specific action, which lets you have multiple submit buttons in a single form. JavaScript event handlers can be added using the same parameter names as in HTML.

Examples

<g:actionSubmit value="Update" />

<!--'Update' is action, label is 'Some update label'-->
<g:actionSubmit value="Some update label" action="Update" />

<!--label derived from message bundle-->
<g:actionSubmit value="${message(code:'label.update')}" action="Update" />

<g:actionSubmit value="Delete" />

<g:actionSubmit value="DeleteAll"
                onclick="return confirm('Are you sure???')" />

Description

Attributes

  • value (required) - The caption of the button and name of action when not explicitly defined.

  • action (optional) - The name of the action to be executed, otherwise it is derived from the value.

When you use a normal submit button inside a form, it is the form itself that determines what URL the request is sent to, and therefore what action is executed. However, this tag overrides that behaviour and determines which action is executed. Note that it is still the form that determines the target controller.

Due to the way that the tag works, you should not specify an action on the enclosing form unless it is completely necessary. If you do, the URL address in the browser is likely to include the name of the action specified by the form, not the one specified by the actionSubmit tag. In such cases, it is probably a good idea to use custom URL mappings.

URL Mappings

The implementation of the actionSubmit tag means that it does not sit entirely comfortably with URL mappings, particularly the default one. The reason for this is that URL mappings work on the URL of the request, but actionSubmit uses a parameter to determine the action to execute. This means that there is a mismatch between any action name in the URL mapping, and the name of the actual action executed.

Take this simple case with the default URL mapping:

class UrlMappings {
    static mappings = {
        "/$controller/$action?/$id?"{
            constraints {
                // apply constraints here
            }
        }
    }
}

and a GSP page containing this simple form:

<g:form controller="test">
    <g:actionSubmit value="Submit" action="success"/>
</g:form>

The URL generated for the <form> element will either be "…​/test" or "…​/test/index" (assuming "index" is the default action) depending on your version of Grails. Note that neither version includes "success" in the URL, and when you click on the submit button the URL in the browser will be without "success" too.

This isn’t too much of a problem when the form URL does not include an action name, but if you have a version of Grails that appends the name of the default action, or you specify an action in your <g:form> tag, then you should probably use a custom URL mapping to hide the action name:

"/test/submit" {
    controller = "test"
    action = "index"
}

where the action specified in the mapping is either the default action of the controller, or the action specified in the <g:form> tag.

Also note that this tag relies on the multipart resolver to be able to inspect parameters included with multipart requests. If you disable the resolver by setting grails.disableCommonsMultipart to true in the application configuration, actionSubmit will not work.