[gen] Anti-double-click system.
This commit is contained in:
parent
f38792a5b9
commit
7c58582b9a
|
@ -66,8 +66,8 @@ class Pod(Field):
|
||||||
<img var="iconSuffix=frozen and 'Frozen' or ''"
|
<img var="iconSuffix=frozen and 'Frozen' or ''"
|
||||||
src=":url(fmt + iconSuffix)" class="clickable"
|
src=":url(fmt + iconSuffix)" class="clickable"
|
||||||
title=":field.getIconTitle(obj, fmt, frozen)"
|
title=":field.getIconTitle(obj, fmt, frozen)"
|
||||||
onclick=":'generatePod(%s,%s,%s,%s,%s,null,%s)' % (q(uid), q(name), \
|
onclick=":'generatePod(this,%s,%s,%s,%s,%s,null,%s)' % (q(uid), \
|
||||||
q(info.template), q(fmt), q(ztool.getQueryInfo()), gc)"/>''')
|
q(name), q(info.template), q(fmt), q(ztool.getQueryInfo()), gc)"/>''')
|
||||||
|
|
||||||
pxView = pxCell = Px('''
|
pxView = pxCell = Px('''
|
||||||
<x var="uid=obj.uid;
|
<x var="uid=obj.uid;
|
||||||
|
@ -125,7 +125,7 @@ class Pod(Field):
|
||||||
<tr for="mailing in mailings[fmt]" valign="top"
|
<tr for="mailing in mailings[fmt]" valign="top"
|
||||||
var2="mailingName=field.getMailingName(obj, mailing)">
|
var2="mailingName=field.getMailingName(obj, mailing)">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<a var="js='generatePod(%s,%s,%s,%s,%s,null,%s,%s)' % \
|
<a var="js='generatePod(this,%s,%s,%s,%s,%s,null,%s,%s)' % \
|
||||||
(q(uid), q(name), q(info.template), q(fmt), \
|
(q(uid), q(name), q(info.template), q(fmt), \
|
||||||
q(ztool.getQueryInfo()), gc, q(mailing))"
|
q(ztool.getQueryInfo()), gc, q(mailing))"
|
||||||
onclick=":'askConfirm(%s,%s)' % (q('script'), q(js, False))"
|
onclick=":'askConfirm(%s,%s)' % (q('script'), q(js, False))"
|
||||||
|
@ -738,21 +738,21 @@ class Pod(Field):
|
||||||
'''This method is called when an action tied to this pod field
|
'''This method is called when an action tied to this pod field
|
||||||
(generate, freeze, upload...) is triggered from the user
|
(generate, freeze, upload...) is triggered from the user
|
||||||
interface.'''
|
interface.'''
|
||||||
# What is the action to perform?
|
# What is the action to perform ?
|
||||||
action = rq.get('action', 'generate')
|
action = rq.get('action', 'generate')
|
||||||
# Security check.
|
# Security check
|
||||||
obj.o.mayView(self.readPermission, raiseError=True)
|
obj.o.mayView(self.readPermission, raiseError=True)
|
||||||
# Perform the requested action.
|
# Perform the requested action
|
||||||
tool = obj.tool.o
|
tool = obj.tool.o
|
||||||
template = rq.get('template')
|
template = rq.get('template')
|
||||||
format = rq.get('podFormat')
|
format = rq.get('podFormat')
|
||||||
if action == 'generate':
|
if action == 'generate':
|
||||||
# Generate a (or get a frozen) document.
|
# Generate a (or get a frozen) document
|
||||||
res = self.getValue(obj, template=template, format=format,
|
res = self.getValue(obj, template=template, format=format,
|
||||||
queryData=rq.get('queryData'),
|
queryData=rq.get('queryData'),
|
||||||
customContext=self.getCustomContext(obj, rq))
|
customContext=self.getCustomContext(obj, rq))
|
||||||
if isinstance(res, basestring):
|
if isinstance(res, basestring):
|
||||||
# An error has occurred, and p_res contains the error message.
|
# An error has occurred, and p_res contains the error message
|
||||||
obj.say(res)
|
obj.say(res)
|
||||||
return tool.goto(rq.get('HTTP_REFERER'))
|
return tool.goto(rq.get('HTTP_REFERER'))
|
||||||
# res contains a FileInfo instance.
|
# res contains a FileInfo instance.
|
||||||
|
@ -763,35 +763,36 @@ class Pod(Field):
|
||||||
# With disposition=inline, Google Chrome and IE may launch a PDF
|
# With disposition=inline, Google Chrome and IE may launch a PDF
|
||||||
# viewer that triggers one or many additional crashing HTTP GET
|
# viewer that triggers one or many additional crashing HTTP GET
|
||||||
# requests.
|
# requests.
|
||||||
|
rq.RESPONSE.setCookie('podDownload', 'true', path='/')
|
||||||
res.writeResponse(rq.RESPONSE, disposition='attachment')
|
res.writeResponse(rq.RESPONSE, disposition='attachment')
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# Send the email(s).
|
# Send the email(s)
|
||||||
msg = self.sendMailing(obj, template, mailing, res)
|
msg = self.sendMailing(obj, template, mailing, res)
|
||||||
obj.say(obj.translate(msg))
|
obj.say(obj.translate(msg))
|
||||||
return tool.goto(rq.get('HTTP_REFERER'))
|
return tool.goto(rq.get('HTTP_REFERER'))
|
||||||
# Performing any other action requires write access to p_obj.
|
# Performing any other action requires write access to p_obj
|
||||||
obj.o.mayEdit(self.writePermission, raiseError=True)
|
obj.o.mayEdit(self.writePermission, raiseError=True)
|
||||||
msg = 'action_done'
|
msg = 'action_done'
|
||||||
if action == 'freeze':
|
if action == 'freeze':
|
||||||
# (Re-)freeze a document in the database.
|
# (Re-)freeze a document in the database
|
||||||
self.freeze(obj, template, format, noSecurity=False,
|
self.freeze(obj, template, format, noSecurity=False,
|
||||||
freezeOdtOnError=False)
|
freezeOdtOnError=False)
|
||||||
elif action == 'unfreeze':
|
elif action == 'unfreeze':
|
||||||
# Unfreeze a document in the database.
|
# Unfreeze a document in the database
|
||||||
self.unfreeze(obj, template, format, noSecurity=False)
|
self.unfreeze(obj, template, format, noSecurity=False)
|
||||||
elif action == 'upload':
|
elif action == 'upload':
|
||||||
# Ensure a file from the correct type has been uploaded.
|
# Ensure a file from the correct type has been uploaded
|
||||||
upload = rq.get('uploadedFile')
|
upload = rq.get('uploadedFile')
|
||||||
if not upload or not upload.filename or \
|
if not upload or not upload.filename or \
|
||||||
not upload.filename.endswith('.%s' % format):
|
not upload.filename.endswith('.%s' % format):
|
||||||
# A wrong file has been uploaded (or no file at all)
|
# A wrong file has been uploaded (or no file at all)
|
||||||
msg = 'upload_invalid'
|
msg = 'upload_invalid'
|
||||||
else:
|
else:
|
||||||
# Store the uploaded file in the database.
|
# Store the uploaded file in the database
|
||||||
self.freeze(obj, template, format, noSecurity=False,
|
self.freeze(obj, template, format, noSecurity=False,
|
||||||
upload=upload)
|
upload=upload)
|
||||||
# Return a message to the user interface.
|
# Return a message to the user interface
|
||||||
obj.say(obj.translate(msg))
|
obj.say(obj.translate(msg))
|
||||||
return tool.goto(rq.get('HTTP_REFERER'))
|
return tool.goto(rq.get('HTTP_REFERER'))
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -164,6 +164,7 @@ class UiSearch:
|
||||||
<a href=":'%s?className=%s&search=%s' % \
|
<a href=":'%s?className=%s&search=%s' % \
|
||||||
(queryUrl, className, search.name)"
|
(queryUrl, className, search.name)"
|
||||||
class=":(search.name == currentSearch) and 'current' or ''"
|
class=":(search.name == currentSearch) and 'current' or ''"
|
||||||
|
onclick="clickOn(this)"
|
||||||
title=":search.translatedDescr">:search.translated</a>
|
title=":search.translatedDescr">:search.translated</a>
|
||||||
</div>''')
|
</div>''')
|
||||||
|
|
||||||
|
|
|
@ -472,10 +472,10 @@ class UiTransition:
|
||||||
css=ztool.getButtonCss(label, inButtons)">
|
css=ztool.getButtonCss(label, inButtons)">
|
||||||
<!-- Real button -->
|
<!-- Real button -->
|
||||||
<input if="transition.mayTrigger" type="button" class=":css"
|
<input if="transition.mayTrigger" type="button" class=":css"
|
||||||
var="back=inButtons and q(zobj.id) or 'null'"
|
var="back=inButtons and q(zobj.id) or 'null'" id=":transition.name"
|
||||||
style=":url(transition.icon, bg=True)" value=":label"
|
style=":url(transition.icon, bg=True)" value=":label"
|
||||||
onclick=":'triggerTransition(%s,%s,%s,%s)' % (q(formId), \
|
onclick=":'triggerTransition(%s,this,%s,%s)' % \
|
||||||
q(transition.name), q(transition.confirm), back)"/>
|
(q(formId), q(transition.confirm), back)"/>
|
||||||
|
|
||||||
<!-- Fake button, explaining why the transition can't be triggered -->
|
<!-- Fake button, explaining why the transition can't be triggered -->
|
||||||
<input if="not transition.mayTrigger" type="button"
|
<input if="not transition.mayTrigger" type="button"
|
||||||
|
|
|
@ -1006,10 +1006,9 @@ class BaseMixin:
|
||||||
if mode == 'link':
|
if mode == 'link':
|
||||||
inPopup = inPopup or (target.target != '_self')
|
inPopup = inPopup or (target.target != '_self')
|
||||||
url = self.getUrl(page=page, nav=nav, inPopup=inPopup)
|
url = self.getUrl(page=page, nav=nav, inPopup=inPopup)
|
||||||
onClick = target.openPopup and \
|
onClick = target.openPopup or 'clickOn(this)'
|
||||||
(' onclick="%s"' % target.openPopup) or ''
|
res = '<a href="%s" class="%s" onclick="%s" target="%s">%s</a>' % \
|
||||||
res = '<a href="%s" class="%s" target="%s"%s>%s</a>' % \
|
(url, cssClass, onClick, target.target, title)
|
||||||
(url, cssClass, target.target, onClick, title)
|
|
||||||
elif mode == 'select':
|
elif mode == 'select':
|
||||||
res = '<span class="%s clickable" onclick="%s">%s</span>' % \
|
res = '<span class="%s clickable" onclick="%s">%s</span>' % \
|
||||||
(cssClass, selectJs, title)
|
(cssClass, selectJs, title)
|
||||||
|
|
|
@ -13,6 +13,7 @@ h5 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;
|
||||||
h6 { font-size: 9pt; margin:0; font-weight: bold }
|
h6 { font-size: 9pt; margin:0; font-weight: bold }
|
||||||
a { text-decoration: none; color: #114353 }
|
a { text-decoration: none; color: #114353 }
|
||||||
a:visited { color: #114353 }
|
a:visited { color: #114353 }
|
||||||
|
.unclickable { pointer-events: none; color: grey !important }
|
||||||
table { font-size: 100%; border-spacing: 0px; border-collapse:collapse }
|
table { font-size: 100%; border-spacing: 0px; border-collapse:collapse }
|
||||||
form { margin: 0; padding: 0 }
|
form { margin: 0; padding: 0 }
|
||||||
p { margin: 0 0 5px 0 }
|
p { margin: 0 0 5px 0 }
|
||||||
|
|
107
gen/ui/appy.js
107
gen/ui/appy.js
|
@ -1,4 +1,9 @@
|
||||||
var wrongTextInput = '#F9EDBE none';
|
var wrongTextInput = '#F9EDBE none';
|
||||||
|
var loadingLink = '<img src="ui/loading.gif"/>';
|
||||||
|
var loadingButton = '<img align="center" src="ui/loadingBtn.gif"/>';
|
||||||
|
var loadingZone = '<div align="center"><img src="ui/loadingBig.gif"/></div>';
|
||||||
|
var lsTimeout; // Timout for the live search
|
||||||
|
var podTimeout; // Timeout for checking status of pod downloads
|
||||||
|
|
||||||
// Functions related to user authentication
|
// Functions related to user authentication
|
||||||
function cookiesAreEnabled() {
|
function cookiesAreEnabled() {
|
||||||
|
@ -97,9 +102,9 @@ function injectChunk(elem, content, inner, searchTop){
|
||||||
else {
|
else {
|
||||||
// Replace p_elem with a new node filled with p_content and return it
|
// Replace p_elem with a new node filled with p_content and return it
|
||||||
var id = elem.id;
|
var id = elem.id;
|
||||||
if (searchTop) id = ':' + id;
|
if (id && searchTop) id = ':' + id;
|
||||||
elem.outerHTML = content;
|
elem.outerHTML = content;
|
||||||
res = getAjaxHook(id); // Get the new element
|
if (id) res = getAjaxHook(id); // Get the new element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -113,6 +118,25 @@ function injectChunk(elem, content, inner, searchTop){
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickOn(node) {
|
||||||
|
// If node is a form, disable all form buttons
|
||||||
|
if (node.tagName == 'FORM') {
|
||||||
|
var i = node.elements.length -1;
|
||||||
|
while (i >= 0) {
|
||||||
|
if (node.elements[i].type == 'button') { clickOn(node.elements[i]); }
|
||||||
|
i = i - 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Disable any click on p_node to be protected against double-click
|
||||||
|
var cn = (node.className)? 'unclickable ' + node.className : 'unclickable';
|
||||||
|
node.className = cn;
|
||||||
|
/* For a button, show the preloader directly. For a link, show it only after
|
||||||
|
a while, if the target page is still not there. */
|
||||||
|
if (node.tagName != 'A') injectChunk(node, loadingButton);
|
||||||
|
else setTimeout(function(){injectChunk(node, loadingLink)}, 700);
|
||||||
|
}
|
||||||
|
|
||||||
function getAjaxHook(hookId, forceTop) {
|
function getAjaxHook(hookId, forceTop) {
|
||||||
/* Gets the XHTML element whose ID is p_hookId: it will be the placeholder
|
/* Gets the XHTML element whose ID is p_hookId: it will be the placeholder
|
||||||
for the result of an ajax request. If p_hookId starts with ':', we search
|
for the result of an ajax request. If p_hookId starts with ':', we search
|
||||||
|
@ -136,32 +160,22 @@ function getAjaxChunk(pos) {
|
||||||
// This function is the callback called by the AJAX machinery (see function
|
// This function is the callback called by the AJAX machinery (see function
|
||||||
// askAjaxChunk below) when an Ajax response is available.
|
// askAjaxChunk below) when an Ajax response is available.
|
||||||
// First, find back the correct XMLHttpRequest object
|
// First, find back the correct XMLHttpRequest object
|
||||||
if ( (typeof(xhrObjects[pos]) != 'undefined') &&
|
var rq = xhrObjects[pos];
|
||||||
(xhrObjects[pos].freed == 0)) {
|
if ( (typeof(rq) != 'undefined') && (rq.freed == 0)) {
|
||||||
var hook = xhrObjects[pos].hook;
|
if ((!rq.hook) || (rq.xhr.readyState != 4)) return;
|
||||||
if (hook && (xhrObjects[pos].xhr.readyState == 1)) {
|
|
||||||
// The request has been initialized: display the waiting radar
|
|
||||||
var hookElem = getAjaxHook(hook);
|
|
||||||
if (hookElem)
|
|
||||||
injectChunk(hookElem, "<div align=\"center\"><img src=\"ui/waiting.gif\"/><\/div>", true);
|
|
||||||
}
|
|
||||||
if (xhrObjects[pos].xhr.readyState == 4) {
|
|
||||||
// We have received the HTML chunk
|
// We have received the HTML chunk
|
||||||
var hookElem = getAjaxHook(hook);
|
var hookElem = getAjaxHook(rq.hook);
|
||||||
if (hookElem) {
|
if (hookElem) {
|
||||||
var content = xhrObjects[pos].xhr.responseText;
|
var content = rq.xhr.responseText;
|
||||||
var searchTop = hook[0] == ':';
|
var searchTop = rq.hook[0] == ':';
|
||||||
var injected = injectChunk(hookElem, content, false, searchTop);
|
var injected = injectChunk(hookElem, content, false, searchTop);
|
||||||
// Call a custom Javascript function if required
|
// Call a custom Javascript function if required
|
||||||
if (xhrObjects[pos].onGet) {
|
if (rq.onGet) rq.onGet(rq, injected);
|
||||||
xhrObjects[pos].onGet(xhrObjects[pos], injected);
|
|
||||||
}
|
|
||||||
// Display the Appy message if present
|
// Display the Appy message if present
|
||||||
var msg = xhrObjects[pos].xhr.getResponseHeader('Appy-Message');
|
var msg = rq.xhr.getResponseHeader('Appy-Message');
|
||||||
if (msg) showAppyMessage(decodeURIComponent(escape(msg)));
|
if (msg) showAppyMessage(decodeURIComponent(escape(msg)));
|
||||||
}
|
}
|
||||||
xhrObjects[pos].freed = 1;
|
rq.freed = 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +231,8 @@ function askAjaxChunk(hook, mode, url, px, params, beforeSend, onGet) {
|
||||||
if (mode == 'GET') {
|
if (mode == 'GET') {
|
||||||
urlFull = urlFull + '?' + paramsFull;
|
urlFull = urlFull + '?' + paramsFull;
|
||||||
}
|
}
|
||||||
|
// Display the preloader
|
||||||
|
injectChunk(getAjaxHook(rq.hook), loadingZone, true);
|
||||||
// Perform the asynchronous HTTP GET or POST
|
// Perform the asynchronous HTTP GET or POST
|
||||||
rq.xhr.open(mode, urlFull, true);
|
rq.xhr.open(mode, urlFull, true);
|
||||||
if (mode == 'POST') {
|
if (mode == 'POST') {
|
||||||
|
@ -651,8 +667,8 @@ function initSlaves(objectUrl, layoutType, requestValues, errors) {
|
||||||
function submitAppyForm(button) {
|
function submitAppyForm(button) {
|
||||||
var f = document.getElementById('appyForm');
|
var f = document.getElementById('appyForm');
|
||||||
// On which button has the user clicked ?
|
// On which button has the user clicked ?
|
||||||
f.button.value = button;
|
f.button.value = button.id;
|
||||||
f.submit();
|
f.submit(); clickOn(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitForm(formId, msg, showComment, back) {
|
function submitForm(formId, msg, showComment, back) {
|
||||||
|
@ -661,8 +677,8 @@ function submitForm(formId, msg, showComment, back) {
|
||||||
/* Submit the form and either refresh the entire page (back is null)
|
/* Submit the form and either refresh the entire page (back is null)
|
||||||
or ajax-refresh a given part only (p_back corresponds to the id of the
|
or ajax-refresh a given part only (p_back corresponds to the id of the
|
||||||
DOM node to be refreshed. */
|
DOM node to be refreshed. */
|
||||||
if (back) askAjax(back, formId);
|
if (back) { askAjax(back, formId); }
|
||||||
else f.submit();
|
else { f.submit(); clickOn(f) }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Ask a confirmation to the user before proceeding
|
// Ask a confirmation to the user before proceeding
|
||||||
|
@ -674,9 +690,9 @@ function submitForm(formId, msg, showComment, back) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function used for triggering a workflow transition
|
// Function used for triggering a workflow transition
|
||||||
function triggerTransition(formId, transitionId, msg, back) {
|
function triggerTransition(formId, node, msg, back) {
|
||||||
var f = document.getElementById(formId);
|
var f = document.getElementById(formId);
|
||||||
f.transition.value = transitionId;
|
f.transition.value = node.id;
|
||||||
submitForm(formId, msg, true, back);
|
submitForm(formId, msg, true, back);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,8 +805,17 @@ function toggleCookie(cookieId, display, defaultValue) {
|
||||||
createCookie(cookieId, newState);
|
createCookie(cookieId, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function podDownloadStatus(node, data) {
|
||||||
|
// Checks the status of cookie "podDownload"
|
||||||
|
var status = readCookie('podDownload');
|
||||||
|
// Stop the timeout if the download is complete
|
||||||
|
if (status == 'false') return;
|
||||||
|
clearInterval(podTimeout);
|
||||||
|
for (var key in data) node.setAttribute(key, data[key]);
|
||||||
|
}
|
||||||
|
|
||||||
// Function that allows to generate a document from a pod template
|
// Function that allows to generate a document from a pod template
|
||||||
function generatePod(uid, fieldName, template, podFormat, queryData,
|
function generatePod(node, uid, fieldName, template, podFormat, queryData,
|
||||||
customParams, getChecked, mailing) {
|
customParams, getChecked, mailing) {
|
||||||
var f = document.getElementById('podForm');
|
var f = document.getElementById('podForm');
|
||||||
f.objectUid.value = uid;
|
f.objectUid.value = uid;
|
||||||
|
@ -814,7 +839,22 @@ function generatePod(uid, fieldName, template, podFormat, queryData,
|
||||||
f.checkedSem.value = node['_appy_objs_sem'];
|
f.checkedSem.value = node['_appy_objs_sem'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Submitting the form at the end blocks the animated gifs on FF
|
||||||
f.submit();
|
f.submit();
|
||||||
|
// If p_node is an image, replace it with a preloader to prevent double-clicks
|
||||||
|
if (node.tagName == 'IMG') {
|
||||||
|
var data = {'src': node.src, 'class': node.className,
|
||||||
|
'onclick': node.attributes.onclick.value};
|
||||||
|
node.setAttribute('onclick', '');
|
||||||
|
node.className = '';
|
||||||
|
var src2 = node.src.replace(podFormat + '.png', 'loadingPod.gif');
|
||||||
|
node.setAttribute('src', src2);
|
||||||
|
// Initialize the pod download cookie. "false" means: not downloaded yet
|
||||||
|
createCookie('podDownload', 'false');
|
||||||
|
// Set a timer that will check the cookie value
|
||||||
|
podTimeout = window.setInterval(function(){
|
||||||
|
podDownloadStatus(node, data)}, 700);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function that allows to (un-)freeze a document from a pod template
|
// Function that allows to (un-)freeze a document from a pod template
|
||||||
|
@ -961,7 +1001,7 @@ function doConfirm() {
|
||||||
from the popup when relevant. */
|
from the popup when relevant. */
|
||||||
var f = document.getElementById(action);
|
var f = document.getElementById(action);
|
||||||
transferComment(confirmForm, f);
|
transferComment(confirmForm, f);
|
||||||
f.submit();
|
f.submit(); clickOn(f);
|
||||||
}
|
}
|
||||||
else if (actionType == 'url') { goto(action) } // Go to some URL
|
else if (actionType == 'url') { goto(action) } // Go to some URL
|
||||||
else if (actionType == 'script') { eval(action) } // Exec some JS code
|
else if (actionType == 'script') { eval(action) } // Exec some JS code
|
||||||
|
@ -970,7 +1010,7 @@ function doConfirm() {
|
||||||
var f = document.getElementById(elems[0]);
|
var f = document.getElementById(elems[0]);
|
||||||
// Submit the form in elems[0] and execute the JS code in elems[1]
|
// Submit the form in elems[0] and execute the JS code in elems[1]
|
||||||
transferComment(confirmForm, f);
|
transferComment(confirmForm, f);
|
||||||
f.submit();
|
f.submit(); clickOn(f);
|
||||||
eval(elems[1]);
|
eval(elems[1]);
|
||||||
}
|
}
|
||||||
else if (actionType == 'form-script') {
|
else if (actionType == 'form-script') {
|
||||||
|
@ -1031,13 +1071,13 @@ function manageTab(tabId, action) {
|
||||||
function showTab(tabId) {
|
function showTab(tabId) {
|
||||||
// 1st, show the tab to show
|
// 1st, show the tab to show
|
||||||
manageTab(tabId, 'show');
|
manageTab(tabId, 'show');
|
||||||
// Compute the number of tabs.
|
// Compute the number of tabs
|
||||||
var idParts = tabId.split('_');
|
var idParts = tabId.split('_');
|
||||||
var prefix = idParts[0] + '_';
|
var prefix = idParts[0] + '_';
|
||||||
// Store the currently selected tab in a cookie.
|
// Store the currently selected tab in a cookie
|
||||||
createCookie('tab_' + idParts[0], tabId);
|
createCookie('tab_' + idParts[0], tabId);
|
||||||
var nbOfTabs = idParts[2]*1;
|
var nbOfTabs = idParts[2]*1;
|
||||||
// Then, hide the other tabs.
|
// Then, hide the other tabs
|
||||||
for (var i=0; i<nbOfTabs; i++) {
|
for (var i=0; i<nbOfTabs; i++) {
|
||||||
var idTab = prefix + (i+1) + '_' + nbOfTabs;
|
var idTab = prefix + (i+1) + '_' + nbOfTabs;
|
||||||
if (idTab != tabId) {
|
if (idTab != tabId) {
|
||||||
|
@ -1238,7 +1278,6 @@ function reindexObject(indexName){
|
||||||
}
|
}
|
||||||
|
|
||||||
// Live-search-related functions (LS)
|
// Live-search-related functions (LS)
|
||||||
var lsTimeout;
|
|
||||||
function detectEventType(event) {
|
function detectEventType(event) {
|
||||||
/* After p_event occurred on a live search input field, must we trigger a
|
/* After p_event occurred on a live search input field, must we trigger a
|
||||||
search (a new char has been added), move up/down within the search
|
search (a new char has been added), move up/down within the search
|
||||||
|
|
BIN
gen/ui/loading.gif
Normal file
BIN
gen/ui/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
gen/ui/loadingBig.gif
Normal file
BIN
gen/ui/loadingBig.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
gen/ui/loadingBtn.gif
Normal file
BIN
gen/ui/loadingBtn.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
gen/ui/loadingPod.gif
Normal file
BIN
gen/ui/loadingPod.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB |
|
@ -223,6 +223,7 @@ class ToolWrapper(AbstractWrapper):
|
||||||
searchInfo.default.name or ''"
|
searchInfo.default.name or ''"
|
||||||
href=":'%s?className=%s&search=%s' % \
|
href=":'%s?className=%s&search=%s' % \
|
||||||
(queryUrl, className, queryParam)"
|
(queryUrl, className, queryParam)"
|
||||||
|
onclick="clickOn(this)"
|
||||||
class=":(not currentSearch and (currentClass==className) and \
|
class=":(not currentSearch and (currentClass==className) and \
|
||||||
(currentPage=='query')) and \
|
(currentPage=='query')) and \
|
||||||
'current' or ''">::_(className + '_plural')</a>
|
'current' or ''">::_(className + '_plural')</a>
|
||||||
|
|
|
@ -457,35 +457,35 @@ class AbstractWrapper(object):
|
||||||
css=ztool.getButtonCss(label, small=False)">
|
css=ztool.getButtonCss(label, small=False)">
|
||||||
<!-- Button on the edit page -->
|
<!-- Button on the edit page -->
|
||||||
<x if="isEdit">
|
<x if="isEdit">
|
||||||
<input type="button" class=":css" value=":label"
|
<input type="button" class=":css" value=":label" id="previous"
|
||||||
onclick="submitAppyForm('previous')"
|
onclick="submitAppyForm(this)"
|
||||||
style=":url('previous', bg=True)"/>
|
style=":url('previous', bg=True)"/>
|
||||||
<input type="hidden" name="previousPage" value=":previousPage"/>
|
<input type="hidden" name="previousPage" value=":previousPage"/>
|
||||||
</x>
|
</x>
|
||||||
<!-- Button on the view page -->
|
<!-- Button on the view page -->
|
||||||
<input if="not isEdit" type="button" class=":css" value=":label"
|
<input if="not isEdit" type="button" class=":css" value=":label"
|
||||||
style=":url('previous', bg=True)"
|
style=":url('previous', bg=True)" id="previous"
|
||||||
onclick=":'goto(%s)' % q(zobj.getUrl(page=previousPage, \
|
onclick=":'goto(%s)' % q(zobj.getUrl(page=previousPage, \
|
||||||
inPopup=inPopup))"/>
|
inPopup=inPopup))"/>
|
||||||
</x>
|
</x>
|
||||||
<!-- Save -->
|
<!-- Save -->
|
||||||
<input if="isEdit and pageInfo.showSave" type="button"
|
<input if="isEdit and pageInfo.showSave" type="button" id="save"
|
||||||
var2="label=_('object_save');
|
var2="label=_('object_save');
|
||||||
css=ztool.getButtonCss(label, small=False)"
|
css=ztool.getButtonCss(label, small=False)"
|
||||||
class=":css" onclick="submitAppyForm('save')"
|
class=":css" onclick="submitAppyForm(this)"
|
||||||
value=":label" style=":url('save', bg=True)" />
|
value=":label" style=":url('save', bg=True)" />
|
||||||
<!-- Cancel -->
|
<!-- Cancel -->
|
||||||
<input if="isEdit and pageInfo.showCancel" type="button"
|
<input if="isEdit and pageInfo.showCancel" type="button" id="cancel"
|
||||||
var2="label=_('object_cancel');
|
var2="label=_('object_cancel');
|
||||||
css=ztool.getButtonCss(label, small=False)"
|
css=ztool.getButtonCss(label, small=False)"
|
||||||
class=":css" onclick="submitAppyForm('cancel')" value=":label"
|
class=":css" onclick="submitAppyForm(this)" value=":label"
|
||||||
style=":url('cancel', bg=True)"/>
|
style=":url('cancel', bg=True)"/>
|
||||||
<x if="not isEdit"
|
<x if="not isEdit"
|
||||||
var2="locked=zobj.isLocked(user, page);
|
var2="locked=zobj.isLocked(user, page);
|
||||||
editable=pageInfo.showOnEdit and pageInfo.showEdit and \
|
editable=pageInfo.showOnEdit and pageInfo.showEdit and \
|
||||||
mayAct and zobj.mayEdit()">
|
mayAct and zobj.mayEdit()">
|
||||||
<!-- Edit -->
|
<!-- Edit -->
|
||||||
<input if="editable and not locked" type="button"
|
<input if="editable and not locked" type="button" id="edit"
|
||||||
var="label=_('object_edit');
|
var="label=_('object_edit');
|
||||||
css=ztool.getButtonCss(label, small=False)"
|
css=ztool.getButtonCss(label, small=False)"
|
||||||
value=":label" class=":css" style=":url('edit', bg=True)"
|
value=":label" class=":css" style=":url('edit', bg=True)"
|
||||||
|
@ -511,18 +511,18 @@ class AbstractWrapper(object):
|
||||||
value=":label" class=":css" style=":url('delete', bg=True)"
|
value=":label" class=":css" style=":url('delete', bg=True)"
|
||||||
onclick=":'onDeleteObject(%s)' % q(zobj.id)"/>
|
onclick=":'onDeleteObject(%s)' % q(zobj.id)"/>
|
||||||
<!-- Next -->
|
<!-- Next -->
|
||||||
<x if="nextPage and pageInfo.showNext"
|
<x if="nextPage and pageInfo.showNext" id="next"
|
||||||
var2="label=_('page_next');
|
var2="label=_('page_next');
|
||||||
css=ztool.getButtonCss(label, small=False)">
|
css=ztool.getButtonCss(label, small=False)">
|
||||||
<!-- Button on the edit page -->
|
<!-- Button on the edit page -->
|
||||||
<x if="isEdit">
|
<x if="isEdit">
|
||||||
<input type="button" class=":css" onclick="submitAppyForm('next')"
|
<input type="button" class=":css" onclick="submitAppyForm(this)"
|
||||||
style=":url('next', bg=True)" value=":label"/>
|
id="next" style=":url('next', bg=True)" value=":label"/>
|
||||||
<input type="hidden" name="nextPage" value=":nextPage"/>
|
<input type="hidden" name="nextPage" value=":nextPage"/>
|
||||||
</x>
|
</x>
|
||||||
<!-- Button on the view page -->
|
<!-- Button on the view page -->
|
||||||
<input if="not isEdit" type="button" class=":css" value=":label"
|
<input if="not isEdit" type="button" class=":css" value=":label"
|
||||||
style=":url('next', bg=True)"
|
style=":url('next', bg=True)" id="next"
|
||||||
onclick=":'goto(%s)' % q(zobj.getUrl(page=nextPage, \
|
onclick=":'goto(%s)' % q(zobj.getUrl(page=nextPage, \
|
||||||
inPopup=inPopup))"/>
|
inPopup=inPopup))"/>
|
||||||
</x>
|
</x>
|
||||||
|
|
Loading…
Reference in a new issue