~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/app/widgets/popup.py

  • Committer: Danilo Segan
  • Date: 2011-04-22 14:02:29 UTC
  • mto: This revision was merged to the branch mainline in revision 12910.
  • Revision ID: danilo@canonical.com-20110422140229-zhq4d4c2k8jpglhf
Ignore hidden files when building combined JS file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
import cgi
11
11
 
12
 
from lazr.restful.utils import safe_hasattr
13
12
import simplejson
14
13
from z3c.ptcompat import ViewPageTemplateFile
15
14
from zope.app.form.browser.itemswidgets import (
18
17
    )
19
18
from zope.schema.interfaces import IChoice
20
19
 
21
 
from lp.app.browser.stringformatter import FormattersAPI
22
 
from lp.app.browser.vocabulary import get_person_picker_entry_metadata
 
20
from canonical.launchpad.webapp import canonical_url
23
21
from lp.services.propertycache import cachedproperty
24
 
from lp.services.webapp import canonical_url
25
 
from lp.services.webapp.vocabulary import IHugeVocabulary
26
22
 
27
23
 
28
24
class VocabularyPickerWidget(SingleDataHelper, ItemsWidgetBase):
30
26
 
31
27
    __call__ = ViewPageTemplateFile('templates/form-picker.pt')
32
28
 
33
 
    picker_type = 'default'
34
 
    # Provide default values for the following properties in case someone
35
 
    # creates a vocab picker for a person instead of using the derived
36
 
    # PersonPicker.
37
 
    show_assign_me_button = False
38
 
    show_remove_button = False
39
 
    assign_me_text = 'Pick me'
40
 
    remove_person_text = 'Remove person'
41
 
    remove_team_text = 'Remove team'
42
 
 
43
29
    popup_name = 'popup-vocabulary-picker'
44
30
 
45
31
    # Override inherited attributes for the form field.
93
79
    def inputField(self):
94
80
        d = {
95
81
            'formToken': cgi.escape(self.formToken, quote=True),
96
 
            'name': self.input_id,
 
82
            'name': self.name,
97
83
            'displayWidth': self.displayWidth,
98
84
            'displayMaxWidth': self.displayMaxWidth,
99
85
            'onKeyPress': self.onKeyPress,
107
93
                         class="%(cssClass)s" />""" % d
108
94
 
109
95
    @property
110
 
    def selected_value(self):
111
 
        """ String representation of field value associated with the picker.
112
 
 
113
 
        Default implementation is to return the 'name' attribute.
114
 
        """
115
 
        val = self._getFormValue()
116
 
        if val is not None and safe_hasattr(val, 'name'):
117
 
            return getattr(val, 'name')
118
 
        return None
119
 
 
120
 
    @property
121
 
    def selected_value_metadata(self):
122
 
        return None
 
96
    def suffix(self):
 
97
        return self.name.replace('.', '-')
123
98
 
124
99
    @property
125
100
    def show_widget_id(self):
126
 
        return 'show-widget-%s' % self.input_id.replace('.', '-')
127
 
 
128
 
    @property
129
 
    def config(self):
130
 
        return dict(
131
 
            picker_type=self.picker_type,
132
 
            selected_value=self.selected_value,
133
 
            selected_value_metadata=self.selected_value_metadata,
134
 
            header=self.header_text, step_title=self.step_title_text,
135
 
            extra_no_results_message=self.extra_no_results_message,
136
 
            assign_me_text=self.assign_me_text,
137
 
            remove_person_text=self.remove_person_text,
138
 
            remove_team_text=self.remove_team_text,
139
 
            show_remove_button=self.show_remove_button,
140
 
            show_assign_me_button=self.show_assign_me_button,
141
 
            vocabulary_name=self.vocabulary_name,
142
 
            vocabulary_filters=self.vocabulary_filters,
143
 
            input_element=self.input_id)
144
 
 
145
 
    @property
146
 
    def json_config(self):
147
 
        return simplejson.dumps(self.config)
 
101
        return 'show-widget-%s' % self.suffix
148
102
 
149
103
    @property
150
104
    def extra_no_results_message(self):
155
109
        :return: A string that will be passed to Y.Node.create()
156
110
                 so it needs to be contained in a single HTML element.
157
111
        """
158
 
        return None
159
 
 
160
 
    @property
161
 
    def vocabulary_filters(self):
162
 
        """The name of the field's vocabulary."""
163
 
        choice = IChoice(self.context)
164
 
        if choice.vocabulary is None:
165
 
            # We need the vocabulary to get the supported filters.
166
 
            raise ValueError(
167
 
                "The %r.%s interface attribute doesn't have its "
168
 
                "vocabulary specified."
169
 
                % (choice.context, choice.__name__))
170
 
        # Only IHugeVocabulary's have filters.
171
 
        if not IHugeVocabulary.providedBy(choice.vocabulary):
172
 
            return []
173
 
        supported_filters = choice.vocabulary.supportedFilters()
174
 
        # If we have no filters or just the ALL filter, then no filtering
175
 
        # support is required.
176
 
        filters = []
177
 
        if (len(supported_filters) == 0 or
178
 
           (len(supported_filters) == 1
179
 
            and supported_filters[0].name == 'ALL')):
180
 
            return filters
181
 
        for filter in supported_filters:
182
 
            filters.append({
183
 
                'name': filter.name,
184
 
                'title': filter.title,
185
 
                'description': filter.description,
186
 
                })
187
 
        return filters
 
112
        return simplejson.dumps(None)
188
113
 
189
114
    @property
190
115
    def vocabulary_name(self):
203
128
 
204
129
    @property
205
130
    def header_text(self):
206
 
        return self.header or self.vocabulary.displayname
 
131
        return simplejson.dumps(self.header or self.vocabulary.displayname)
207
132
 
208
133
    @property
209
134
    def step_title_text(self):
210
 
        return self.step_title or self.vocabulary.step_title
 
135
        return simplejson.dumps(self.step_title or self.vocabulary.step_title)
211
136
 
212
137
    @property
213
138
    def input_id(self):
214
 
        """This is used to ensure the widget id contains only valid chars."""
215
 
        return FormattersAPI(self.name).zope_css_id()
 
139
        return self.name
216
140
 
217
141
    def chooseLink(self):
218
142
        if self.nonajax_uri is None:
233
157
 
234
158
 
235
159
class PersonPickerWidget(VocabularyPickerWidget):
236
 
 
237
160
    include_create_team_link = False
238
 
    show_assign_me_button = True
239
 
    show_remove_button = False
240
 
    picker_type = 'person'
241
 
 
242
 
    @property
243
 
    def selected_value_metadata(self):
244
 
        val = self._getFormValue()
245
 
        return get_person_picker_entry_metadata(val)
246
161
 
247
162
    def chooseLink(self):
248
163
        link = super(PersonPickerWidget, self).chooseLink()
259
174
class BugTrackerPickerWidget(VocabularyPickerWidget):
260
175
 
261
176
    __call__ = ViewPageTemplateFile('templates/bugtracker-picker.pt')
 
177
 
262
178
    link_template = """
263
179
        or (<a id="create-bugtracker-link"
264
180
        href="/bugs/bugtrackers/+newbugtracker"
285
201
 
286
202
    @property
287
203
    def extra_no_results_message(self):
288
 
        return ("<strong>Didn't find the project you were "
 
204
        return simplejson.dumps("<strong>Didn't find the project you were "
289
205
                "looking for? "
290
206
                '<a href="%s/+affects-new-product">Register it</a>.</strong>'
291
207
                % canonical_url(self.context.context))