[gen] Added, on edit.pt (the unique Appy form) a handler window.onbeforeunload to warn the user that data can be lost or a lock can stay on the object.
This commit is contained in:
parent
d42dffacad
commit
b3ff087e8f
|
@ -17,7 +17,8 @@ except ImportError:
|
||||||
_noroles = []
|
_noroles = []
|
||||||
|
|
||||||
# Errors -----------------------------------------------------------------------
|
# Errors -----------------------------------------------------------------------
|
||||||
jsMessages = ('no_elem_selected', 'delete_confirm', 'unlink_confirm')
|
jsMessages = ('no_elem_selected', 'delete_confirm', 'unlink_confirm',
|
||||||
|
'warn_leave_form')
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class ToolMixin(BaseMixin):
|
class ToolMixin(BaseMixin):
|
||||||
|
|
|
@ -202,7 +202,7 @@ class BaseMixin:
|
||||||
# page is already locked by the same user, we don't mind: he could have
|
# page is already locked by the same user, we don't mind: he could have
|
||||||
# used back/forward buttons of its browser...
|
# used back/forward buttons of its browser...
|
||||||
userId = user.getId()
|
userId = user.getId()
|
||||||
if (page in self.locks) and (userId != self.locks[page]):
|
if (page in self.locks) and (userId != self.locks[page][0]):
|
||||||
from AccessControl import Unauthorized
|
from AccessControl import Unauthorized
|
||||||
raise Unauthorized('This page is locked.')
|
raise Unauthorized('This page is locked.')
|
||||||
# Set the lock
|
# Set the lock
|
||||||
|
@ -302,7 +302,8 @@ class BaseMixin:
|
||||||
# If this object is created from an initiator, get info about him.
|
# If this object is created from an initiator, get info about him.
|
||||||
initiator, initiatorPage, initiatorField = self.getInitiatorInfo()
|
initiator, initiatorPage, initiatorField = self.getInitiatorInfo()
|
||||||
# If the user clicked on 'Cancel', go back to the previous page.
|
# If the user clicked on 'Cancel', go back to the previous page.
|
||||||
if rq.get('buttonCancel.x', None):
|
buttonClicked = rq.get('button')
|
||||||
|
if buttonClicked == 'cancel':
|
||||||
if initiator:
|
if initiator:
|
||||||
# Go back to the initiator page.
|
# Go back to the initiator page.
|
||||||
urlBack = initiator.getUrl(page=initiatorPage, nav='')
|
urlBack = initiator.getUrl(page=initiatorPage, nav='')
|
||||||
|
@ -359,13 +360,13 @@ class BaseMixin:
|
||||||
# main site page.
|
# main site page.
|
||||||
if not obj.allows('View'):
|
if not obj.allows('View'):
|
||||||
return self.goto(tool.getSiteUrl(), msg)
|
return self.goto(tool.getSiteUrl(), msg)
|
||||||
if rq.get('buttonOk.x', None) or saveConfirmed:
|
if (buttonClicked == 'save') or saveConfirmed:
|
||||||
obj.say(msg)
|
obj.say(msg)
|
||||||
if isNew and initiator:
|
if isNew and initiator:
|
||||||
return self.goto(initiator.getUrl(page=initiatorPage, nav=''))
|
return self.goto(initiator.getUrl(page=initiatorPage, nav=''))
|
||||||
else:
|
else:
|
||||||
return self.goto(obj.getUrl())
|
return self.goto(obj.getUrl())
|
||||||
if rq.get('buttonPrevious.x', None):
|
if buttonClicked == 'previous':
|
||||||
# Go to the previous page for this object.
|
# Go to the previous page for this object.
|
||||||
# We recompute the list of phases and pages because things
|
# We recompute the list of phases and pages because things
|
||||||
# may have changed since the object has been updated (ie,
|
# may have changed since the object has been updated (ie,
|
||||||
|
@ -388,7 +389,7 @@ class BaseMixin:
|
||||||
else:
|
else:
|
||||||
obj.say(msg)
|
obj.say(msg)
|
||||||
return self.goto(obj.getUrl())
|
return self.goto(obj.getUrl())
|
||||||
if rq.get('buttonNext.x', None):
|
if buttonClicked == 'next':
|
||||||
# Go to the next page for this object.
|
# Go to the next page for this object.
|
||||||
# We remember page name, because the next method may set a new
|
# We remember page name, because the next method may set a new
|
||||||
# current page if the current one is not visible anymore.
|
# current page if the current one is not visible anymore.
|
||||||
|
@ -398,7 +399,7 @@ class BaseMixin:
|
||||||
if pageName:
|
if pageName:
|
||||||
# Return to the edit or view page?
|
# Return to the edit or view page?
|
||||||
if pageInfo['showOnEdit']:
|
if pageInfo['showOnEdit']:
|
||||||
# Same remark as above (buttonPrevious).
|
# Same remark as above (click on "previous").
|
||||||
return self.goto(obj.getUrl(mode='edit', page=pageName))
|
return self.goto(obj.getUrl(mode='edit', page=pageName))
|
||||||
else:
|
else:
|
||||||
return self.goto(obj.getUrl(page=pageName))
|
return self.goto(obj.getUrl(page=pageName))
|
||||||
|
|
|
@ -202,6 +202,9 @@ appyLabels = [
|
||||||
('changes_hide', 'Hide changes'),
|
('changes_hide', 'Hide changes'),
|
||||||
('anonymous', 'an anonymous user'),
|
('anonymous', 'an anonymous user'),
|
||||||
('page_locked', '${date} - This page is locked by ${user}.'),
|
('page_locked', '${date} - This page is locked by ${user}.'),
|
||||||
|
('warn_leave_form', 'In some situations, by leaving this page this way, you ' \
|
||||||
|
'may lose encoded data or prevent other users from ' \
|
||||||
|
'editing it afterwards. Please use buttons instead.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Some default values for labels whose ids are not fixed (so they can't be
|
# Some default values for labels whose ids are not fixed (so they can't be
|
||||||
|
|
|
@ -333,6 +333,14 @@ function initSlaves() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function used to submit the appy form on edit.pt
|
||||||
|
function submitAppyForm(button) {
|
||||||
|
var theForm = document.getElementById('appyForm');
|
||||||
|
// On which button has the user clicked?
|
||||||
|
theForm.button.value = button;
|
||||||
|
theForm.submit();
|
||||||
|
}
|
||||||
|
|
||||||
// Function used for triggering a workflow transition
|
// Function used for triggering a workflow transition
|
||||||
function triggerTransition(transitionId, msg) {
|
function triggerTransition(transitionId, msg) {
|
||||||
var theForm = document.getElementById('triggerTransitionForm');
|
var theForm = document.getElementById('triggerTransitionForm');
|
||||||
|
@ -517,8 +525,9 @@ function doAskPasswordReinit() {
|
||||||
// Function that finally posts the edit form after the user has confirmed that
|
// Function that finally posts the edit form after the user has confirmed that
|
||||||
// she really wants to post it.
|
// she really wants to post it.
|
||||||
function postConfirmedEditForm() {
|
function postConfirmedEditForm() {
|
||||||
var theForm = document.getElementById('appyEditForm');
|
var theForm = document.getElementById('appyForm');
|
||||||
theForm.confirmed.value = "True";
|
theForm.confirmed.value = "True";
|
||||||
|
theForm.button.value = 'save';
|
||||||
theForm.submit();
|
theForm.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,16 +14,27 @@
|
||||||
tal:on-error="structure python: tool.manageError(error)">
|
tal:on-error="structure python: tool.manageError(error)">
|
||||||
|
|
||||||
<metal:prologue use-macro="context/ui/page/macros/prologue"/>
|
<metal:prologue use-macro="context/ui/page/macros/prologue"/>
|
||||||
<form id="appyEditForm" name="appyEditForm" method="post" enctype="multipart/form-data"
|
<tal:comment replace="nothing">Warn the user that the form should be left via buttons</tal:comment>
|
||||||
tal:attributes="action python: contextObj.absolute_url()+'/do';
|
<script type="text/javascript">
|
||||||
class python: test(confirmMsg, 'atBaseEditForm', 'enableUnloadProtection atBaseEditForm')">
|
window.onbeforeunload = function(e){
|
||||||
|
theForm = document.getElementById('appyForm');
|
||||||
|
if (theForm.button.value == "") {
|
||||||
|
var e = e || window.event;
|
||||||
|
if (e) {e.returnValue = warn_leave_form;}
|
||||||
|
return warn_leave_form;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<form id="appyForm" name="appyForm" method="post" enctype="multipart/form-data"
|
||||||
|
tal:attributes="action python: contextObj.absolute_url()+'/do'">
|
||||||
<input type="hidden" name="action" value="Update"/>
|
<input type="hidden" name="action" value="Update"/>
|
||||||
|
<input type="hidden" name="button" value=""/>
|
||||||
<input type="hidden" name="page" tal:attributes="value page"/>
|
<input type="hidden" name="page" tal:attributes="value page"/>
|
||||||
<input type="hidden" name="nav" tal:attributes="value request/nav|nothing"/>
|
<input type="hidden" name="nav" tal:attributes="value request/nav|nothing"/>
|
||||||
<input type="hidden" name="confirmed" value="False"/>
|
<input type="hidden" name="confirmed" value="False"/>
|
||||||
<metal:show use-macro="context/ui/page/macros/show"/>
|
<metal:show use-macro="context/ui/page/macros/show"/>
|
||||||
</form>
|
</form>
|
||||||
<script tal:condition="confirmMsg"
|
<script tal:condition="confirmMsg" type="text/javascript"
|
||||||
tal:content="python: 'askConfirm(\'script\', \'postConfirmedEditForm()\', \'%s\')' % confirmMsg">
|
tal:content="python: 'askConfirm(\'script\', \'postConfirmedEditForm()\', \'%s\')' % confirmMsg">
|
||||||
</script>
|
</script>
|
||||||
<metal:footer use-macro="context/ui/page/macros/footer"/>
|
<metal:footer use-macro="context/ui/page/macros/footer"/>
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
global allAreImported python:True">
|
global allAreImported python:True">
|
||||||
|
|
||||||
<div metal:use-macro="context/ui/page/macros/prologue"/>
|
<div metal:use-macro="context/ui/page/macros/prologue"/>
|
||||||
<script language="javascript">
|
<script type="text/javascript">
|
||||||
<!--
|
|
||||||
var importedElemsShown = false;
|
var importedElemsShown = false;
|
||||||
function toggleViewableElements() {
|
function toggleViewableElements() {
|
||||||
var rows = document.getElementsByName('importedElem');
|
var rows = document.getElementsByName('importedElem');
|
||||||
|
@ -50,7 +49,6 @@
|
||||||
f.submit();
|
f.submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-->
|
|
||||||
</script>
|
</script>
|
||||||
<tal:comment replace="nothing">Form for importing several meetings at once.</tal:comment>
|
<tal:comment replace="nothing">Form for importing several meetings at once.</tal:comment>
|
||||||
<form name="importElements"
|
<form name="importElements"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</tal:include>
|
</tal:include>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Javascript messages</tal:comment>
|
<tal:comment replace="nothing">Javascript messages</tal:comment>
|
||||||
<script language="javascript" tal:content="tool/getJavascriptMessages"></script>
|
<script type="text/javascript" tal:content="tool/getJavascriptMessages"></script>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Global form for deleting an object</tal:comment>
|
<tal:comment replace="nothing">Global form for deleting an object</tal:comment>
|
||||||
<form id="deleteForm" method="post" action="do">
|
<form id="deleteForm" method="post" action="do">
|
||||||
|
@ -230,7 +230,8 @@
|
||||||
tal:attributes="style python:test(historyExpanded, 'display:block', 'display:none')">
|
tal:attributes="style python:test(historyExpanded, 'display:block', 'display:none')">
|
||||||
<div tal:define="ajaxHookId python: contextObj.UID() + '_history';"
|
<div tal:define="ajaxHookId python: contextObj.UID() + '_history';"
|
||||||
tal:attributes="id ajaxHookId">
|
tal:attributes="id ajaxHookId">
|
||||||
<script tal:content="python: 'askObjectHistory(\'%s\',\'%s\',%d,0)' % (ajaxHookId, contextObj.absolute_url(),historyMaxPerPage)">
|
<script type="text/javascript"
|
||||||
|
tal:content="python: 'askObjectHistory(\'%s\',\'%s\',%d,0)' % (ajaxHookId, contextObj.absolute_url(),historyMaxPerPage)">
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
@ -241,11 +242,7 @@
|
||||||
|
|
||||||
<tal:comment replace="nothing">The page footer.</tal:comment>
|
<tal:comment replace="nothing">The page footer.</tal:comment>
|
||||||
<metal:footer define-macro="footer">
|
<metal:footer define-macro="footer">
|
||||||
<script language="javascript">
|
<script type="text/javascript">initSlaves();</script>
|
||||||
<!--
|
|
||||||
initSlaves();
|
|
||||||
-->
|
|
||||||
</script>
|
|
||||||
</metal:footer>
|
</metal:footer>
|
||||||
|
|
||||||
<tal:comment replace="nothing">
|
<tal:comment replace="nothing">
|
||||||
|
@ -260,31 +257,27 @@
|
||||||
<tal:comment replace="nothing">Previous</tal:comment>
|
<tal:comment replace="nothing">Previous</tal:comment>
|
||||||
<td tal:condition="python: previousPage and pageInfo['showPrevious']">
|
<td tal:condition="python: previousPage and pageInfo['showPrevious']">
|
||||||
<tal:button condition="isEdit">
|
<tal:button condition="isEdit">
|
||||||
<input type="image" name="buttonPrevious"
|
<img style="cursor:pointer" onClick="submitAppyForm('previous')"
|
||||||
tal:attributes="src string:$appUrl/ui/previous.png;
|
tal:attributes="src string:$appUrl/ui/previous.png; title python: _('page_previous')"/>
|
||||||
title python: _('page_previous')"/>
|
|
||||||
<input type="hidden" name="previousPage" tal:attributes="value previousPage"/>
|
<input type="hidden" name="previousPage" tal:attributes="value previousPage"/>
|
||||||
</tal:button>
|
</tal:button>
|
||||||
<tal:link condition="not: isEdit">
|
<tal:link condition="not: isEdit">
|
||||||
<a tal:attributes="href python: contextObj.getUrl(page=previousPage)">
|
<a tal:attributes="href python: contextObj.getUrl(page=previousPage)">
|
||||||
<img tal:attributes="src string:$appUrl/ui/previous.png;
|
<img tal:attributes="src string:$appUrl/ui/previous.png; title python: _('page_previous')"/>
|
||||||
title python: _('page_previous')"/>
|
|
||||||
</a>
|
</a>
|
||||||
</tal:link>
|
</tal:link>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Save</tal:comment>
|
<tal:comment replace="nothing">Save</tal:comment>
|
||||||
<td tal:condition="python: isEdit and pageInfo['showSave']">
|
<td tal:condition="python: isEdit and pageInfo['showSave']">
|
||||||
<input type="image" name="buttonOk"
|
<img style="cursor:pointer" onClick="submitAppyForm('save')"
|
||||||
tal:attributes="src string:$appUrl/ui/save.png;
|
tal:attributes="src string:$appUrl/ui/save.png; title python: _('object_save');"/>
|
||||||
title python: _('object_save')"/>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Cancel</tal:comment>
|
<tal:comment replace="nothing">Cancel</tal:comment>
|
||||||
<td tal:condition="python: isEdit and pageInfo['showCancel']">
|
<td tal:condition="python: isEdit and pageInfo['showCancel']">
|
||||||
<input type="image" name="buttonCancel"
|
<img style="cursor:pointer" onClick="submitAppyForm('cancel')"
|
||||||
tal:attributes="src string:$appUrl/ui/cancel.png;
|
tal:attributes="src string:$appUrl/ui/cancel.png; title python: _('object_cancel')"/>
|
||||||
title python: _('object_cancel')"/>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<tal:edit condition="not: isEdit">
|
<tal:edit condition="not: isEdit">
|
||||||
|
@ -309,17 +302,17 @@
|
||||||
|
|
||||||
<tal:comment replace="nothing">Refresh</tal:comment>
|
<tal:comment replace="nothing">Refresh</tal:comment>
|
||||||
<td tal:condition="contextObj/isDebug">
|
<td tal:condition="contextObj/isDebug">
|
||||||
<img title="Refresh" style="cursor:pointer; vertical-align:top"
|
<a tal:attributes="href python: contextObj.getUrl(mode=layoutType, page=page, refresh='yes')">
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode=layoutType, page=page, refresh='yes');
|
<img title="Refresh" style="vertical-align:top"
|
||||||
src string: $appUrl/ui/refresh.png"/>
|
tal:attributes="src string: $appUrl/ui/refresh.png"/>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Next</tal:comment>
|
<tal:comment replace="nothing">Next</tal:comment>
|
||||||
<td tal:condition="python: nextPage and pageInfo['showNext']">
|
<td tal:condition="python: nextPage and pageInfo['showNext']">
|
||||||
<tal:button condition="isEdit">
|
<tal:button condition="isEdit">
|
||||||
<input type="image" name="buttonNext"
|
<img style="cursor:pointer" onClick="submitAppyForm('next')"
|
||||||
tal:attributes="src string:$appUrl/ui/next.png;
|
tal:attributes="src string:$appUrl/ui/next.png; title python: _('page_next')"/>
|
||||||
title python: _('page_next')"/>
|
|
||||||
<input type="hidden" name="nextPage" tal:attributes="value nextPage"/>
|
<input type="hidden" name="nextPage" tal:attributes="value nextPage"/>
|
||||||
</tal:button>
|
</tal:button>
|
||||||
<tal:link condition="not: isEdit">
|
<tal:link condition="not: isEdit">
|
||||||
|
@ -330,7 +323,7 @@
|
||||||
</tal:link>
|
</tal:link>
|
||||||
</td>
|
</td>
|
||||||
<tal:comment replace="nothing">Workflow transitions</tal:comment>
|
<tal:comment replace="nothing">Workflow transitions</tal:comment>
|
||||||
<td tal:condition="python: layoutType in ('view', 'result')">
|
<td tal:condition="not: isEdit">
|
||||||
<metal:transitions use-macro="app/ui/page/macros/transitions"/>
|
<metal:transitions use-macro="app/ui/page/macros/transitions"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
<tal:link repeat="name tool/getGlobalCssJs">
|
<tal:link repeat="name tool/getGlobalCssJs">
|
||||||
<link tal:condition="python: name.endswith('.css') and not ((dir == 'ltr') and (name == 'appyrtl.css'))"
|
<link tal:condition="python: name.endswith('.css') and not ((dir == 'ltr') and (name == 'appyrtl.css'))"
|
||||||
rel="stylesheet" type="text/css" tal:attributes="href string:$appUrl/ui/$name"/>
|
rel="stylesheet" type="text/css" tal:attributes="href string:$appUrl/ui/$name"/>
|
||||||
<script tal:condition="python: name.endswith('.js')"
|
<script tal:condition="python: name.endswith('.js')" type="text/javascript"
|
||||||
type="text/javascript" tal:attributes="src string:$appUrl/ui/$name"></script>
|
tal:attributes="src string:$appUrl/ui/$name"></script>
|
||||||
</tal:link>
|
</tal:link>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<tal:async condition="not: sync">
|
<tal:async condition="not: sync">
|
||||||
<div tal:define= "ajaxHookId python: contextObj.UID() + name"
|
<div tal:define= "ajaxHookId python: contextObj.UID() + name"
|
||||||
tal:attributes = "id ajaxHookId">
|
tal:attributes = "id ajaxHookId">
|
||||||
<script language="javascript"
|
<script type="text/javascript"
|
||||||
tal:content="python: 'askComputedField(\'%s\',\'%s\',\'%s\')' % (ajaxHookId, contextObj.absolute_url(), name)">
|
tal:content="python: 'askComputedField(\'%s\',\'%s\',\'%s\')' % (ajaxHookId, contextObj.absolute_url(), name)">
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
||||||
<input type="hidden" tal:attributes="id name; name name"/>
|
<input type="hidden" tal:attributes="id name; name name"/>
|
||||||
<img tal:attributes="id string:${name}_img; src string: $appUrl/ui/calendar.gif"/>
|
<img tal:attributes="id string:${name}_img; src string: $appUrl/ui/calendar.gif"/>
|
||||||
<script tal:content="python: contextObj.getCalendarInit(name, years)"></script>
|
<script type="text/javascript" tal:content="python: contextObj.getCalendarInit(name, years)"></script>
|
||||||
|
|
||||||
<tal:hour condition="python: widget['format'] == 0">
|
<tal:hour condition="python: widget['format'] == 0">
|
||||||
<select tal:define="hours python:range(0,24);"
|
<select tal:define="hours python:range(0,24);"
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
||||||
<input type="hidden" tal:attributes="id fromName; name fromName"/>
|
<input type="hidden" tal:attributes="id fromName; name fromName"/>
|
||||||
<img tal:attributes="id string:${fromName}_img; src string: $appUrl/ui/calendar.gif"/>
|
<img tal:attributes="id string:${fromName}_img; src string: $appUrl/ui/calendar.gif"/>
|
||||||
<script tal:content="python: tool.getCalendarInit(fromName, years)"></script>
|
<script type="text/javascript" tal:content="python: tool.getCalendarInit(fromName, years)"></script>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tal:comment replace="nothing">To</tal:comment>
|
<tal:comment replace="nothing">To</tal:comment>
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
<tal:comment replace="nothing">The icon for displaying the calendar popup</tal:comment>
|
||||||
<input type="hidden" tal:attributes="id toName; name toName"/>
|
<input type="hidden" tal:attributes="id toName; name toName"/>
|
||||||
<img tal:attributes="id string:${toName}_img; src string: $appUrl/ui/calendar.gif"/>
|
<img tal:attributes="id string:${toName}_img; src string: $appUrl/ui/calendar.gif"/>
|
||||||
<script tal:content="python: tool.getCalendarInit(toName, years)"></script>
|
<script type="text/javascript" tal:content="python: tool.getCalendarInit(toName, years)"></script>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -164,7 +164,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script language="javascript"
|
<script type="text/javascript"
|
||||||
tal:content="python: 'initTab(\'tab_%s\', \'%s_1_%d\')' % (widget['name'], widget['name'], len(widget['widgets']))"></script>
|
tal:content="python: 'initTab(\'tab_%s\', \'%s_1_%d\')' % (widget['name'], widget['name'], len(widget['widgets']))"></script>
|
||||||
</tal:asTabs>
|
</tal:asTabs>
|
||||||
</metal:group>
|
</metal:group>
|
||||||
|
|
Loading…
Reference in a new issue