source: cows_wps/trunk/cows_wps/renderer/form_renderer.py @ 7104

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows_wps/trunk/cows_wps/renderer/form_renderer.py@7104
Revision 7104, 6.5 KB checked in by astephen, 10 years ago (diff)

more work on jobs page.

Line 
1import os
2
3from genshi.template import TemplateLoader
4from genshi.builder import * 
5from genshi import HTML
6
7
8class FormRenderer(object):
9    """
10    A set of rendering methods for HTML forms.
11    """
12
13    def __init__(self):
14        # Instantiate Genshi template loader
15        self.templateLoader = TemplateLoader(
16           os.path.join(os.getcwd(), 'cows_wps/templates'),
17           auto_reload=True)
18
19    def htmlify(self, html): return HTML(html)
20
21    def renderRadioButton(self, name, is_boolean = True, values = None):
22        """
23        Returns HTML of radio button.
24        """
25        if is_boolean == True:
26            values = ("true", "false")
27
28        html = ""
29        for value in values:
30            html += """         <input type="radio" id="%s" name="%s" value="%s" />
31                <label for="%s">%s</label><br />\n"""   
32
33        return html
34
35    def renderTextInput(self, name, dtype, optional = False, default = None, multiple = False):
36        """
37        Returns HTML for text input including onChange validator.
38        optional is a boolean.
39
40        Populates with default value if not None.
41        If multiple is true then makes box bigger.
42        """
43        if default == None: default = ""
44
45        allowed_dtypes = ("any", "float", "int", "string", "datetime")
46        js_opt = str(optional).lower()
47
48        if dtype not in allowed_dtypes:
49            raise Exception("Invalid type sent to FormRenderer.renderTextInput(): %s" % dtype)
50
51        validators = {"int": ("/^[0-9]+$/", "The %s input must be an integer." % name), 
52                      "float": ("/^[-+]?([0-9]*\.[0-9]+|[0-9]+)$/", "The %s input must be a decimal number." % name),
53                      "string": ("/[0-9a-zA-Z]+/", "The %s input must include text characters." % name),
54                      "any": ("/.*/", "No message."),
55                      "datetime": ("/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/", "The %s input must be a date/time entry as follows YYYY-MM-DDThh:mm:ss (e.g. 2009-01-01T12:00:00)." % name)}
56
57        (regex, msg) = validators[dtype]
58
59        if multiple == True:
60            on_change = "validateTextAreaInput"; 
61        else:
62            on_change = "validateTextInput";
63
64        tag_contents = """name="%s" id="%s" value="%s" onChange="%s(this.value, %s, '%s', %s);" """ % (name, name, default, on_change, regex, msg, js_opt)
65
66        if multiple == True:
67            # Use textarea
68            html = """<textarea cols="50" rows="3" %s ></textarea>""" % tag_contents
69            html += """\n<script type="text/javascript">registerTextArea('%s');</script>""" % name
70
71            validator_type = "textarea"
72        else:
73            # Use text input
74            html = '<input type="text" %s />' % tag_contents
75            validator_type = "text"
76
77        html += """<br />\n<script type="text/javascript">addValidator('%s', '%s', %s, '%s', %s);</script>\n""" % (name, validator_type, regex, msg, js_opt)
78        return html
79
80    def renderSelectList(self, name, values, optional = False, multiple = False, 
81                         option_names = None, selected = None, size = 1):
82        """
83        Returns HTML for select list.
84
85        If optional is True then add an extra option called "-- Please select --".
86        """
87        # Do some checks
88        if option_names == None:
89            option_names = values[:]
90       
91        if optional == True:
92            values.insert(0, "")
93            option_names.insert(0, "-- Please select --")
94
95        if len(values) != len(option_names):
96            raise Exception("Length of 'values' and 'option_names' sent to renderSelectList() must be the same and are not.")
97
98        multiple_string = ""
99        if multiple == True:
100            multiple_string = 'multiple="multiple"'
101
102        html = """<select %s name="%s" id="%s">\n""" % (multiple_string, name, name)
103       
104        for (i, value) in enumerate(values):
105            option_name = option_names[i]
106
107#            html += "%s--%s++%s.." % (i, value, selected)
108            # FIXME: Does not pick up submitted value here from 'selected' arg.
109            selected_flag = ""
110            if selected == value:
111                selected_flag = 'selected="selected"' 
112
113            html += """ <option %s value="%s">%s</option>\n""" % (selected_flag, value, option_name)
114
115        html += "</select>\n"
116        return html
117
118    def renderBBox(self, name, extent):
119        """
120        Renders a bounding box and (west, south, east, north) selectors.
121        ``extent`` is received as a string of "west|south|east|north".
122        """
123        if extent == False: extent = "-180|-90|180|90"
124        (w, s, e, n) = extent.split("|")
125
126        html = """    <div id="bounding_container">
127        <div> BBox = <span id="bbox_show_val"></span></div>
128        <div id="bounds_control_container"></div>
129        <div id="map_container">
130            <div id='map'></div>
131        </div>
132            <input type="hidden" name="%s" id="bbox_hidden_input" />
133            <script type="text/javascript">
134                var initial_extent = [%s, %s, %s, %s];
135                addValidator('bbox_hidden_input', 'bounding_box', '%s', 'Your selected spatial bounding box must overlap with the available extent of: (%s) as ("west|south|east|north").', false);
136            </script>
137        </div>
138        """ % (name, w, s, e, n, extent, extent)
139        return html     
140
141    def renderTypeAheadDirList(self, name, base_dir):
142        """
143        Renders type-ahead widget for directory listing.
144        """
145        html = """      <script type="text/javascript" src="/js/ext/jquery-1.3.2/jquery-1.3.2.js"></script>
146        <script type="text/javascript" src="/js/ui/type_ahead_dirs.js"></script>
147        <script type="text/javascript">
148                var current_list = false;
149                var abs_pos_%s = null;
150
151                $(document).ready(function(){
152                        initTypeAhead("%s", "type_ahead_for_%s", "%s");
153                        abs_pos_%s = type_ahead_div.offset();   
154                        positionRespDiv(abs_pos_%s);
155                });
156        </script>
157
158        <p>Press down button to fill with text...</p>
159        <div style="z-index: 1;">
160                <input type="text" id="%s" name="%s" value="" style="width: 505px; height: 25px;" onBlur="hideSuggestions();" onFocus="showSuggestions();" />
161        </div>
162        <!--<span id="resp_container">
163<div id="type_ahead_for_%s" style="width: 500px; background-color: yellow; border-style: solid; border-width: 1px; position: relative;"></div>
164        </span>-->
165        <div id="type_ahead_for_%s" style="width: 500px; background-color: yellow; border-style: solid; border-width: 1px; position: statis;"></div>
166""" % (name, name, name, base_dir, name, name, name, name, name, name)
167        return html 
Note: See TracBrowser for help on using the repository browser.