diff --git a/fields/__init__.py b/fields/__init__.py
index ef29f94..5c281c4 100644
--- a/fields/__init__.py
+++ b/fields/__init__.py
@@ -75,15 +75,15 @@ class Field:
layoutTarget=field">:tool.pxLayoutedObject''')
# Displays a field label.
- pxLabel = Px('''''')
+ pxLabel = Px('''''')
# Displays a field description.
pxDescription = Px('''::zobj.translate('descr', field=field)''')
+ class="discreet">::_('descr', field=field)''')
# Displays a field help.
- pxHelp = Px('''''')
# 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
diff --git a/fields/action.py b/fields/action.py
index c1db238..7614f27 100644
--- a/fields/action.py
+++ b/fields/action.py
@@ -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'}
diff --git a/fields/group.py b/fields/group.py
index 42a6854..36360ba 100644
--- a/fields/group.py
+++ b/fields/group.py
@@ -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('''''')
- # 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('''
''')
@@ -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.
- self.elements = [[]]
+ # 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)
diff --git a/gen/ui/appy.css b/gen/ui/appy.css
index d26244b..218340f 100644
--- a/gen/ui/appy.css
+++ b/gen/ui/appy.css
@@ -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 }
diff --git a/gen/ui/appy.js b/gen/ui/appy.js
index 9031f3b..cd16a2d 100644
--- a/gen/ui/appy.js
+++ b/gen/ui/appy.js
@@ -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
diff --git a/gen/wrappers/__init__.py b/gen/wrappers/__init__.py
index 780078c..ebd5075 100644
--- a/gen/wrappers/__init__.py
+++ b/gen/wrappers/__init__.py
@@ -457,6 +457,12 @@ class AbstractWrapper(object):
isEdit=layoutType == 'edit';
pageInfo=phaseObj.pagesInfo[page]">