[gen] Fixed some problems with groups having style='tabs'.

This commit is contained in:
Gaetan Delannay 2014-04-30 15:10:11 +02:00
parent 7adbc7e4bc
commit 4d78996938
6 changed files with 54 additions and 35 deletions

View file

@ -75,15 +75,15 @@ class Field:
layoutTarget=field">:tool.pxLayoutedObject</x>''')
# Displays a field label.
pxLabel = Px('''<label if="field.hasLabel and (field.type != 'Action')"
lfor=":field.name">::zobj.translate('label', field=field)</label>''')
pxLabel = Px('''<label if="field.hasLabel and field.renderLabel"
lfor=":field.name">::_('label', field=field)</label>''')
# Displays a field description.
pxDescription = Px('''<span if="field.hasDescr"
class="discreet">::zobj.translate('descr', field=field)</span>''')
class="discreet">::_('descr', field=field)</span>''')
# Displays a field help.
pxHelp = Px('''<acronym title=":zobj.translate('help', field=field)"><img
pxHelp = Px('''<acronym title=":_('help', field=field)"><img
src=":url('help')"/></acronym>''')
# Displays validation-error-related info about a field.
@ -424,6 +424,13 @@ class Field:
layouts[layoutType].removeElement('r')
# Derive some boolean values from the layouts.
self.hasLabel = self.hasLayoutElement('l', layouts)
# "renderLabel" indicates if the existing label (if hasLabel is True)
# must be rendered by pxLabel. For example, if field is an action, the
# label will be rendered within the button, not by pxLabel.
self.renderLabel = self.hasLabel
# If field is within a group rendered like a tab, the label will already
# be rendered in the corresponding tab.
if self.group and (self.group.style == 'tabs'): self.renderLabel = False
self.hasDescr = self.hasLayoutElement('d', layouts)
self.hasHelp = self.hasLayoutElement('h', layouts)
return layouts

View file

@ -74,6 +74,7 @@ class Action(Field):
master, masterValue, focus, historized, mapping, label,
None, None, None, None, False)
self.validable = False
self.renderLabel = False # Label is rendered directly within the button.
def getDefaultLayouts(self): return {'view': 'l-f', 'edit': 'lrv-f'}

View file

@ -81,8 +81,7 @@ class Group:
self.hasLabel = self.hasDescr = self.hasHelp = False
# The rendering is forced to a single column
self.columns = self.columns[:1]
# Header labels will be used as labels for the tabs.
self.hasHeaders = True
# Inner field/group labels will be used as tab labels.
self.css_class = css_class
self.master = master
self.masterValue = gutils.initMasterValue(masterValue)
@ -194,7 +193,7 @@ class UiGroup:
pxHelp = Px('''<acronym title="obj.translate('help', field=field)"><img
src=":url('help')"/></acronym>''')
# PX that renders the content of a group (which is refered as var "field").
# PX that renders the content of a group (which is referred as var "field").
pxContent = Px('''
<table var="cellgap=field.cellgap" width=":field.wide"
align=":ztool.flipLanguageDirection(field.align, dir)"
@ -253,20 +252,20 @@ class UiGroup:
<x if="field.style not in ('fieldset', 'tabs')">:field.pxContent</x>
<!-- Render the group as tabs if required -->
<x if="field.style == 'tabs'" var2="lenFields=len(field.elements)">
<x if="field.style == 'tabs'" var2="tabsCount=len(field.elements)">
<table width=":field.wide" class=":groupCss" id=":tagId" name=":tagName">
<!-- First row: the tabs. -->
<tr valign="middle"><td style="border-bottom: 1px solid #ff8040">
<table class="tabs" cellpadding="0" cellspacing="0">
<tr valign="middle">
<x for="row in field.elements"
var2="nb = loop.row.nb + 1;
suffix='%s_%d_%d' % (field.name, nb, lenFields);
<x for="sub in field.elements"
var2="nb = loop.sub.nb + 1;
suffix='%s_%d_%d' % (field.name, nb, tabsCount);
tabId='tab_%s' % suffix">
<td><img src=":url('tabLeft')" id=":'%s_left' % tabId"/></td>
<td style=":url('tabBg', bg=True)" class="tab" id=":tabId">
<a onclick=":'showTab(%s)' % q(suffix)"
class="clickable">:_('%s_col%d' % (field.labelId, nb))</a>
class="clickable">:_(sub.labelId)</a>
</td>
<td><img id=":'%s_right' % tabId" src=":url('tabRight')"/></td>
</x>
@ -275,18 +274,18 @@ class UiGroup:
</td></tr>
<!-- Other rows: the fields -->
<tr for="row in field.elements"
var2="nb=loop.row.nb + 1"
id=":'tabcontent_%s_%d_%d' % (field.name, nb, lenFields)"
<tr for="sub in field.elements"
var2="nb=loop.sub.nb + 1"
id=":'tabcontent_%s_%d_%d' % (field.name, nb, tabsCount)"
style=":(nb == 1) and 'display:table-row' or 'display:none'">
<td var="field=row[0]">
<td var="field=sub">
<x if="field.type == 'group'">:field.pxView</x>
<x if="field.type != 'group'">:field.pxRender</x>
</td>
</tr>
</table>
<script type="text/javascript">:'initTab(%s,%s)' % \
(q('tab_%s' % field.name), q('%s_1_%d' % (field.name, lenFields)))
(q('tab_%s' % field.name), q('%s_1_%d' % (field.name, tabsCount)))
</script>
</x>
</x>''')
@ -365,16 +364,24 @@ class UiGroup:
self.helpId = self.labelId + '_help'
# The name of the page where the group lies
self.page = page.name
# The elements contained in the group, that the current user may see.
# They will be stored by m_addElement below as a list of lists because
# they will be rendered as a table.
# The elements (fields or sub-groups) contained in the group, that the
# current user may see. They will be inserted by m_addElement below.
if self.style != 'tabs':
# In most cases, "elements" will be a list of lists for rendering
# them as a table.
self.elements = [[]]
else:
# If the group is a tab, elements will be stored as a simple list.
self.elements = []
# PX to use for rendering this group.
self.px = self.pxByContent[content]
def addElement(self, element):
'''Adds p_element into self.elements. We try first to add p_element into
the last row. If it is not possible, we create a new row.'''
if self.style == 'tabs':
self.elements.append(element)
return
# Get the last row
lastRow = self.elements[-1]
numberOfColumns = len(self.columnsWidths)

