22 |
22 |
23 from logilab.common.deprecation import class_renamed |
23 from logilab.common.deprecation import class_renamed |
24 from logilab.mtconverter import xml_escape |
24 from logilab.mtconverter import xml_escape |
25 |
25 |
26 from cubicweb import NoSelectableObject, role |
26 from cubicweb import NoSelectableObject, role |
|
27 from cubicweb import tags, uilib, utils |
27 from cubicweb.selectors import partial_has_related_entities |
28 from cubicweb.selectors import partial_has_related_entities |
28 from cubicweb.view import EntityView |
29 from cubicweb.view import EntityView |
29 from cubicweb import tags, uilib |
|
30 from cubicweb.utils import make_uid |
|
31 from cubicweb.web.views import primary |
30 from cubicweb.web.views import primary |
32 |
31 |
33 class LazyViewMixin(object): |
32 class LazyViewMixin(object): |
34 """provides two convenience methods for the tab machinery |
33 """provides two convenience methods for the tab machinery. |
35 can also be used to lazy-load arbitrary views |
34 |
|
35 Can also be used to lazy-load arbitrary views. |
36 """ |
36 """ |
37 |
37 |
38 def _prepare_bindings(self, vid, reloadable): |
38 def _prepare_bindings(self, vid, reloadable): |
39 self._cw.add_onload(u""" |
39 self._cw.add_onload(u""" |
40 jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) { |
40 jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) { |
41 load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s); |
41 loadNow('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s); |
42 });""" % {'event': 'load_%s' % vid, 'vid': vid, |
42 });""" % {'event': 'load_%s' % vid, 'vid': vid, |
43 'reloadable' : str(reloadable).lower()}) |
43 'reloadable' : str(reloadable).lower()}) |
44 |
44 |
45 def lazyview(self, vid, rql=None, eid=None, rset=None, tabid=None, |
45 def lazyview(self, vid, rql=None, eid=None, rset=None, tabid=None, |
46 reloadable=False, show_spinbox=True, w=None): |
46 reloadable=False, show_spinbox=True, w=None): |
47 """ a lazy version of wview """ |
47 """a lazy version of wview""" |
48 w = w or self.w |
48 w = w or self.w |
49 self._cw.add_js('cubicweb.lazy.js') |
|
50 urlparams = {'vid' : vid, 'fname' : 'view'} |
49 urlparams = {'vid' : vid, 'fname' : 'view'} |
51 if rql: |
50 if rql: |
52 urlparams['rql'] = rql |
51 urlparams['rql'] = rql |
53 elif eid: |
52 elif eid: |
54 urlparams['rql'] = uilib.rql_for_eid(eid) |
53 urlparams['rql'] = uilib.rql_for_eid(eid) |
68 (tabid, self._cw._('follow this link if javascript is deactivated')))) |
67 (tabid, self._cw._('follow this link if javascript is deactivated')))) |
69 w(u'</div>') |
68 w(u'</div>') |
70 self._prepare_bindings(tabid, reloadable) |
69 self._prepare_bindings(tabid, reloadable) |
71 |
70 |
72 def forceview(self, vid): |
71 def forceview(self, vid): |
73 """trigger an event that will force immediate loading of the view |
72 """trigger an event that will force immediate loading of the view on dom |
74 on dom readyness |
73 readyness |
75 """ |
74 """ |
76 self._cw.add_js('cubicweb.lazy.js') |
75 self._cw.add_onload(uilib.js.triggerLoad(vid)) |
77 self._cw.add_onload("trigger_load('%s');" % vid) |
|
78 |
76 |
79 |
77 |
80 class TabsMixin(LazyViewMixin): |
78 class TabsMixin(LazyViewMixin): |
81 """a tab mixin |
79 """a tab mixin to easily get jQuery based, lazy, ajax tabs""" |
82 """ |
|
83 |
80 |
84 @property |
81 @property |
85 def cookie_name(self): |
82 def cookie_name(self): |
86 return str('%s_active_tab' % self._cw.vreg.config.appid) |
83 return str('%s_active_tab' % self._cw.vreg.config.appid) |
87 |
84 |
102 selected_tabs = [] |
99 selected_tabs = [] |
103 may_be_active_tab = self.active_tab(default_tab) |
100 may_be_active_tab = self.active_tab(default_tab) |
104 active_tab = uilib.domid(default_tab) |
101 active_tab = uilib.domid(default_tab) |
105 viewsvreg = self._cw.vreg['views'] |
102 viewsvreg = self._cw.vreg['views'] |
106 for tab in tabs: |
103 for tab in tabs: |
107 try: |
104 if isinstance(tab, basestring): |
|
105 tabid, tabkwargs = tab, {} |
|
106 else: |
108 tabid, tabkwargs = tab |
107 tabid, tabkwargs = tab |
109 tabkwargs = tabkwargs.copy() |
108 tabkwargs = tabkwargs.copy() |
110 except ValueError: |
|
111 tabid, tabkwargs = tab, {} |
|
112 tabkwargs.setdefault('rset', self.cw_rset) |
109 tabkwargs.setdefault('rset', self.cw_rset) |
113 vid = tabkwargs.get('vid', tabid) |
110 vid = tabkwargs.get('vid', tabid) |
114 domid = uilib.domid(tabid) |
111 domid = uilib.domid(tabid) |
115 try: |
112 try: |
116 viewsvreg.select(vid, self._cw, **tabkwargs) |
113 viewsvreg.select(vid, self._cw, **tabkwargs) |
126 # in the result set (tabs are pretty useless there) |
123 # in the result set (tabs are pretty useless there) |
127 if entity and len(self.cw_rset) > 1: |
124 if entity and len(self.cw_rset) > 1: |
128 entity.view(default, w=self.w) |
125 entity.view(default, w=self.w) |
129 return |
126 return |
130 self._cw.add_css('ui.tabs.css') |
127 self._cw.add_css('ui.tabs.css') |
131 self._cw.add_js(('ui.core.js', 'ui.tabs.js', |
128 self._cw.add_js(('ui.core.js', 'ui.tabs.js', 'cubicweb.ajax.js')) |
132 'cubicweb.ajax.js', 'cubicweb.tabs.js', 'cubicweb.lazy.js')) |
|
133 # prune tabs : not all are to be shown |
129 # prune tabs : not all are to be shown |
134 tabs, active_tab = self.prune_tabs(tabs, default) |
130 tabs, active_tab = self.prune_tabs(tabs, default) |
135 # build the html structure |
131 # build the html structure |
136 w = self.w |
132 w = self.w |
137 uid = entity and entity.eid or make_uid('tab') |
133 uid = entity and entity.eid or utils.make_uid('tab') |
138 w(u'<div id="entity-tabs-%s">' % uid) |
134 w(u'<div id="entity-tabs-%s">' % uid) |
139 w(u'<ul>') |
135 w(u'<ul>') |
140 active_tab_idx = None |
136 active_tab_idx = None |
141 for i, (tabid, domid, tabkwargs) in enumerate(tabs): |
137 for i, (tabid, domid, tabkwargs) in enumerate(tabs): |
142 w(u'<li>') |
138 w(u'<li>') |
143 w(u'<a href="#%s">' % domid) |
139 w(u'<a href="#%s">' % domid) |
144 w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (domid, self.cookie_name)) |
140 w(u'<span onclick="%s">' % xml_escape(unicode(uilib.js.setTab(domid, self.cookie_name)))) |
145 w(tabkwargs.pop('label', self._cw._(tabid))) |
141 w(tabkwargs.pop('label', self._cw._(tabid))) |
146 w(u'</span>') |
142 w(u'</span>') |
147 w(u'</a>') |
143 w(u'</a>') |
148 w(u'</li>') |
144 w(u'</li>') |
149 if domid == active_tab: |
145 if domid == active_tab: |
155 tabkwargs.setdefault('tabid', domid) |
151 tabkwargs.setdefault('tabid', domid) |
156 tabkwargs.setdefault('vid', tabid) |
152 tabkwargs.setdefault('vid', tabid) |
157 tabkwargs.setdefault('rset', self.cw_rset) |
153 tabkwargs.setdefault('rset', self.cw_rset) |
158 self.lazyview(**tabkwargs) |
154 self.lazyview(**tabkwargs) |
159 w(u'</div>') |
155 w(u'</div>') |
160 # call the set_tab() JS function *after* each tab is generated |
156 # call the setTab() JS function *after* each tab is generated |
161 # because the callback binding needs to be done before |
157 # because the callback binding needs to be done before |
162 # XXX make work history: true |
158 # XXX make work history: true |
163 self._cw.add_onload(u""" |
159 self._cw.add_onload(u""" |
164 jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s }); |
160 jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s }); |
165 set_tab('%(domid)s', '%(cookiename)s'); |
161 setTab('%(domid)s', '%(cookiename)s'); |
166 """ % {'tabindex' : active_tab_idx, |
162 """ % {'tabindex' : active_tab_idx, |
167 'domid' : active_tab, |
163 'domid' : active_tab, |
168 'eeid' : (entity and entity.eid or uid), |
164 'eeid' : (entity and entity.eid or uid), |
169 'cookiename' : self.cookie_name}) |
165 'cookiename' : self.cookie_name}) |
170 |
166 |