web/views/tabs.py
branchtls-sprint
changeset 939 ad72e06320e2
parent 886 0b417be91dca
parent 917 51d5224b1698
child 940 15dcdc863965
equal deleted inserted replaced
913:5dfba71b1872 939:ad72e06320e2
    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.selectors import partial_has_related_entities
    14 from cubicweb.selectors import partial_has_related_entities
    15 from cubicweb.common.view import EntityView
    15 from cubicweb.common.view import EntityView
       
    16 from cubicweb.common.selectors import has_related_entities
    16 from cubicweb.common.utils import HTMLHead
    17 from cubicweb.common.utils import HTMLHead
    17 from cubicweb.common.uilib import rql_for_eid
    18 from cubicweb.common.uilib import rql_for_eid
    18 
    19 
    19 from cubicweb.web.views.basecontrollers import JSonController
    20 from cubicweb.web.views.basecontrollers import JSonController
    20 
    21 
    31   jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) {
    32   jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) {
    32      load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s);
    33      load_now('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s);
    33   });""" % {'event': 'load_%s' % vid, 'vid': vid,
    34   });""" % {'event': 'load_%s' % vid, 'vid': vid,
    34             'reloadable' : str(reloadable).lower()})
    35             'reloadable' : str(reloadable).lower()})
    35 
    36 
    36     def lazyview(self, vid, eid=None, reloadable=False, show_spinbox=True, w=None):
    37     def lazyview(self, vid, rql=None, eid=None, rset=None, static=False,
       
    38                  reloadable=False, show_spinbox=True, w=None):
    37         """a lazy version of wview
    39         """a lazy version of wview
    38         first version only support lazy viewing for an entity at a time
    40         first version only support lazy viewing for an entity at a time
    39         """
    41         """
       
    42         assert rql or eid or rset or static, \
       
    43             'lazyview wants at least : rql, or an eid, or an rset -- or call it with static=True'
    40         w = w or self.w
    44         w = w or self.w
    41         self.req.add_js('cubicweb.lazy.js')
    45         self.req.add_js('cubicweb.lazy.js')
    42         urlparams = {'vid' : vid, 'mode' : 'html'}
    46         urlparams = {'vid' : vid, 'mode' : 'html'}
    43         if eid:
    47         if rql:
       
    48             urlparams['rql'] = rql
       
    49         elif eid:
    44             urlparams['rql'] = rql_for_eid(eid)
    50             urlparams['rql'] = rql_for_eid(eid)
       
    51         elif rset:
       
    52             urlparams['rql'] = rset.printable_rql()
    45         w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % (
    53         w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % (
    46             vid, html_escape(self.build_url('json', **urlparams))))
    54             vid, html_escape(self.build_url('json', **urlparams))))
    47         if show_spinbox:
    55         if show_spinbox:
    48             w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>'
    56             w(u'<img src="data/loading.gif" id="%s-hole" alt="%s"/>'
    49               % (vid, self.req._('loading')))
    57               % (vid, self.req._('loading')))
    63     @property
    71     @property
    64     def cookie_name(self):
    72     def cookie_name(self):
    65         return str('%s_active_tab' % self.config.appid)
    73         return str('%s_active_tab' % self.config.appid)
    66 
    74 
    67     def active_tab(self, tabs, default):
    75     def active_tab(self, tabs, default):
    68         cookie = self.req.get_cookie()
    76         cookies = self.req.get_cookie()
    69         cookiename = self.cookie_name
    77         cookiename = self.cookie_name
    70         activetab = cookie.get(cookiename)
    78         activetab = cookies.get(cookiename)
    71         if activetab is None:
    79         if activetab is None:
    72             cookie[cookiename] = default
    80             cookies[cookiename] = default
    73             self.req.set_cookie(cookie, cookiename)
    81             self.req.set_cookie(cookies, cookiename)
    74             tab = default
    82             tab = default
    75         else:
    83         else:
    76             tab = activetab.value
    84             tab = activetab.value
    77         return tab in tabs and tab or default
    85         return tab in tabs and tab or default
    78 
    86 
    94         tabs = self.prune_tabs(tabs)
   102         tabs = self.prune_tabs(tabs)
    95         # select a tab
   103         # select a tab
    96         active_tab = self.active_tab(tabs, default)
   104         active_tab = self.active_tab(tabs, default)
    97         # build the html structure
   105         # build the html structure
    98         w = self.w
   106         w = self.w
    99         w(u'<div id="entity-tabs">')
   107         w(u'<div id="entity-tabs-%s">' % entity.eid)
   100         w(u'<ul>')
   108         w(u'<ul>')
   101         for tab in tabs:
   109         for tab in tabs:
   102             w(u'<li>')
   110             w(u'<li>')
   103             w(u'<a href="#as-%s">' % tab)
   111             w(u'<a href="#as-%s">' % tab)
   104             w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tab, self.cookie_name))
   112             w(u'<span onclick="set_tab(\'%s\', \'%s\')">' % (tab, self.cookie_name))
   108             w(u'</li>')
   116             w(u'</li>')
   109         w(u'</ul>')
   117         w(u'</ul>')
   110         w(u'</div>')
   118         w(u'</div>')
   111         for tab in tabs:
   119         for tab in tabs:
   112             w(u'<div id="as-%s">' % tab)
   120             w(u'<div id="as-%s">' % tab)
   113             self.lazyview(tab, entity.eid)
   121             self.lazyview(tab, eid=entity.eid)
   114             w(u'</div>')
   122             w(u'</div>')
   115         # call the set_tab() JS function *after* each tab is generated
   123         # call the set_tab() JS function *after* each tab is generated
   116         # because the callback binding needs to be done before
   124         # because the callback binding needs to be done before
   117         self.req.html_headers.add_onload(u"""
   125         self.req.html_headers.add_onload(u"""
   118    jQuery('#entity-tabs > ul').tabs( { selected: %(tabindex)s });
   126    jQuery('#entity-tabs-%(eeid)s > ul').tabs( { selected: %(tabindex)s });
   119    set_tab('%(vid)s', '%(cookiename)s');
   127    set_tab('%(vid)s', '%(cookiename)s');
   120  """ % {'tabindex'   : tabs.index(active_tab),
   128  """ % {'tabindex'   : tabs.index(active_tab),
   121         'vid'        : active_tab,
   129         'vid'        : active_tab,
       
   130         'eeid'       : entity.eid,
   122         'cookiename' : self.cookie_name})
   131         'cookiename' : self.cookie_name})
   123 
   132 
   124 
   133 
   125 
   134 class EntityRelatedTab(EntityView):
   126 class EntityRelationView(EntityView):
   135     """A view you should inherit from leftmost,
   127     """view displaying entity related stuff. Such a view _must_ provide rtype
   136     to wrap another actual view displaying entity related stuff.
   128     and target attributes
   137     Such a view _must_ provide the rtype, target and vid attributes :
   129 
   138 
   130     Example :
   139     Example :
   131 
   140 
   132     class ProjectScreenshotsView(EntityRelationView):
   141     class ProjectScreenshotsView(EntityRelationView):
   133         '''display project's screenshots'''
   142         '''display project's screenshots'''
   134         id = title = _('projectscreenshots')
   143         id = title = _('projectscreenshots')
   135         __select__ = implements('Project')
   144         accepts = ('Project',)
   136         rtype = 'screenshot'
   145         rtype = 'screenshot'
   137         target = 'object'
   146         target = 'object'
       
   147         vid = 'gallery'
       
   148         __selectors__ = EntityRelationView.__selectors__ + (one_line_rset,)
       
   149 
       
   150 
       
   151     This is the view we want to have in a tab, only if there is something to show.
       
   152     Then, just define as below, and declare this being the tab content :
       
   153 
       
   154     class ProjectScreenshotTab(EntityRelatedTab, ProjectScreenshotsView):
       
   155         id = 'screenshots_tab'
   138     """
   156     """
   139     __select__ = EntityView.__select__ & partial_has_related_entities()
   157     __select__ = EntityView.__select__ & partial_has_related_entities()
   140     vid = 'list'
   158     vid = 'list'
   141     
   159     
   142     def cell_call(self, row, col):
   160     def cell_call(self, row, col):
   143         rset = self.rset.get_entity(row, col).related(self.rtype, role(self))
   161         rset = self.entity(row, col).related(self.rtype, role(self))
   144         self.w(u'<h1>%s</h1>' % self.req._(self.title).capitalize())
       
   145         self.w(u'<div class="mainInfo">')
   162         self.w(u'<div class="mainInfo">')
   146         self.wview(self.vid, rset, 'noresult')
   163         self.wview(self.vid, rset, 'noresult')
   147         self.w(u'</div>')
   164         self.w(u'</div>')