View file

@ -47,8 +47,7 @@ img { border: 0; vertical-align: middle }
/* Styles that apply when viewing content of XHTML fields, that mimic styles
that ckeditor uses for displaying XHTML content in the edit view. */
.xhtml { margin-top: 5px; background-color: white;
padding: 6px; border: 1px dashed grey; border-radius: 0.3em }
.xhtml { background-color: white; padding: 6px; font-size: 95% }
.xhtml img { margin-right: 5px }
.xhtml p { margin: 3px 0 7px 0 }
.clickable { cursor: pointer }
@ -156,7 +155,7 @@ td.search { padding-top: 8px }
.homeTable th { padding-top: 5px; font-size: 105% }
.first { margin-top: 0px }
.error { margin: 5px }
.podName { font-size: 90% }
.podName { font-size: 95% }
.podTable { margin-left: 15px }
.cbCell { width: 10px; text-align: center}
.tabs { position:relative; bottom:-2px }

View file

@ -811,10 +811,16 @@ function showTab(tabId) {
}
// Function that initializes the state of a tab
function initTab(cookieId, defaultValue) {
var toSelect = readCookie(cookieId);
if (!toSelect) { showTab(defaultValue) }
else { showTab(toSelect); }
function initTab(tabsId, defaultValue) {
var selectedTabId = readCookie(tabsId);
if (!selectedTabId) { showTab(defaultValue) }
else {
/* Ensure the selected tab exists (it could be absent because of field
visibility settings) */
var selectedTab = document.getElementById('tab_' + selectedTabId);
if (selectedTab) { showTab(selectedTabId) }
else { showTab(defaultValue) }
}
}
// List-related Javascript functions

View file

@ -457,6 +457,12 @@ class AbstractWrapper(object):
isEdit=layoutType == 'edit';
pageInfo=phaseObj.pagesInfo[page]">
<tr valign="top">
<!-- Refresh -->
<td if="zobj.isDebug()">
<a href=":zobj.getUrl(mode=layoutType, page=page, refresh='yes')">
<img title="Refresh" style="vertical-align:top" src=":url('refresh')"/>
</a>
</td>
<!-- Previous -->
<td if="previousPage and pageInfo.showPrevious"
var2="label=_('page_previous');
@ -536,13 +542,6 @@ class AbstractWrapper(object):
<!-- Workflow transitions -->
<td var="targetObj=zobj; buttonsMode='normal'"
if="targetObj.showTransitions(layoutType)">:obj.pxTransitions</td>
<!-- Refresh -->
<td if="zobj.isDebug()">
<a href=":zobj.getUrl(mode=layoutType, page=page, refresh='yes')">
<img title="Refresh" style="vertical-align:top" src=":url('refresh')"/>
</a>
</td>
</tr>
</table>''')