web/views/tabs.py
changeset 1000 90705536b7c8
parent 999 999198995a53
child 1006 92a0601b2523
child 1079 452cb76fe07a
equal deleted inserted replaced
999:999198995a53 1000:90705536b7c8
     1 """base classes to handle tabbed views
     1 """base classes to handle tabbed views
     2 
     2 
     3 :organization: Logilab
     3 :organization: Logilab
     4 :copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 """
     6 """
     7 
     7 
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
     9 
     9 
    10 from logilab.common.decorators import monkeypatch
    10 from logilab.common.decorators import monkeypatch
    11 from logilab.mtconverter import html_escape
    11 from logilab.mtconverter import html_escape
    12 
    12 
    13 from cubicweb import NoSelectableObject, role
    13 from cubicweb import NoSelectableObject, role
    14 from cubicweb.common.view import EntityView
    14 from cubicweb.common.view import EntityView 
    15 from cubicweb.common.selectors import has_related_entities
    15 from cubicweb.common.selectors import has_related_entities
    16 from cubicweb.common.utils import HTMLHead
    16 from cubicweb.common.utils import HTMLHead
    17 from cubicweb.common.uilib import rql_for_eid
    17 from cubicweb.common.uilib import rql_for_eid
    18 
    18 
    19 from cubicweb.web.views.basecontrollers import JSonController
    19 from cubicweb.web.views.basecontrollers import JSonController
    31   jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) {
    31   jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) {
    32      load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s);
    32      load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s);
    33   });""" % {'event': 'load_%s' % vid, 'vid': vid,
    33   });""" % {'event': 'load_%s' % vid, 'vid': vid,
    34             'reloadable' : str(reloadable).lower()})
    34             'reloadable' : str(reloadable).lower()})
    35 
    35 
    36     def lazyview(self, vid, eid=None, reloadable=False, show_spinbox=True, w=None):
    36     def lazyview(self, vid, rql=None, eid=None, rset=None, static=False,
       
    37                  reloadable=False, show_spinbox=True, w=None):
    37         """a lazy version of wview
    38         """a lazy version of wview
    38         first version only support lazy viewing for an entity at a time
    39         first version only support lazy viewing for an entity at a time
    39         """
    40         """
       
    41         assert rql or eid or rset or static, \
       
    42             'lazyview wants at least : rql, or an eid, or an rset -- or call it with static=True'
    40         w = w or self.w
    43         w = w or self.w
    41         self.req.add_js('cubicweb.lazy.js')
    44         self.req.add_js('cubicweb.lazy.js')
    42         urlparams = {'vid' : vid, 'mode' : 'html'}
    45         urlparams = {'vid' : vid, 'mode' : 'html'}
    43         if eid:
    46         if rql:
       
    47             urlparams['rql'] = rql
       
    48         elif eid:
    44             urlparams['rql'] = rql_for_eid(eid)
    49             urlparams['rql'] = rql_for_eid(eid)
       
    50         elif rset:
       
    51             urlparams['rql'] = rset.printable_rql()
    45         w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % (
    52         w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % (
    46             vid, html_escape(self.build_url('json', **urlparams))))
    53             vid, html_escape(self.build_url('json', **urlparams))))
    47         if show_spinbox:
    54         if show_spinbox:
    48             w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>'
    55             w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>'
    49               % (vid, self.req._('loading')))
    56               % (vid, self.req._('loading')))
    63     @property
    70     @property
    64     def cookie_name(self):
    71     def cookie_name(self):
    65         return str('%s_active_tab' % self.config.appid)
    72         return str('%s_active_tab' % self.config.appid)
    66 
    73 
    67     def active_tab(self, tabs, default):
    74     def active_tab(self, tabs, default):
    68         cookie = self.req.get_cookie()
    75         cookies = self.req.get_cookie()
    69         cookiename = self.cookie_name
    76         cookiename = self.cookie_name
    70         activetab = cookie.get(cookiename)
    77         activetab = cookies.get(cookiename)
    71         if activetab is None:
    78         if activetab is None:
    72             cookie[cookiename] = default
    79             cookies[cookiename] = default
    73             self.req.set_cookie(cookie, cookiename)
    80             self.req.set_cookie(cookies, cookiename)
    74             tab = default
    81             tab = default
    75         else:
    82         else:
    76             tab = activetab.value
    83             tab = activetab.value
    77         return tab in tabs and tab or default
    84         return tab in tabs and tab or default
    78 
    85 
    99         tabs = self.prune_tabs(tabs)
   106         tabs = self.prune_tabs(tabs)
   100         # select a tab
   107         # select a tab
   101         active_tab = self.active_tab(tabs, default)
   108         active_tab = self.active_tab(tabs, default)
   102         # build the html structure
   109         # build the html structure
   103         w = self.w
   110         w = self.w
   104         w(u'<div id="entity-tabs">')
   111         w(u'<div id="entity-tabs-%s">' % entity.eid)
   105         w(u'<ul>')
   112         w(u'<ul>')
   106         for tab in tabs:
   113         for tab in tabs:
   107             w(u'<li>')
   114             w(u'<li>')
   108             w(u'<a href="#as-%s">' % tab)
   115             w(u'<a href="#as-%s">' % tab)
   109             w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tab, self.cookie_name))
   116             w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tab, self.cookie_name))
   113             w(u'</li>')
   120             w(u'</li>')
   114         w(u'</ul>')
   121         w(u'</ul>')
   115         w(u'</div>')
   122         w(u'</div>')
   116         for tab in tabs:
   123         for tab in tabs:
   117             w(u'<div id="as-%s">' % tab)
   124             w(u'<div id="as-%s">' % tab)
   118             self.lazyview(tab, entity.eid)
   125             self.lazyview(tab, eid=entity.eid)
   119             w(u'</div>')
   126             w(u'</div>')
   120         # call the set_tab() JS function *after* each tab is generated
   127         # call the set_tab() JS function *after* each tab is generated
   121         # because the callback binding needs to be done before
   128         # because the callback binding needs to be done before
   122         self.req.html_headers.add_onload(u"""
   129         self.req.html_headers.add_onload(u"""
   123    jQuery('#entity-tabs > ul').tabs( { selected: %(tabindex)s });
   130    jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s });
   124    set_tab('%(vid)s', '%(cookiename)s');
   131    set_tab('%(vid)s', '%(cookiename)s');
   125  """ % {'tabindex'   : tabs.index(active_tab),
   132  """ % {'tabindex'   : tabs.index(active_tab),
   126         'vid'        : active_tab,
   133         'vid'        : active_tab,
       
   134         'eeid'       : entity.eid,
   127         'cookiename' : self.cookie_name})
   135         'cookiename' : self.cookie_name})
   128 
   136 
   129 
   137 
   130 class EntityRelatedTab(EntityView):
   138 class EntityRelatedTab(EntityView):
   131     """A view you should inherit from leftmost,
   139     """A view you should inherit from leftmost,
   141         rtype = 'screenshot'
   149         rtype = 'screenshot'
   142         target = 'object'
   150         target = 'object'
   143         vid = 'gallery'
   151         vid = 'gallery'
   144         __selectors__ = EntityRelationView.__selectors__ + (one_line_rset,)
   152         __selectors__ = EntityRelationView.__selectors__ + (one_line_rset,)
   145 
   153 
   146 
       
   147     This is the view we want to have in a tab, only if there is something to show.
   154     This is the view we want to have in a tab, only if there is something to show.
   148     Then, just define as below, and declare this being the tab content :
   155     Then, just define as below, and declare this being the tab content :
   149 
   156 
   150     class ProjectScreenshotTab(DataDependantTab, ProjectScreenshotsView):
   157     class ProjectScreenshotTab(EntityRelatedTab, ProjectScreenshotsView):
   151         id = 'screenshots_tab'
   158         id = 'screenshots_tab'
   152     """
   159     """
   153     __selectors__ = EntityView.__selectors__ + (has_related_entities,)
   160     __selectors__ = EntityView.__selectors__ + (has_related_entities,)
   154     vid = 'list'
   161     vid = 'list'
   155 
   162