source: trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy @ 89

Last change on this file since 89 was 89, checked in by duh, 10 years ago
  • refactored some wizard code
  • templatizing and standardizing form elements into tag libraries
  • Property svn:keywords set to Rev Author Date
File size: 4.0 KB
Line 
1package dbnp.studycapturing
2import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib
3
4/**
5 * Wizard tag library
6 *
7 * @author  Jeroen Wesbeek
8 * @since   20100113
9 * @package wizard
10 *
11 * Revision information:
12 * $Rev: 89 $
13 * $Author: duh $
14 * $Date: 2010-01-14 16:44:28 +0000 (do, 14 jan 2010) $
15 */
16class WizardTagLib extends JavascriptTagLib {
17  // define the tag namespace (e.g.: <wizard:action ... />
18  static namespace = "wizard"
19
20  // define the AJAX provider to use
21  static ajaxProvider = "jquery"
22
23  // define default text field width
24  static defaultTextFieldSize = 25;
25 
26  /**
27   * ajaxButton tag, this is a modified version of the default
28   * grails submitToRemote tag to work with grails webflows.
29   * Usage is identical to submitToRemote with the only exception
30   * that a 'name' form element attribute is required. E.g.
31   * <wizard:ajaxButton name="myAction" value="myButton ... />
32   *
33   * @see   http://www.grails.org/WebFlow
34   * @see   http://www.grails.org/Tag+-+submitToRemote
35   * @todo  perhaps some methods should be moved to a more generic
36   *        'webflow' taglib
37   * @param Map     attributes
38   * @param Closure body
39   */
40  def ajaxButton = { attrs, body ->
41    // fetch the element name from the attributes
42    def elementName = attrs['name'].replaceAll(/ /,"_")
43   
44    // generate a normal submitToRemote button
45    def button = submitToRemote(attrs,body)
46
47    /**
48     * as of now (grails 1.2.0 and jQuery 1.3.2.4) the grails webflow does
49     * not properly work with AJAX as the submitToRemote button does not
50     * handle and submit the form properly. In order to support webflows
51     * this method modifies two parts of a 'normal' submitToRemote button:
52     *
53     * 1) replace 'this' with 'this.form' as the 'this' selector in a button
54     *    action refers to the button and / or the action upon that button.
55     *    However, it should point to the form the button is part of as the
56     *    the button should submit the form data.
57     * 2) prepend the button name to the serialized data. The default behaviour
58     *    of submitToRemote is to remove the element name altogether, while
59     *    the grails webflow expects a parameter _eventId_BUTTONNAME to execute
60     *    the appropriate webflow action. Hence, we are going to prepend the
61     *    serialized formdata with an _eventId_BUTTONNAME parameter.
62     */
63    button = button.replaceFirst(/data\:jQuery\(this\)\.serialize\(\)/, "data:\'_eventId_${elementName}=1&\'+jQuery(this.form).serialize()")
64
65    // render button
66    out << button
67  }
68
69  /**
70   * wizard navigation buttons render wrapper, in order to be able to add
71   * functionality in the future
72   */
73  def previousNext = { attrs ->
74    // define AJAX provider
75    setProvider([library:ajaxProvider])
76
77    // render navigation buttons
78    out << render(template:"/wizard/common/buttons")
79  }
80
81  /**
82   * render the content of a particular wizard page
83   * @param Map     attrs
84   * @param Closure body
85   */
86  def pageContent = { attrs, body ->
87    // define AJAX provider
88    setProvider([library:ajaxProvider])
89
90    // render new body content
91    out << render(template:"/wizard/common/tabs")
92    out << '<div class="content">'
93    out << body()
94    out << '</div>'
95    out << render(template:"/wizard/common/navigation")
96  }
97
98  def textFieldElement = { attrs, body ->
99    // set default size, or scale to max length if it is less than the default size
100    if (!attrs.get("size")) {
101      if (attrs.get("maxlength")) {
102        attrs.size = ((attrs.get("maxlength") as int) > defaultTextFieldSize) ? defaultTextFieldSize : attrs.get("maxlength") 
103      } else {
104        attrs.size = defaultTextFieldSize
105      }
106    }
107
108    // render a text element
109    out << '<div class="element">'
110    out << ' <div class="description">'
111    out << body()
112    out << ' </div>'
113    out << ' <div class="input">'
114    out << textField(attrs)
115    out << ' </div>'
116
117    // add help icon?
118    if (attrs.get('help')) {
119      out << ' <div class="help"><img src="../images/icons/famfamfam/help.png"></div>'
120    }
121   
122    out << '</div>'
123  }
124}
Note: See TracBrowser for help on using the repository browser.