web/views/tabs.py
changeset 6952 7de13eb473e3
parent 6582 8eb7883b4223
child 6997 88b4fdce7c91
equal deleted inserted replaced
6951:cb6314b09e0f 6952:7de13eb473e3
    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