28 jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) { |
28 jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) { |
29 load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s); |
29 load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s); |
30 });""" % {'event': 'load_%s' % vid, 'vid': vid, |
30 });""" % {'event': 'load_%s' % vid, 'vid': vid, |
31 'reloadable' : str(reloadable).lower()}) |
31 'reloadable' : str(reloadable).lower()}) |
32 |
32 |
33 def lazyview(self, vid, rql=None, eid=None, rset=None, static=False, |
33 def lazyview(self, vid, rql=None, eid=None, rset=None, tabid=None, |
34 reloadable=False, show_spinbox=True, w=None): |
34 reloadable=False, show_spinbox=True, w=None): |
35 """a lazy version of wview |
35 """a lazy version of wview |
36 first version only support lazy viewing for an entity at a time |
36 first version only support lazy viewing for an entity at a time |
37 """ |
37 """ |
38 assert rql or eid or rset or static, \ |
|
39 'lazyview wants at least : rql, or an eid, or an rset -- or call it with static=True' |
|
40 w = w or self.w |
38 w = w or self.w |
41 self.req.add_js('cubicweb.lazy.js') |
39 self.req.add_js('cubicweb.lazy.js') |
42 urlparams = {'vid' : vid, 'fname' : 'view'} |
40 urlparams = {'vid' : vid, 'fname' : 'view'} |
43 if rql: |
41 if rql: |
44 urlparams['rql'] = rql |
42 urlparams['rql'] = rql |
45 elif eid: |
43 elif eid: |
46 urlparams['rql'] = uilib.rql_for_eid(eid) |
44 urlparams['rql'] = uilib.rql_for_eid(eid) |
47 elif rset: |
45 elif rset: |
48 urlparams['rql'] = rset.printable_rql() |
46 urlparams['rql'] = rset.printable_rql() |
49 w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % ( |
47 w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % ( |
50 vid, xml_escape(self.build_url('json', **urlparams)))) |
48 tabid or vid, xml_escape(self.build_url('json', **urlparams)))) |
51 if show_spinbox: |
49 if show_spinbox: |
52 w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>' |
50 w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>' |
53 % (vid, self.req._('loading'))) |
51 % (tabid or vid, self.req._('loading'))) |
54 w(u'</div>') |
52 w(u'</div>') |
55 self._prepare_bindings(vid, reloadable) |
53 self._prepare_bindings(tabid or vid, reloadable) |
56 |
54 |
57 def forceview(self, vid): |
55 def forceview(self, vid): |
58 """trigger an event that will force immediate loading of the view |
56 """trigger an event that will force immediate loading of the view |
59 on dom readyness |
57 on dom readyness |
60 """ |
58 """ |
68 |
66 |
69 @property |
67 @property |
70 def cookie_name(self): |
68 def cookie_name(self): |
71 return str('%s_active_tab' % self.config.appid) |
69 return str('%s_active_tab' % self.config.appid) |
72 |
70 |
73 def active_tab(self, tabs, default): |
71 def active_tab(self, default): |
74 formtab = self.req.form.get('tab') |
72 if 'tab' in self.req.form: |
75 if formtab in tabs: |
73 return self.req.form['tab'] |
76 return formtab |
|
77 cookies = self.req.get_cookie() |
74 cookies = self.req.get_cookie() |
78 cookiename = self.cookie_name |
75 cookiename = self.cookie_name |
79 activetab = cookies.get(cookiename) |
76 activetab = cookies.get(cookiename) |
80 if activetab is None: |
77 if activetab is None: |
81 cookies[cookiename] = default |
78 cookies[cookiename] = default |
82 self.req.set_cookie(cookies, cookiename) |
79 self.req.set_cookie(cookies, cookiename) |
83 tab = default |
80 return default |
84 else: |
81 return activetab.value |
85 tab = activetab.value |
|
86 return tab in tabs and tab or default |
|
87 |
82 |
88 def prune_tabs(self, tabs): |
83 def prune_tabs(self, tabs, default_tab): |
89 selected_tabs = [] |
84 selected_tabs = [] |
|
85 may_be_active_tab = self.active_tab(default_tab) |
|
86 active_tab = default_tab |
|
87 viewsvreg = self.vreg['views'] |
90 for tab in tabs: |
88 for tab in tabs: |
91 try: |
89 try: |
92 self.vreg['views'].select(tab, self.req, rset=self.rset) |
90 tabid, tabkwargs = tab |
93 selected_tabs.append(tab) |
91 tabkwargs = tabkwargs.copy() |
|
92 except ValueError: |
|
93 tabid, tabkwargs = tab, {} |
|
94 tabkwargs.setdefault('rset', self.rset) |
|
95 vid = tabkwargs.get('vid', tabid) |
|
96 try: |
|
97 viewsvreg.select(vid, self.req, **tabkwargs) |
|
98 selected_tabs.append((tabid, tabkwargs)) |
94 except NoSelectableObject: |
99 except NoSelectableObject: |
95 continue |
100 continue |
96 return selected_tabs |
101 if tabid == may_be_active_tab: |
|
102 active_tab = tabid |
|
103 return selected_tabs, active_tab |
97 |
104 |
98 def render_tabs(self, tabs, default, entity=None): |
105 def render_tabs(self, tabs, default, entity=None): |
99 # delegate to the default tab if there is more than one entity |
106 # delegate to the default tab if there is more than one entity |
100 # in the result set (tabs are pretty useless there) |
107 # in the result set (tabs are pretty useless there) |
101 if entity and len(self.rset) > 1: |
108 if entity and len(self.rset) > 1: |
103 return |
110 return |
104 self.req.add_css('ui.tabs.css') |
111 self.req.add_css('ui.tabs.css') |
105 self.req.add_js(('ui.core.js', 'ui.tabs.js', |
112 self.req.add_js(('ui.core.js', 'ui.tabs.js', |
106 'cubicweb.ajax.js', 'cubicweb.tabs.js', 'cubicweb.lazy.js')) |
113 'cubicweb.ajax.js', 'cubicweb.tabs.js', 'cubicweb.lazy.js')) |
107 # prune tabs : not all are to be shown |
114 # prune tabs : not all are to be shown |
108 tabs = self.prune_tabs(tabs) |
115 tabs, active_tab = self.prune_tabs(tabs, default) |
109 # select a tab |
|
110 active_tab = self.active_tab(tabs, default) |
|
111 # build the html structure |
116 # build the html structure |
112 w = self.w |
117 w = self.w |
113 uid = entity and entity.eid or make_uid('tab') |
118 uid = entity and entity.eid or make_uid('tab') |
114 w(u'<div id="entity-tabs-%s">' % uid) |
119 w(u'<div id="entity-tabs-%s">' % uid) |
115 w(u'<ul>') |
120 w(u'<ul>') |
116 for tab in tabs: |
121 active_tab_idx = None |
|
122 for i, (tabid, tabkwargs) in enumerate(tabs): |
117 w(u'<li>') |
123 w(u'<li>') |
118 w(u'<a href="#%s">' % tab) |
124 w(u'<a href="#%s">' % tabid) |
119 w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tab, self.cookie_name)) |
125 w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tabid, self.cookie_name)) |
120 w(self.req._(tab)) |
126 w(tabkwargs.pop('label', self.req._(tabid))) |
121 w(u'</span>') |
127 w(u'</span>') |
122 w(u'</a>') |
128 w(u'</a>') |
123 w(u'</li>') |
129 w(u'</li>') |
|
130 if tabid == active_tab: |
|
131 active_tab_idx = i |
124 w(u'</ul>') |
132 w(u'</ul>') |
125 w(u'</div>') |
133 w(u'</div>') |
126 for tab in tabs: |
134 for tabid, tabkwargs in tabs: |
127 w(u'<div id="%s">' % tab) |
135 w(u'<div id="%s">' % tabid) |
128 if entity: |
136 tabkwargs.setdefault('tabid', tabid) |
129 self.lazyview(tab, eid=entity.eid) |
137 tabkwargs.setdefault('vid', tabid) |
130 else: |
138 tabkwargs.setdefault('rset', self.rset) |
131 self.lazyview(tab, static=True) |
139 self.lazyview(**tabkwargs) |
132 w(u'</div>') |
140 w(u'</div>') |
133 # call the set_tab() JS function *after* each tab is generated |
141 # call the set_tab() JS function *after* each tab is generated |
134 # because the callback binding needs to be done before |
142 # because the callback binding needs to be done before |
135 # XXX make work history: true |
143 # XXX make work history: true |
136 self.req.add_onload(u""" |
144 self.req.add_onload(u""" |
137 jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s }); |
145 jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s }); |
138 set_tab('%(vid)s', '%(cookiename)s'); |
146 set_tab('%(vid)s', '%(cookiename)s'); |
139 """ % {'tabindex' : tabs.index(active_tab), |
147 """ % {'tabindex' : active_tab_idx, |
140 'vid' : active_tab, |
148 'vid' : active_tab, |
141 'eeid' : (entity and entity.eid or uid), |
149 'eeid' : (entity and entity.eid or uid), |
142 'cookiename' : self.cookie_name}) |
150 'cookiename' : self.cookie_name}) |
143 |
151 |
144 |
152 |