# form

## Purpose

Creates a form that submits to a controller, action, and/or id. Beyond what is below all the usual HTML attributes apply.

## Examples

Example controller for an application called "shop":

    class Book {
         def list = { [ books: Book.list( params ) ] }
         def show = { [ book : Book.get( params['id'] ) ] }
    }

Example usages for above controller:

    <g:form name="myForm" action="myaction" id="1">...</g:form>
    results in:
    <form action="/shop/book/myaction/1" method="post" name="myForm" id="myForm" >...</form><g:form name="myForm" url="[action:'list',controller:'book']">...</g:form>
    results in:
    <form action="/shop/book/list" method="post" name="myForm" id="myForm" >...</form><g:form action="show">...</g:form>
    results in:
    <form action="/shop/book/show" method="post" >...</form>

## Description

Attributes

- `action` (optional) - The name of the action to use in the link, if not specified the default action will be linked
- `controller` (optional) - The name of the controller to use in the link, if not specified the current controller will be linked
- `id` (optional) - The id to use in the link
- `fragment` (optional) - The link fragment (often called anchor tag) to use
- `mapping` (optional) - The named URL mapping to use to rewrite the link
- `params` (optional) - A map containing URL query parameters
- `url` (optional) - A map containing the action,controller,id etc.
- `absolute` (optional) - If set to "true" will prefix the link target address with the value of the grails.serverURL property from Config, or http://localhost:<port> if no value in Config and not running in production.
- `base` (optional) - Sets the prefix to be added to the link target address, typically an absolute server URL. This overrides the behaviour of the `absolute` property, if both are specified.
- `name` (optional) - A value to use for both the name and id attribute of the form tag
- `useToken` (optional) - Set whether to send a token in the request to handle duplicate form submissions. See Handling Duplicate Form Submissions

## Source

Show Source

    def form = { attrs, body ->        def useToken = attrs.remove('useToken')
            def writer = getOut()        writer << "<form action=\"${createLink(attrs)}\" "
            // default to post
            def method = attrs.remove('method')?.toUpperCase() ?: 'POST'
            def httpMethod = HttpMethod.valueOf(method)
            boolean notGet = httpMethod != HttpMethod.GET        if (notGet) {
                writer << 'method="post" '
            }
            else {
                writer << 'method="get" '
            }        // process remaining attributes
            attrs.id = attrs.id ? attrs.id : attrs.name
            if (attrs.id == null) attrs.remove('id')        outputAttributes(attrs)        writer << ">"
            if (request['flowExecutionKey']) {
                writer.println()
                hiddenFieldImpl(writer, [name: "execution", value: request['flowExecutionKey']])
            }        if (notGet && httpMethod != HttpMethod.POST) {
                hiddenFieldImpl(writer, [name: "_method", value: httpMethod.toString()])
            }        if (useToken) {
                def token = SynchronizerToken.store(session)
                writer.println()
                hiddenFieldImpl(writer, [name: SynchronizerToken.KEY, value: token.currentToken])
                writer.println()
                hiddenFieldImpl(writer, [name: SynchronizerToken.URI, value: request.forwardURI])
            }        // output the body
            writer << body()        // close tag
            writer << "</form>"
        }