appy.gen: reimplemented master/slave-related Javascript code without Plone queryCss.
This commit is contained in:
parent
c9353b46db
commit
e821307b4c
|
@ -22,6 +22,13 @@ validatorTypes = (types.FunctionType, types.UnboundMethodType,
|
|||
emptyTuple = ()
|
||||
labelTypes = ('label', 'descr', 'help')
|
||||
|
||||
def initMasterValue(v):
|
||||
'''Standardizes p_v as a list.'''
|
||||
if not v: res = []
|
||||
elif type(v) not in sequenceTypes: res = [v]
|
||||
else: res = v
|
||||
return res
|
||||
|
||||
# Descriptor classes used for refining descriptions of elements in types
|
||||
# (pages, groups,...) ----------------------------------------------------------
|
||||
class Page:
|
||||
|
@ -153,26 +160,10 @@ class Group:
|
|||
# Header labels will be used as labels for the tabs.
|
||||
self.hasHeaders = True
|
||||
self.css_class = css_class
|
||||
self.master = None
|
||||
self.masterValue = None
|
||||
if master:
|
||||
self._addMaster(master, masterValue)
|
||||
self.label = label # See similar attr of Type class.
|
||||
|
||||
def _addMaster(self, master, masterValue):
|
||||
'''Specifies this group being a slave of another field: we will add css
|
||||
classes allowing to show/hide, in Javascript, its widget according
|
||||
to master value.'''
|
||||
self.master = master
|
||||
self.masterValue = masterValue
|
||||
classes = 'slave_%s' % self.master.id
|
||||
if type(self.masterValue) not in sequenceTypes:
|
||||
masterValues = [self.masterValue]
|
||||
else:
|
||||
masterValues = self.masterValue
|
||||
for masterValue in masterValues:
|
||||
classes += ' slaveValue_%s_%s' % (self.master.id, masterValue)
|
||||
self.css_class += ' ' + classes
|
||||
self.masterValue = initMasterValue(masterValue)
|
||||
if master: master.slaves.append(self)
|
||||
self.label = label # See similar attr of Type class.
|
||||
|
||||
def _setColumns(self):
|
||||
'''Standardizes field "columns" as a list of Column instances. Indeed,
|
||||
|
@ -440,17 +431,14 @@ class Type:
|
|||
# If the widget is in a group with multiple columns, the following
|
||||
# attribute specifies on how many columns to span the widget.
|
||||
self.colspan = colspan
|
||||
# The list of slaves of this field, if it is a master
|
||||
self.slaves = []
|
||||
# The behaviour of this field may depend on another, "master" field
|
||||
self.master = master
|
||||
self.slaves = [] # The list of slaves of this field, if it is a master
|
||||
# Every HTML input field corresponding to a master must get some
|
||||
# CSS classes for controlling its slaves.
|
||||
self.master_css = ''
|
||||
if master:
|
||||
self.master.slaves.append(self)
|
||||
self.master.master_css = 'appyMaster master_%s' % self.master.id
|
||||
# When master has some value(s), there is impact on this field.
|
||||
self.masterValue = masterValue
|
||||
self.masterValue = initMasterValue(masterValue)
|
||||
# If a field must retain attention in a particular way, set focus=True.
|
||||
# It will be rendered in a special way.
|
||||
self.focus = focus
|
||||
|
@ -494,7 +482,8 @@ class Type:
|
|||
# Recompute the ID (and derived attributes) that may have changed if
|
||||
# we are in debug mode (because we recreate new Type instances).
|
||||
self.id = id(self)
|
||||
if self.slaves: self.master_css = 'appyMaster master_%s' % self.id
|
||||
# Remember master name on every slave
|
||||
for slave in self.slaves: slave.masterName = name
|
||||
# Determine ids of i18n labels for this field
|
||||
labelName = name
|
||||
trPrefix = None
|
||||
|
@ -591,13 +580,10 @@ class Type:
|
|||
master, masterValue = masterData
|
||||
reqValue = master.getRequestValue(obj.REQUEST)
|
||||
reqValue = master.getStorableValue(reqValue)
|
||||
# Manage the fact that values can be lists or single values
|
||||
multiMaster = type(masterValue) in sequenceTypes
|
||||
multiReq = type(reqValue) in sequenceTypes
|
||||
if not multiMaster and not multiReq: return reqValue == masterValue
|
||||
elif multiMaster and not multiReq: return reqValue in masterValue
|
||||
elif not multiMaster and multiReq: return masterValue in reqValue
|
||||
else: # multiMaster and multiReq
|
||||
# reqValue can be a list or not
|
||||
if type(reqValue) not in sequenceTypes:
|
||||
return reqValue in masterValue
|
||||
else:
|
||||
for m in masterValue:
|
||||
for r in reqValue:
|
||||
if m == r: return True
|
||||
|
@ -674,19 +660,6 @@ class Type:
|
|||
layouts['cell'] = Table(other=layouts['view'], derivedType='cell')
|
||||
# Put the required CSS classes in the layouts
|
||||
layouts['cell'].addCssClasses('noStyle')
|
||||
if self.master:
|
||||
# This type has a master (so is a slave): we add css classes
|
||||
# allowing to show/hide, in Javascript, its widget according to
|
||||
# master value.
|
||||
classes = 'slave_%s' % self.master.id
|
||||
if type(self.masterValue) not in sequenceTypes:
|
||||
masterValues = [self.masterValue]
|
||||
else:
|
||||
masterValues = self.masterValue
|
||||
for masterValue in masterValues:
|
||||
classes += ' slaveValue_%s_%s' % (self.master.id, masterValue)
|
||||
layouts['view'].addCssClasses(classes)
|
||||
layouts['edit'].addCssClasses(classes)
|
||||
if self.focus:
|
||||
# We need to make it flashy
|
||||
layouts['view'].addCssClasses('appyFocus')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import re, os, os.path, time, Cookie, types
|
||||
import re, os, os.path, time, types
|
||||
from appy.shared import mimeTypes
|
||||
from appy.shared.utils import getOsTempFolder
|
||||
import appy.gen
|
||||
|
@ -84,7 +84,6 @@ class ToolMixin(BaseMixin):
|
|||
'''Returns the (translated) names of fields of p_contentType.'''
|
||||
res = []
|
||||
for appyType in self.getAllAppyTypes(className=contentType):
|
||||
if appyType.name == 'title': continue # Will be included by default.
|
||||
res.append((appyType.name, self.translate(appyType.labelId)))
|
||||
# Add object state
|
||||
res.append(('state', self.translate('workflow_state')))
|
||||
|
@ -611,13 +610,6 @@ class ToolMixin(BaseMixin):
|
|||
res.append(dSearch)
|
||||
return res
|
||||
|
||||
def getCookieValue(self, cookieId, default=''):
|
||||
'''Server-side code for getting the value of a cookie entry.'''
|
||||
cookie = Cookie.SimpleCookie(self.REQUEST['HTTP_COOKIE'])
|
||||
cookieValue = cookie.get(cookieId)
|
||||
if cookieValue: return cookieValue.value
|
||||
return default
|
||||
|
||||
def getQueryUrl(self, contentType, searchName, startNumber=None):
|
||||
'''This method creates the URL that allows to perform a (non-Ajax)
|
||||
request for getting queried objects from a search named p_searchName
|
||||
|
|
|
@ -14,9 +14,9 @@ class Protos:
|
|||
protos = {}
|
||||
# List of attributes that can't be given to a Type constructor
|
||||
notInit = ('id', 'type', 'pythonType', 'slaves', 'isSelect', 'hasLabel',
|
||||
'hasDescr', 'hasHelp', 'master_css', 'required', 'filterable',
|
||||
'validable', 'backd', 'isBack', 'sync', 'pageName',
|
||||
'shownInfoWidths')
|
||||
'hasDescr', 'hasHelp', 'required', 'filterable', 'validable',
|
||||
'backd', 'isBack', 'sync', 'pageName', 'shownInfoWidths',
|
||||
'masterName')
|
||||
@classmethod
|
||||
def get(self, appyType):
|
||||
'''Returns a prototype instance for p_appyType.'''
|
||||
|
|
|
@ -8,18 +8,26 @@ table { font-size: 100%; border-spacing: 0px; border-collapse:collapse;}
|
|||
form { margin: 0; padding: 0;}
|
||||
p { margin: 0;}
|
||||
acronym {cursor: help;}
|
||||
input { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
font-family: Lucida,Helvetica,Arial,sans-serif; margin-bottom: 1px}
|
||||
input[type=image] { border-width: 0px; background: none; }
|
||||
input[type=button] { cursor: pointer; }
|
||||
input[type=image] { border: 0; background: none; }
|
||||
input[type=checkbox] { border: 0; background: none; cursor: pointer;}
|
||||
input[type=button] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
cursor: pointer;}
|
||||
input[type=submit] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
cursor: pointer; }
|
||||
input[type=text] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
font-family: Lucida,Helvetica,Arial,sans-serif;
|
||||
margin-bottom: 1px}
|
||||
select { border: 1px solid #cccccc; background-color: #f8f8f8;}
|
||||
|
||||
textarea { width: 99%; font: 100% Lucida,Helvetica,Arial,sans-serif;
|
||||
border: 1px solid #a79e9e; background-color: #f8f8f8;}
|
||||
label { font-weight: 600; font-style: italic; line-height: 1.4em;}
|
||||
legend { padding-bottom: 2px; padding-right: 3px;}
|
||||
legend { padding-bottom: 2px; padding-right: 3px; color: black;}
|
||||
ul { line-height: 1.2em; margin: 0 0 0.2em 0.6em; padding: 0;
|
||||
list-style: none outside none;}
|
||||
li { margin: 0; background-image: url("skyn/li.gif"); padding-left: 10px;
|
||||
background-repeat: no-repeat; background-position: 0 4px;}
|
||||
img {border: 0;}
|
||||
|
||||
.main { width: 900px; background-color: white; box-shadow: 3px 3px 3px #A9A9A9;
|
||||
border-style: solid; border-width: 1px; border-color: grey; }
|
||||
|
|
|
@ -177,7 +177,7 @@ function askRefField(hookId, objectUrl, fieldName, innerRef, startNumber,
|
|||
action, actionParams){
|
||||
// Sends an Ajax request for getting the content of a reference field.
|
||||
var startKey = hookId + '_startNumber';
|
||||
var params = {'fieldName': fieldName, 'innerRef': innerRef, };
|
||||
var params = {'fieldName': fieldName, 'innerRef': innerRef };
|
||||
params[startKey] = startNumber;
|
||||
if (action) params['action'] = action;
|
||||
if (actionParams) {
|
||||
|
@ -201,70 +201,94 @@ function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
|
|||
}
|
||||
|
||||
// Functions used for master/slave relationships between widgets
|
||||
function getMasterValue(widget) {
|
||||
// Returns an array of selected options in a select widget
|
||||
res = new Array();
|
||||
if (widget.type == 'checkbox') {
|
||||
var mv = widget.checked + '';
|
||||
mv = mv.charAt(0).toUpperCase() + mv.substr(1);
|
||||
res.push(mv);
|
||||
function getSlaveInfo(slave, infoType) {
|
||||
// Returns the appropriate info about slavery, depending on p_infoType.
|
||||
cssClasses = slave.className.split(' ');
|
||||
// Find the CSS class containing master-related info.
|
||||
for (var j=0; j < cssClasses.length; j++) {
|
||||
if (cssClasses[j].indexOf('slave_') == 0) {
|
||||
// Extract, from this CSS class, master name or master values.
|
||||
masterInfo = cssClasses[j].split('_');
|
||||
if (infoType == 'masterName') return masterInfo[1];
|
||||
else return masterInfo.slice(2); // Master values
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMasterValues(master) {
|
||||
// Returns the list of values that p_master currently has.
|
||||
if (master.tagName == 'SPAN') {
|
||||
res = master.attributes['value'].value;
|
||||
if ((res[0] == '(') || (res[0] == '[')) {
|
||||
// There are multiple values, split it
|
||||
values = res.substring(1, res.length-1).split(',');
|
||||
res = [];
|
||||
for (var i=0; i < values.length; i++){
|
||||
v = values[i].replace(' ', '');
|
||||
res.push(v.substring(1, v.length-1));
|
||||
}
|
||||
}
|
||||
else res = [res]; // A single value
|
||||
}
|
||||
else if (master.type == 'checkbox') {
|
||||
res = master.checked + '';
|
||||
res = res.charAt(0).toUpperCase() + res.substr(1);
|
||||
res = [res];
|
||||
}
|
||||
else { // SELECT widget
|
||||
for (var i=0; i < widget.options.length; i++) {
|
||||
if (widget.options[i].selected) res.push(widget.options[i].value);
|
||||
res = [];
|
||||
for (var i=0; i < master.options.length; i++) {
|
||||
if (master.options[i].selected) res.push(master.options[i].value);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function updateSlaves(masterValues, appyTypeId) {
|
||||
// Given the value(s) selected in a master field, this function updates the
|
||||
// state of all corresponding slaves.
|
||||
var slaves = cssQuery('table.slave_' + appyTypeId);
|
||||
for (var i=0; i< slaves.length; i++){
|
||||
slaves[i].style.display = "none";
|
||||
function getSlaves(master) {
|
||||
// Gets all the slaves of master.
|
||||
allSlaves = document.getElementsByName('slave');
|
||||
res = [];
|
||||
slavePrefix = 'slave_' + master.attributes['name'].value + '_';
|
||||
for (var i=0; i < slaves.length; i++){
|
||||
cssClasses = slaves[i].className.split(' ');
|
||||
for (var j=0; j < cssClasses.length; j++) {
|
||||
if (cssClasses[j].indexOf(slavePrefix) == 0) {
|
||||
res.push(slaves[i]);
|
||||
break;
|
||||
}
|
||||
for (var i=0; i < masterValues.length; i++) {
|
||||
var activeSlaves = cssQuery('table.slaveValue_' + appyTypeId + '_' + masterValues[i]);
|
||||
for (var j=0; j < activeSlaves.length; j++){
|
||||
activeSlaves[j].style.display = "";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function updateSlaves(master) {
|
||||
// Given the value(s) in a master field, we must update slave's visibility.
|
||||
slaves = getSlaves(master);
|
||||
masterValues = getMasterValues(master);
|
||||
for (var i=0; i < slaves.length; i++) {
|
||||
showSlave = false;
|
||||
slaveryValues = getSlaveInfo(slaves[i], 'masterValues');
|
||||
for (var j=0; j < slaveryValues.length; j++) {
|
||||
for (var k=0; k< masterValues.length; k++) {
|
||||
if (slaveryValues[j] == masterValues[k]) showSlave = true;
|
||||
}
|
||||
}
|
||||
if (showSlave) slaves[i].style.display = "";
|
||||
else slaves[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function initSlaves() {
|
||||
// When the current page is loaded, we must set the correct state for all
|
||||
// slave fields.
|
||||
var masters = cssQuery('.appyMaster');
|
||||
for (var i=0; i < masters.length; i++) {
|
||||
var cssClasses = masters[i].className.split(' ');
|
||||
for (var j=0; j < cssClasses.length; j++) {
|
||||
if (cssClasses[j].indexOf('master_') == 0) {
|
||||
var appyId = cssClasses[j].split('_')[1];
|
||||
var masterValue = [];
|
||||
if (masters[i].nodeName == 'SPAN'){
|
||||
var idField = masters[i].id;
|
||||
if (idField == '') {
|
||||
masterValue.push(idField);
|
||||
}
|
||||
else {
|
||||
if ((idField[0] == '(') || (idField[0] == '[')) {
|
||||
// There are multiple values, split it
|
||||
var subValues = idField.substring(1, idField.length-1).split(',');
|
||||
for (var k=0; k < subValues.length; k++){
|
||||
var subValue = subValues[k].replace(' ','');
|
||||
masterValue.push(subValue.substring(1, subValue.length-1));
|
||||
}
|
||||
}
|
||||
else { masterValue.push(masters[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { masterValue = getMasterValue(masters[i]);
|
||||
}
|
||||
updateSlaves(masterValue, appyId);
|
||||
}
|
||||
}
|
||||
slaves = document.getElementsByName('slave');
|
||||
walkedMasters = {}; // Remember the already walked masters.
|
||||
for (var i=0; i < slaves.length; i++) {
|
||||
masterName = getSlaveInfo(slaves[i], 'masterName');
|
||||
if (masterName in walkedMasters) continue;
|
||||
master = document.getElementById(masterName);
|
||||
updateSlaves(master);
|
||||
walkedMasters[masterName] = 'walked';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<!--
|
||||
var importedElemsShown = false;
|
||||
function toggleViewableElements() {
|
||||
var rows = cssQuery('#importedElem');
|
||||
var rows = document.getElementsByName('importedElem');
|
||||
var newDisplay = 'table-row';
|
||||
if (isIe) newDisplay = 'block';
|
||||
if (importedElemsShown) newDisplay = 'none';
|
||||
|
@ -33,10 +33,9 @@
|
|||
}
|
||||
importedElemsShown = !importedElemsShown;
|
||||
}
|
||||
|
||||
var checkBoxesChecked = true;
|
||||
function toggleCheckboxes() {
|
||||
var checkBoxes = cssQuery('#cbElem');
|
||||
var checkBoxes = document.getElementsByName('cbElem');
|
||||
var newCheckValue = true;
|
||||
if (checkBoxesChecked) newCheckValue = false;
|
||||
for (var i=0; i<checkBoxes.length; i++) {
|
||||
|
@ -44,18 +43,16 @@
|
|||
}
|
||||
checkBoxesChecked = newCheckValue;
|
||||
}
|
||||
|
||||
function importSingleElement(importPath) {
|
||||
var f = document.forms['importElements'];
|
||||
f.importPath.value = importPath;
|
||||
f.submit();
|
||||
}
|
||||
|
||||
function importManyElements() {
|
||||
var f = document.forms['importElements'];
|
||||
var importPaths = '';
|
||||
// Get the values of the checkboxes
|
||||
var checkBoxes = cssQuery('#cbElem');
|
||||
var checkBoxes = document.getElementsByName('cbElem');
|
||||
for (var i=0; i<checkBoxes.length; i++) {
|
||||
if (checkBoxes[i].checked) {
|
||||
importPaths += checkBoxes[i].value + '|';
|
||||
|
@ -67,7 +64,6 @@
|
|||
f.submit();
|
||||
}
|
||||
}
|
||||
|
||||
-->
|
||||
</script>
|
||||
<tal:comment replace="nothing">Form for importing several meetings at once.</tal:comment>
|
||||
|
@ -98,9 +94,10 @@
|
|||
<tr tal:define="alreadyImported python: tool.isAlreadyImported(contentType, row[0]);
|
||||
global allAreImported python: allAreImported and alreadyImported;
|
||||
odd repeat/row/odd"
|
||||
tal:attributes="id python:test(alreadyImported, 'importedElem', 'notImportedElem');
|
||||
style python:test(alreadyImported, 'display:none', 'display:table-row');
|
||||
class python:test(odd, 'even', 'odd')">
|
||||
tal:attributes="id python: alreadyImported and 'importedElem' or 'notImportedElem';
|
||||
name python: alreadyImported and 'importedElem' or 'notImportedElem';
|
||||
style python: alreadyImported and 'display:none' or 'display:table-row';
|
||||
class python: odd and 'even' or 'odd'">
|
||||
<td tal:repeat="elem python: row[1:]" tal:content="elem">
|
||||
</td>
|
||||
<td>
|
||||
|
@ -109,8 +106,10 @@
|
|||
value python: tool.translate('query_import')"/>
|
||||
<span tal:condition="alreadyImported" tal:replace="python: tool.translate('import_already')"/>
|
||||
</td>
|
||||
<td align="center"><input type="checkbox" checked="checked" class="noborder" id="cbElem"
|
||||
tal:attributes="value python: row[0]" tal:condition="not: alreadyImported"/></td>
|
||||
<td align="center">
|
||||
<input type="checkbox" checked="checked" class="noborder" id="cbElem" name="cbElem"
|
||||
tal:attributes="value python: row[0]" tal:condition="not: alreadyImported"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tal:row>
|
||||
<tr tal:condition="python: not importElems[1] or allAreImported"><td colspan="15" tal:content="python: tool.translate('query_no_result')"></td></tr>
|
||||
|
|
|
@ -187,7 +187,7 @@
|
|||
tal:define="showWorkflow python: tool.getAttr('showWorkflowFor' + contextObj.meta_type);
|
||||
hasHistory contextObj/hasHistory;
|
||||
historyMaxPerPage options/maxPerPage|python: 5;
|
||||
historyExpanded python: tool.getCookieValue('appyHistory', default='collapsed') == 'expanded';
|
||||
historyExpanded python: request.get('appyHistory', 'collapsed') == 'expanded';
|
||||
creator contextObj/Creator"
|
||||
tal:condition="not: contextObj/isTemporary">
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<tal:searchOrGroup repeat="searchOrGroup python: tool.getSearches(rootClass)">
|
||||
<tal:group condition="searchOrGroup/isGroup">
|
||||
<tal:expanded define="group searchOrGroup;
|
||||
expanded python: tool.getCookieValue(group['labelId'], default='collapsed') == 'expanded'">
|
||||
expanded python: request.get(group['labelId'], 'collapsed') == 'expanded'">
|
||||
<tal:comment replace="nothing">Group name</tal:comment>
|
||||
<dt class="portletAppyItem portletGroup">
|
||||
<img align="left" style="cursor:pointer"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<tal:comment replace="nothing">Query result</tal:comment>
|
||||
<div id="queryResult"></div>
|
||||
|
||||
<script language="javascript"
|
||||
<script type="text/javascript"
|
||||
tal:define="ajaxUrl python: tool.getQueryUrl(contentType, searchName)"
|
||||
tal:content="python: 'askQueryResult(\'queryResult\', \'%s\',\'%s\',\'%s\',0)' % (tool.absolute_url(), contentType, searchName)">
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<tal:comment replace="nothing">View macro for a Boolean.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:attributes="class widget/master_css; id rawValue" tal:content="value"></span>
|
||||
<span tal:attributes="class masterCss; value rawValue; name name; id name"
|
||||
tal:content="value"></span>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Boolean.</tal:comment>
|
||||
|
@ -9,8 +10,8 @@
|
|||
tal:attributes="name python: name + '_visible';
|
||||
id name;
|
||||
checked python:contextObj.checkboxChecked(name, rawValue);
|
||||
onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(getMasterValue(this), \'%s\')' % (name, name, widget['id']);
|
||||
class python: 'noborder ' + widget['master_css']"/>
|
||||
onClick python:'toggleCheckbox(\'%s\', \'%s_hidden\');;updateSlaves(this)' % (name, name);
|
||||
class python: 'noborder %s' % masterCss"/>
|
||||
<input tal:attributes="name name;
|
||||
id string:${name}_hidden;
|
||||
value python: test(contextObj.checkboxChecked(name, rawValue), 'True', 'False')"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<tal:comment replace="nothing">View macro for a Float.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:content="value"
|
||||
tal:attributes="id value; class widget/master_css"></span>
|
||||
tal:attributes="value value; class masterCss; name name; id name"></span>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Float.</tal:comment>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<tal:comment replace="nothing">View macro for an Integer.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:content="value" tal:attributes="id value; class widget/master_css"></span>
|
||||
<span tal:content="value"
|
||||
tal:attributes="value value; class masterCss; name name; id name"></span>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Integer.</tal:comment>
|
||||
|
|
|
@ -9,15 +9,23 @@
|
|||
contextMacro The base folder containing the macros to call for
|
||||
rendering the elements within the layout.
|
||||
Defaults to app.skyn
|
||||
slaveId The name and id of the main tag for this layout (used
|
||||
for master/slave relationships).
|
||||
slaveCss The CSS class for a slave.
|
||||
</tal:comment>
|
||||
<metal:show define-macro="layout"
|
||||
tal:define="contextMacro contextMacro| python: app.skyn">
|
||||
tal:define="contextMacro contextMacro| python: app.skyn;
|
||||
slaveId slaveId|python:'';
|
||||
slaveCss slaveCss|python:'';
|
||||
layoutCss layout/css_class;">
|
||||
<table tal:attributes="cellpadding layout/cellpadding;
|
||||
cellspacing layout/cellspacing;
|
||||
width layout/width;
|
||||
align layout/align;
|
||||
class layout/css_class;
|
||||
style layout/style">
|
||||
class python: slaveCss and ('%s %s' % (slaveCss, layoutCss)) or layoutCss;
|
||||
style layout/style;
|
||||
id slaveId;
|
||||
name slaveId;">
|
||||
<tal:comment replace="nothing">The table header row</tal:comment>
|
||||
<tr tal:condition="layout/headerRow" tal:attributes="valign layout/headerRow/valign">
|
||||
<th tal:repeat="cell layout/headerRow/cells"
|
||||
|
@ -52,7 +60,10 @@
|
|||
inRequest python: request.has_key(name);
|
||||
errors errors | python: ();
|
||||
inError python: (widget['name'] in errors) and True or False;
|
||||
isMultiple python: (widget['multiplicity'][1] == None) or (widget['multiplicity'][1] > 1)">
|
||||
isMultiple python: (widget['multiplicity'][1] == None) or (widget['multiplicity'][1] > 1);
|
||||
masterCss python: widget['slaves'] and ('master_%s' % name) or '';
|
||||
slaveCss python: widget['master'] and ('slave_%s_%s' % (widget['masterName'], '_'.join(widget['masterValue']))) or '';
|
||||
slaveId python: widget['master'] and 'slave' or ''">
|
||||
|
||||
<metal:layout use-macro="here/skyn/widgets/show/macros/layout"/>
|
||||
</metal:field>
|
||||
|
@ -65,7 +76,11 @@
|
|||
layoutType "edit"? "view"? "cell?"
|
||||
widget The widget to render
|
||||
</tal:comment>
|
||||
<metal:group define-macro="group">
|
||||
<metal:group define-macro="group"
|
||||
tal:define="slaveCss python: widget['master'] and ('slave_%s_%s' % (widget['masterName'], '_'.join(widget['masterValue']))) or '';
|
||||
widgetCss widget/css_class;
|
||||
groupCss python: slaveCss and ('%s %s' % (slaveCss, widgetCss)) or widgetCss;
|
||||
slaveId python: widget['master'] and 'slave' or ''">
|
||||
<fieldset tal:condition="python: widget['style'] == 'fieldset'">
|
||||
<legend tal:condition="widget/hasLabel">
|
||||
<i tal:content="structure python: contextObj.translate(widget['labelId'])"></i>
|
||||
|
@ -81,9 +96,9 @@
|
|||
<metal:content use-macro="app/skyn/widgets/show/macros/groupContent"/>
|
||||
</tal:asSection>
|
||||
<tal:asTabs condition="python: widget['style'] == 'tabs'">
|
||||
<table cellpadding="0" cellspacing="0"
|
||||
tal:attributes="width widget/wide;
|
||||
class widget/css_class">
|
||||
<table tal:attributes="width widget/wide;
|
||||
class groupCss;
|
||||
id slaveId; name slaveId">
|
||||
<tal:comment replace="nothing">First row: the tabs.</tal:comment>
|
||||
<tr valign="middle"><td style="border-bottom: 1px solid #ff8040">
|
||||
<table cellpadding="0" cellspacing="0" style="position:relative; bottom:-1px;">
|
||||
|
@ -132,9 +147,10 @@
|
|||
tal:define="cellgap widget/cellgap"
|
||||
tal:attributes="width widget/wide;
|
||||
align widget/align;
|
||||
class widget/css_class;
|
||||
class groupCss;
|
||||
cellspacing widget/cellspacing;
|
||||
cellpadding widget/cellpadding">
|
||||
cellpadding widget/cellpadding;
|
||||
id slaveId; name slaveId">
|
||||
<tal:comment replace="nothing">Display the title of the group if it is not rendered a fieldset.</tal:comment>
|
||||
<tr tal:condition="python: (widget['style'] != 'fieldset') and widget['hasLabel']">
|
||||
<td tal:attributes="colspan python: len(widget['columnsWidths']);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<metal:view define-macro="view"
|
||||
tal:define="fmt widget/format">
|
||||
<span tal:condition="python: fmt in (0, 3)"
|
||||
tal:attributes="class widget/master_css; id rawValue">
|
||||
tal:attributes="class masterCss; value rawValue; name name; id name">
|
||||
<ul tal:condition="python: value and isMultiple">
|
||||
<li tal:repeat="sv value"><i tal:content="structure sv"></i></li>
|
||||
</ul>
|
||||
|
@ -31,8 +31,8 @@
|
|||
tal:attributes="name name;
|
||||
id name;
|
||||
multiple python: isMultiple and 'multiple' or '';
|
||||
onchange python: isMaster and ('updateSlaves(getMasterValue(this), \'%s\')' % widget['id']) or '';
|
||||
class widget/master_css;
|
||||
onchange python: isMaster and 'updateSlaves(this)' or '';
|
||||
class masterCss;
|
||||
size python: isMultiple and widget['height'] or 1">
|
||||
<option tal:repeat="possibleValue possibleValues"
|
||||
tal:attributes="value python: possibleValue[0];
|
||||
|
|
Loading…
Reference in a new issue