cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
widgets.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 ##
21 # @package src.wi.utils.widgets
22 #
23 # @author Piotr Wójcik
24 # @date 20.10.2010
25 #
26 
27 from itertools import chain
28 
29 from django.forms.widgets import Select, CheckboxSelectMultiple, CheckboxInput
30 from django.utils.encoding import force_unicode
31 from django.utils.html import escape, conditional_escape
32 from django.utils.safestring import mark_safe
33 from django.utils.translation import ugettext as _
34 
35 
36 ##
37 #
38 # Subclass of Django's select widget that allows disabling options.
39 # To disable an option, pass a dict instead of a string for its label,
40 # of the form:
41 # @code
42 # {'label': 'option label', 'disabled': True}
43 # @endcode
44 #
45 class SelectWithDisabled(Select):
46  ##
47  #
48  #
49  def render_option(self, selected_choices, option_value, option_label):
50  option_value = force_unicode(option_value)
51  if (option_value in selected_choices):
52  selected_html = u' selected="selected"'
53  else:
54  selected_html = ''
55  disabled_html = ''
56  if isinstance(option_label, dict):
57  if dict.get(option_label, 'disabled'):
58  disabled_html = u' disabled="disabled"'
59  option_label = option_label['label']
60  return u'<option value="%s"%s%s>%s</option>' % (
61  escape(option_value), selected_html, disabled_html,
62  conditional_escape(force_unicode(option_label)))
63 
64 
65 ##
66 #
67 # Widget adding 'disabled' option to CheckboxSelectMultiple.
68 #
69 class CheckboxSelectMultipleWithDisabled(CheckboxSelectMultiple):
70  def render(self, name, value, attrs=None, choices=()):
71  if value is None:
72  value = []
73  has_id = attrs and 'id' in attrs
74  final_attrs = self.build_attrs(attrs, name=name)
75  output = [u'<ul class="multipleCheckBox %s">' % (u'disabled' if len(self.choices) == 0 else u'')]
76 
77  if len(self.choices) == 0:
78  output.append(u'<li><label> %s </label></li>' % (_('none available')))
79 
80  # Normalize to strings
81  str_values = set([force_unicode(v) for v in value])
82  for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
83  # If an ID attribute was given, add a numeric index as a suffix,
84  # so that the checkboxes don't all have the same ID attribute.
85  if has_id:
86  final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
87  label_for = u' for="%s"' % final_attrs['id']
88  else:
89  label_for = ''
90 
91  chb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
92 
93  li_class = ''
94  if isinstance(option_label, dict):
95  if dict.get(option_label, 'disabled'):
96  chb.attrs['disabled'] = 'disabled'
97  li_class = 'disabled'
98  option_label = option_label['label']
99 
100  option_value = force_unicode(option_value)
101  rendered_cb = chb.render(name, option_value)
102  option_label = conditional_escape(force_unicode(option_label))
103  output.append(u'<li class="%s"><label%s>%s %s</label></li>' % (li_class, label_for, rendered_cb, option_label))
104 
105  output.append(u'</ul>')
106  return mark_safe(u'\n'.join(output))
107