appy.gen: reimplemented master/slave-related Javascript code without Plone queryCss.
This commit is contained in:
parent
c9353b46db
commit
e821307b4c
14 changed files with 172 additions and 158 deletions
|
@ -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,8 +177,8 @@ 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, };
|
||||
params[startKey] = startNumber;
|
||||
var params = {'fieldName': fieldName, 'innerRef': innerRef };
|
||||
params[startKey] = startNumber;
|
||||
if (action) params['action'] = action;
|
||||
if (actionParams) {
|
||||
for (key in actionParams) { params[key] = actionParams[key]; };
|
||||
|
@ -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";
|
||||
}
|
||||
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 = "";
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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"
|
||||
|
@ -42,17 +50,20 @@
|
|||
widget The widget to render
|
||||
</tal:comment>
|
||||
<metal:field define-macro="field"
|
||||
tal:define="contextMacro python: app.skyn.widgets;
|
||||
layout python: widget['layouts'][layoutType];
|
||||
name widget/name;
|
||||
sync python: widget['sync'][layoutType];
|
||||
rawValue python: contextObj.getFieldValue(name, onlyIfSync=True, layoutType=layoutType);
|
||||
value python: contextObj.getFormattedFieldValue(name, rawValue);
|
||||
requestValue python: request.get(name, None);
|
||||
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)">
|
||||
tal:define="contextMacro python: app.skyn.widgets;
|
||||
layout python: widget['layouts'][layoutType];
|
||||
name widget/name;
|
||||
sync python: widget['sync'][layoutType];
|
||||
rawValue python: contextObj.getFieldValue(name, onlyIfSync=True, layoutType=layoutType);
|
||||
value python: contextObj.getFormattedFieldValue(name, rawValue);
|
||||
requestValue python: request.get(name, None);
|
||||
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);
|
||||
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…
Add table
Add a link
Reference in a new issue