[gen] Added parameter Ref.collapsible allowing to show/hide (via a cookie in the UI, similar to object history) available or tied items.
This commit is contained in:
parent
73f81d9304
commit
fcf6a52974
|
@ -289,32 +289,25 @@ class UiGroup:
|
||||||
</x>
|
</x>
|
||||||
</x>''')
|
</x>''')
|
||||||
|
|
||||||
# PX that renders a group of searches.
|
# PX that renders a group of searches
|
||||||
pxViewSearches = Px('''
|
pxViewSearches = Px('''
|
||||||
<x var="expanded=req.get(field.labelId, 'collapsed') == 'expanded'">
|
<x var="collapse=field.getCollapseInfo(field.labelId, req)">
|
||||||
<!-- Group name, prefixed by the expand/collapse icon -->
|
<!-- Group name, prefixed by the expand/collapse icon -->
|
||||||
<div class="portletGroup">
|
<div class="portletGroup"><x>:collapse.px</x>
|
||||||
<img class="clickable" style="margin-right: 3px" align=":dleft"
|
|
||||||
id=":'%s_img' % field.labelId"
|
|
||||||
src=":expanded and url('collapse.gif') or url('expand.gif')"
|
|
||||||
onclick=":'toggleCookie(%s)' % q(field.labelId)"/>
|
|
||||||
<x if="not field.translated">:_(field.labelId)</x>
|
<x if="not field.translated">:_(field.labelId)</x>
|
||||||
<x if="field.translated">:field.translated</x>
|
<x if="field.translated">:field.translated</x>
|
||||||
</div>
|
</div>
|
||||||
<!-- Group content -->
|
<!-- Group content -->
|
||||||
<div var="display=expanded and 'display:block' or 'display:none'"
|
<div id=":collapse.id" style=":'padding-left: 10px; %s' % collapse.style">
|
||||||
id=":field.labelId" style=":'padding-left: 10px; %s' % display">
|
|
||||||
<x for="searches in field.elements">
|
<x for="searches in field.elements">
|
||||||
<x for="elem in searches">
|
<x for="elem in searches">
|
||||||
<!-- An inner group within this group -->
|
<!-- An inner group within this group -->
|
||||||
<x if="elem.type == 'group'"
|
<x if="elem.type== 'group'" var2="field=elem">:field.pxViewSearches</x>
|
||||||
var2="field=elem">:field.pxViewSearches</x>
|
|
||||||
<!-- A search -->
|
<!-- A search -->
|
||||||
<x if="elem.type != 'group'" var2="search=elem">:search.pxView</x>
|
<x if="elem.type!= 'group'" var2="search=elem">:search.pxView</x>
|
||||||
</x>
|
</x>
|
||||||
</x>
|
</x>
|
||||||
</div>
|
</div></x>''')
|
||||||
</x>''')
|
|
||||||
|
|
||||||
# PX that renders a group of transitions.
|
# PX that renders a group of transitions.
|
||||||
pxViewTransitions = Px('''
|
pxViewTransitions = Px('''
|
||||||
|
@ -349,7 +342,7 @@ class UiGroup:
|
||||||
self.group = group
|
self.group = group
|
||||||
self.columnsWidths = [col.width for col in group.columns]
|
self.columnsWidths = [col.width for col in group.columns]
|
||||||
self.columnsAligns = [col.align for col in group.columns]
|
self.columnsAligns = [col.align for col in group.columns]
|
||||||
# Names of i18n labels for this group.
|
# Names of i18n labels for this group
|
||||||
labelName = self.name
|
labelName = self.name
|
||||||
prefix = className
|
prefix = className
|
||||||
if group.label:
|
if group.label:
|
||||||
|
@ -397,4 +390,9 @@ class UiGroup:
|
||||||
for i in range(freeColumns): lastRow.append('')
|
for i in range(freeColumns): lastRow.append('')
|
||||||
# Create a new row
|
# Create a new row
|
||||||
self.elements.append([element])
|
self.elements.append([element])
|
||||||
|
|
||||||
|
def getCollapseInfo(self, id, request):
|
||||||
|
'''Returns a Collapsible instance, that determines if this group,
|
||||||
|
represented as an expandable menu item, is collapsed or expanded.'''
|
||||||
|
return gutils.Collapsible(id, request)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -226,15 +226,10 @@ class Ref(Field):
|
||||||
</div>
|
</div>
|
||||||
</div>''')
|
</div>''')
|
||||||
|
|
||||||
pxToggleIcon = Px('''
|
|
||||||
<img class="clickable" onclick="toggleCookie('appyHistory')"
|
|
||||||
src=":True and url('collapse.gif') or url('expand.gif')"
|
|
||||||
align=":dleft" id="appyHistory_img" style="padding-right:4px"/>''')
|
|
||||||
|
|
||||||
# PX that displays referred objects as a list
|
# PX that displays referred objects as a list
|
||||||
pxViewList = Px('''
|
pxViewList = Px('''
|
||||||
<div if="not innerRef or mayAdd or mayLink" style="margin-bottom: 4px">
|
<div if="not innerRef or mayAdd or mayLink" style="margin-bottom: 4px">
|
||||||
<x if="field.collapsible">:field.pxToggleIcon</x>
|
<x if="field.collapsible and objects">:collapse.px</x>
|
||||||
<span if="subLabel" class="discreet">:_(subLabel)</span>
|
<span if="subLabel" class="discreet">:_(subLabel)</span>
|
||||||
(<span class="discreet">:totalNumber</span>)
|
(<span class="discreet">:totalNumber</span>)
|
||||||
<x>:field.pxAdd</x>
|
<x>:field.pxAdd</x>
|
||||||
|
@ -258,7 +253,8 @@ class Ref(Field):
|
||||||
if="not objects and (innerRef and mayAdd)">:_('no_ref')</p>
|
if="not objects and (innerRef and mayAdd)">:_('no_ref')</p>
|
||||||
|
|
||||||
<!-- Linked objects -->
|
<!-- Linked objects -->
|
||||||
<table if="objects" class=":not innerRef and 'list' or ''"
|
<table if="objects" id=":collapse.id" style=":collapse.style"
|
||||||
|
class=":not innerRef and 'list' or ''"
|
||||||
width=":innerRef and '100%' or field.layouts['view'].width"
|
width=":innerRef and '100%' or field.layouts['view'].width"
|
||||||
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
|
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
|
||||||
field.getAttribute(obj, 'shownInfo'), dir)">
|
field.getAttribute(obj, 'shownInfo'), dir)">
|
||||||
|
@ -350,6 +346,7 @@ class Ref(Field):
|
||||||
(totalNumber > 1);
|
(totalNumber > 1);
|
||||||
showSubTitles=showSubTitles|\
|
showSubTitles=showSubTitles|\
|
||||||
req.get('showSubTitles', 'true') == 'true';
|
req.get('showSubTitles', 'true') == 'true';
|
||||||
|
collapse=field.getCollapseInfo(obj, True);
|
||||||
subLabel='selectable_objects'">:field.pxViewList</x>''')
|
subLabel='selectable_objects'">:field.pxViewList</x>''')
|
||||||
|
|
||||||
# PX that displays referred objects as dropdown menus.
|
# PX that displays referred objects as dropdown menus.
|
||||||
|
@ -450,6 +447,7 @@ class Ref(Field):
|
||||||
checkboxesEnabled=field.getAttribute(zobj, 'checkboxes') and \
|
checkboxesEnabled=field.getAttribute(zobj, 'checkboxes') and \
|
||||||
(layoutType != 'cell');
|
(layoutType != 'cell');
|
||||||
checkboxes=checkboxesEnabled and (totalNumber > 1);
|
checkboxes=checkboxesEnabled and (totalNumber > 1);
|
||||||
|
collapse=field.getCollapseInfo(obj, False);
|
||||||
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
|
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
|
||||||
<!-- JS tables storing checkbox statuses if checkboxes are enabled -->
|
<!-- JS tables storing checkbox statuses if checkboxes are enabled -->
|
||||||
<script if="checkboxesEnabled and renderAll and (render == 'list')"
|
<script if="checkboxesEnabled and renderAll and (render == 'list')"
|
||||||
|
@ -1495,6 +1493,16 @@ class Ref(Field):
|
||||||
tiedUrl = tied.getUrl(nav=self.getNavInfo(obj, number+1, len(uids)))
|
tiedUrl = tied.getUrl(nav=self.getNavInfo(obj, number+1, len(uids)))
|
||||||
return obj.goto(tiedUrl)
|
return obj.goto(tiedUrl)
|
||||||
|
|
||||||
|
def getCollapseInfo(self, obj, inPickList):
|
||||||
|
'''Returns a Collapsible instance, that determines if the "tied objects"
|
||||||
|
or "available objects" zone (depending on p_inPickList) is collapsed
|
||||||
|
or expanded.'''
|
||||||
|
# Create the ID of the collapsible zone.
|
||||||
|
suffix = inPickList and 'poss' or 'objs'
|
||||||
|
id = '%s_%s_%s' % (obj.klass.__name__, self.name, suffix)
|
||||||
|
return gutils.Collapsible(id, obj.request, default='expanded',
|
||||||
|
display='table')
|
||||||
|
|
||||||
def autoref(klass, field):
|
def autoref(klass, field):
|
||||||
'''klass.field is a Ref to p_klass. This kind of auto-reference can't be
|
'''klass.field is a Ref to p_klass. This kind of auto-reference can't be
|
||||||
declared in the "normal" way, like this:
|
declared in the "normal" way, like this:
|
||||||
|
|
|
@ -1240,6 +1240,11 @@ class BaseMixin:
|
||||||
res.append(event)
|
res.append(event)
|
||||||
return Object(events=res, totalNumber=len(history))
|
return Object(events=res, totalNumber=len(history))
|
||||||
|
|
||||||
|
def getHistoryCollapse(self):
|
||||||
|
'''Gets a Collapsible instance for showing a collapse or expanded
|
||||||
|
history in this object.'''
|
||||||
|
return Collapsible('appyHistory', self.REQUEST)
|
||||||
|
|
||||||
def mayNavigate(self):
|
def mayNavigate(self):
|
||||||
'''May the currently logged user see the navigation panel linked to
|
'''May the currently logged user see the navigation panel linked to
|
||||||
this object?'''
|
this object?'''
|
||||||
|
|
|
@ -673,13 +673,13 @@ function readCookie(name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleCookie(cookieId) {
|
function toggleCookie(cookieId, display, defaultValue) {
|
||||||
// What is the state of this boolean (expanded/collapsed) cookie?
|
// What is the state of this boolean (expanded/collapsed) cookie?
|
||||||
var state = readCookie(cookieId);
|
var state = readCookie(cookieId);
|
||||||
if ((state != 'collapsed') && (state != 'expanded')) {
|
if ((state != 'collapsed') && (state != 'expanded')) {
|
||||||
// No cookie yet, create it.
|
// No cookie yet, create it
|
||||||
createCookie(cookieId, 'collapsed');
|
createCookie(cookieId, defaultValue);
|
||||||
state = 'collapsed';
|
state = defaultValue;
|
||||||
}
|
}
|
||||||
var hook = document.getElementById(cookieId); // The hook is the part of
|
var hook = document.getElementById(cookieId); // The hook is the part of
|
||||||
// the HTML document that needs to be shown or hidden.
|
// the HTML document that needs to be shown or hidden.
|
||||||
|
@ -688,7 +688,7 @@ function toggleCookie(cookieId) {
|
||||||
var imgSrc = 'ui/expand.gif';
|
var imgSrc = 'ui/expand.gif';
|
||||||
if (state == 'collapsed') {
|
if (state == 'collapsed') {
|
||||||
// Show the HTML zone
|
// Show the HTML zone
|
||||||
displayValue = 'block';
|
displayValue = display;
|
||||||
imgSrc = 'ui/collapse.gif';
|
imgSrc = 'ui/collapse.gif';
|
||||||
newState = 'expanded';
|
newState = 'expanded';
|
||||||
}
|
}
|
||||||
|
|
27
gen/utils.py
27
gen/utils.py
|
@ -1,5 +1,6 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import re, os, os.path, base64, urllib
|
import re, os, os.path, base64, urllib
|
||||||
|
from appy.px import Px
|
||||||
from appy.shared import utils as sutils
|
from appy.shared import utils as sutils
|
||||||
|
|
||||||
# Function for creating a Zope object ------------------------------------------
|
# Function for creating a Zope object ------------------------------------------
|
||||||
|
@ -251,5 +252,29 @@ class Tool(Model):
|
||||||
'''Subclass me to extend or modify the Tool class.'''
|
'''Subclass me to extend or modify the Tool class.'''
|
||||||
class User(Model):
|
class User(Model):
|
||||||
'''Subclass me to extend or modify the User class.'''
|
'''Subclass me to extend or modify the User class.'''
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
class Collapsible:
|
||||||
|
'''Represents a chunk of HTML code that can be collapsed/expanded via a
|
||||||
|
plus/minus icon.'''
|
||||||
|
|
||||||
|
# Plus/minus icon allowing to collapse/expand a chunk of HTML
|
||||||
|
px = Px('''
|
||||||
|
<img id=":'%s_img' % collapse.id" class="clickable" align=":dleft"
|
||||||
|
onclick=":'toggleCookie(%s,%s,%s)' % \
|
||||||
|
(q(collapse.id), q(collapse.display), q(collapse.default))"
|
||||||
|
src=":collapse.expanded and url('collapse.gif') or url('expand.gif')"
|
||||||
|
style="padding-right:4px"/>''')
|
||||||
|
|
||||||
|
def __init__(self, id, request, default='collapsed', display='block'):
|
||||||
|
'''p_display is the value of style attribute "display" for the XHTML
|
||||||
|
element when it must be displayed. By default it is "block"; for a
|
||||||
|
table it must be "table", etc.'''
|
||||||
|
self.id = id # The ID of the collapsible HTML element
|
||||||
|
self.request = request # The request object
|
||||||
|
self.default = default
|
||||||
|
self.display = display
|
||||||
|
# Must the element be collapsed or expanded ?
|
||||||
|
self.expanded = request.get(id, default) == 'expanded'
|
||||||
|
self.style = 'display:%s' % (self.expanded and self.display or 'none')
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -397,16 +397,13 @@ class AbstractWrapper(object):
|
||||||
<div if="not zobj.isTemporary()"
|
<div if="not zobj.isTemporary()"
|
||||||
var2="hasHistory=zobj.hasHistory();
|
var2="hasHistory=zobj.hasHistory();
|
||||||
historyMaxPerPage=req.get('maxPerPage', 5);
|
historyMaxPerPage=req.get('maxPerPage', 5);
|
||||||
historyExpanded=req.get('appyHistory','collapsed')=='expanded';
|
collapse=zobj.getHistoryCollapse();
|
||||||
creator=zobj.Creator()">
|
creator=zobj.Creator()">
|
||||||
<table width="100%" class="summary" cellpadding="0" cellspacing="0">
|
<table width="100%" class="summary" cellpadding="0" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="by">
|
<td colspan="2" class="by">
|
||||||
<!-- Plus/minus icon for accessing history -->
|
<!-- Plus/minus icon for accessing history -->
|
||||||
<x if="hasHistory">
|
<x if="hasHistory"><x>:collapse.px</x>
|
||||||
<img class="clickable" onclick="toggleCookie('appyHistory')"
|
|
||||||
src=":historyExpanded and url('collapse.gif') or url('expand.gif')"
|
|
||||||
align=":dleft" id="appyHistory_img" style="padding-right:4px"/>
|
|
||||||
<x>:_('object_history')</x> —
|
<x>:_('object_history')</x> —
|
||||||
</x>
|
</x>
|
||||||
|
|
||||||
|
@ -434,8 +431,7 @@ class AbstractWrapper(object):
|
||||||
<!-- Object history -->
|
<!-- Object history -->
|
||||||
<tr if="hasHistory">
|
<tr if="hasHistory">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<span id="appyHistory"
|
<span id=":collapse.id" style=":collapse.style">
|
||||||
style=":historyExpanded and 'display:block' or 'display:none'">
|
|
||||||
<div var="ajaxHookId=zobj.id + '_history'" id=":ajaxHookId">
|
<div var="ajaxHookId=zobj.id + '_history'" id=":ajaxHookId">
|
||||||
<script type="text/javascript">::'askObjectHistory(%s,%s,%d,0)' % \
|
<script type="text/javascript">::'askObjectHistory(%s,%s,%d,0)' % \
|
||||||
(q(ajaxHookId), q(zobj.absolute_url()), \
|
(q(ajaxHookId), q(zobj.absolute_url()), \
|
||||||
|
|
Loading…
Reference in a new issue