44from utils import templates
55from random import random
66
7- class Tabs (object ):
8- """Display FieldSet using http://jqueryui.com/demos/tabs/:
7+ class MultiFieldSetProperty (property ):
8+
9+ def __init__ (self , name ):
10+ self .__name__ = '_' + name
11+
12+ def __get__ (self , instance , klass ):
13+ if instance is None :
14+ return klass
15+ return getattr (instance , self .__name__ )
16+
17+ def __set__ (self , instance , value ):
18+ setattr (instance , self .__name__ , value )
19+ for fs in instance ._fs_dict .values ():
20+ setattr (fs , self .__name__ [1 :], value )
21+
22+ class MultiFieldSet (object ):
23+ """Display more than one FieldSet:
924
1025 .. sourcecode:: python
1126
1227 >>> from testing import *
13- >>> tabs = Tabs('my_tabs',
14- ... ('tab1', 'My first tab', fs1),
15- ... footer='<input type="submit" name="%(id)s" />')
16- >>> tabs.append('tab2', 'The second', fs2)
17- >>> tabs.tab1 = tabs.tab1.bind(obj1)
18- >>> tabs.tab2.rebind(obj2)
19- >>> print tabs.render(selected=2) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
20- <div id="my_tabs_...">
21- <ul>
22- <li><a href="#tab1_...">My first tab</a></li>
23- <li><a href="#tab2_...">The second</a></li>
24- </ul>
25- <div id="tab1_...">...
26- </div>
27- <div id="tab2_...">...
28- </div>
28+ >>> fs = MultiFieldSet('my_fieldsets',
29+ ... ('fs1', '', fs1))
30+ >>> fs.append('fs2', 'Second fieldset', fs2)
31+ >>> fs.fs1 = fs.fs1.bind(obj1)
32+ >>> fs.fs2.rebind(obj2)
33+ >>> print fs.render() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
34+ <div id="my_fieldsets_...">
35+ <fieldset id="fs1_...">
36+ <div>
37+ ...
2938 </div>
30- <script type="text/javascript">
31- jQuery.fa.tabs('my_tabs_...', {"selected": 2});
32- </script>
33- <BLANKLINE>
34-
39+ </fieldset>
40+ <fieldset id="fs2_...">
41+ <legend><a href="#fs2_...">Second fieldset</a></legend>
42+ <div>
43+ ...
44+
3545 """
36- engine = None
37- template = templates .get_template ('/forms/tabs.mako' )
46+ template = templates .get_template ('/forms/multifieldset.mako' )
3847 def __init__ (self , id , * fieldsets , ** options ):
3948 if not isinstance (id , basestring ):
4049 raise TypeError ('id must be a string. got %r' % (id ,))
@@ -43,6 +52,10 @@ def __init__(self, id, *fieldsets, **options):
4352 self ._fs_dict = {}
4453 self ._bound_pk = None
4554 self ._options = options
55+ self ._readonly = False
56+ self ._engine = None
57+ self ._focus = False
58+ self ._original_cls = None
4659 for fs in fieldsets :
4760 if not isinstance (fs , (tuple , list )) or len (fs ) != 3 :
4861 raise ValueError ('A form is defined by (id, title, form) got %r' % (fs ,))
@@ -55,15 +68,11 @@ def jsonify(self):
5568 fields .append ((f .key , f .model_value ))
5669 return dict (fields )
5770
58- def _get_bound_pk (self ):
59- for fs in self ._fs :
60- return fs ._bound_pk
61-
62- def _set_bound_pk (self , value ):
63- for fs in self ._fs :
64- fs ._bound_pk = value
65-
66- _bound_pk = property (_get_bound_pk , _set_bound_pk )
71+ _bound_pk = MultiFieldSetProperty ('_bound_pk' )
72+ _request = MultiFieldSetProperty ('_request' )
73+ focus = MultiFieldSetProperty ('focus' )
74+ engine = MultiFieldSetProperty ('engine' )
75+ readonly = MultiFieldSetProperty ('readonly' )
6776
6877 @property
6978 def model (self ):
@@ -90,13 +99,6 @@ def __getattr__(self, attr):
9099 else :
91100 raise AttributeError (attr )
92101
93- def __setattr__ (self , attr , fs ):
94- if attr .startswith ('_' ) or attr in ('engine' , 'readonly' ):
95- object .__setattr__ (self , attr , fs )
96- else :
97- fs .__name__ = attr
98- self ._fs_dict [attr ] = fs
99-
100102 def append (self , id , title , fs ):
101103 """add a fieldset to tabs"""
102104 fs .__name__ = id
@@ -167,14 +169,47 @@ def render(self, *ids, **options):
167169 fieldsets .append (dict (id = id , title = title , fs = fs ))
168170 kwargs = dict (footer = '' , header = '' )
169171 kwargs .update (self ._options )
170- return self .template .render (id = self ._id ,
172+ return self .template .render_unicode (id = self ._id ,
171173 rid = str (random ())[2 :],
172174 fieldsets = fieldsets ,
173175 options = dumps (options ),
174176 ** kwargs )
175177
176- class Accordion (Tabs ):
178+
179+ class Tabs (MultiFieldSet ):
180+ """Display FieldSet using http://jqueryui.com/demos/tabs/:
181+
182+ .. sourcecode:: python
183+
184+ >>> from testing import *
185+ >>> tabs = Tabs('my_tabs',
186+ ... ('tab1', 'My first tab', fs1),
187+ ... footer='<input type="submit" name="%(id)s" />')
188+ >>> tabs.append('tab2', 'The second', fs2)
189+ >>> tabs.tab1 = tabs.tab1.bind(obj1)
190+ >>> tabs.tab2.rebind(obj2)
191+ >>> print tabs.render(selected=2) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
192+ <div id="my_tabs_...">
193+ <ul>
194+ <li><a href="#tab1_...">My first tab</a></li>
195+ <li><a href="#tab2_...">The second</a></li>
196+ </ul>
197+ <div id="tab1_...">...
198+ </div>
199+ <div id="tab2_...">...
200+ </div>
201+ </div>
202+ <script type="text/javascript">
203+ jQuery.fa.tabs('my_tabs_...', {"selected": 2});
204+ </script>
205+ <BLANKLINE>
206+
207+ """
208+ template = templates .get_template ('/forms/tabs.mako' )
209+
210+ class Accordion (MultiFieldSet ):
177211 """Work like :class:`~fa.jquery.forms.Tabs` but use
178212 http://jqueryui.com/demos/accordion/
179213 """
180214 template = templates .get_template ('/forms/accordion.mako' )
215+
0 commit comments