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(''' :field.pxContent - +
+ + - - -
- @@ -275,18 +274,18 @@ class UiGroup: - -
:_('%s_col%d' % (field.labelId, nb)) + class="clickable">:_(sub.labelId)
+ :field.pxView :field.pxRender
''') @@ -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]">
+ + + + :obj.pxTransitions - - - -
''')