[gen] New ajax system: more bugfixes.

This commit is contained in:
Gaetan Delannay 2015-02-05 14:05:29 +01:00
parent d23b9be5e5
commit 40e3612682
7 changed files with 48 additions and 35 deletions

View file

@ -176,7 +176,7 @@ class Ref(Field):
<a target="appyIFrame"
var="tiedClassName=tiedClassName|ztool.getPortalType(field.klass);
className=ztool.getPortalType(obj.klass)"
href=":'%s/query?className=%s&amp;search=%s:%s:%s&amp;popup=1' % \
href=":'%s/query?className=%s&amp;search=%s*%s*%s&amp;popup=1' % \
(ztool.absolute_url(), tiedClassName, obj.uid, field.name, \
popupMode)">
<input type="button"
@ -287,13 +287,13 @@ class Ref(Field):
<!-- Loop on every (tied or selectable) object -->
<x for="tied in objects"
var2="@currentNumber=currentNumber + 1;
rowCss=loop.tied.odd and 'even' or 'odd'">:obj.pxViewAsTied</x>
rowCss=loop.tied.odd and 'even' or 'odd'">:tied.pxViewAsTied</x>
</table>
<!-- Global actions -->
<x if="mayEdit and checkboxes">:field.pxGlobalActions</x>
<!-- (Bottom) navigation -->
<x>:tool.pxNavigate</x>
<!-- Init checkboxes if present. -->
<!-- Init checkboxes if present -->
<script if="checkboxes">:'initCbs(%s)' % q(ajaxHookId)</script>
</div>''')
@ -437,8 +437,8 @@ class Ref(Field):
collapse=field.getCollapseInfo(obj, False);
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
<!-- JS tables storing checkbox statuses if checkboxes are enabled -->
<script if="checkboxesEnabled and renderAll and (render == 'list')"
type="text/javascript">:field.getCbJsInit(zobj)</script>
<script if="checkboxesEnabled and renderAll \
and (render == 'list')">:field.getCbJsInit(zobj)</script>
<x if="linkList and renderAll and mayEdit"
var2="ajaxHookId='%s_%s_poss' % \
(zobj.id, field.name)">:field.pxViewPickList</x>
@ -1265,7 +1265,7 @@ class Ref(Field):
code = "\nnode['_appy_%%s_cbs']={};\nnode['_appy_%%s_sem']='%s';" % \
default
poss = (self.link == 'list') and (code % ('poss', 'poss')) or ''
return "var node=document.getElementById('%s_%s');%s%s" % \
return "var node=findNode(this, '%s_%s');%s%s" % \
(obj.id, self.name, code % ('objs', 'objs'), poss)
def getAjaxData(self, hook, zobj, **params):

View file

@ -202,8 +202,8 @@ class UiSearch:
<td colspan=":len(columns)+1">:_('query_no_result')</td>
</tr>
<x for="zobj in zobjects"
var2="@currentNumber=currentNumber + 1;
rowCss=loop.zobj.odd and 'even' or 'odd'">:obj.pxViewAsResult</x>
var2="rowCss=loop.zobj.odd and 'even' or 'odd';
@currentNumber=currentNumber + 1">:zobj.appy().pxViewAsResult</x>
</table>
<!-- The button for selecting objects and closing the popup -->
<div if="inPopup and cbShown" align=":dleft">
@ -241,7 +241,7 @@ class UiSearch:
<div var="ajaxHookId='queryResult';
className=req['className'];
searchName=req.get('search', '');
uiSearch=uiSearch|ztool.getSearch(className,searchName,ui=True);
uiSearch=field|ztool.getSearch(className, searchName, ui=True);
rootHookId=uiSearch.getRootHookId();
refInfo=ztool.getRefInfo();
refObject=refInfo[0];
@ -389,7 +389,7 @@ class UiSearch:
'''Returns the code that creates JS data structures for storing the
status of checkboxes for every result of this search.'''
default = self.search.checkboxesDefault and 'unchecked' or 'checked'
return '''var node=document.getElementById('%s');
return '''var node=findNode(this, '%s');
node['_appy_objs_cbs'] = {};
node['_appy_objs_sem'] = '%s';''' % (hookId, default)

View file

@ -223,11 +223,11 @@ class ToolMixin(BaseMixin):
return res
def getRootClasses(self):
'''Returns the list of root classes for this application.'''
'''Returns the list of root classes for this application'''
cfg = self.getProductConfig().appConfig
rootClasses = cfg.rootClasses
if not rootClasses:
# We consider every class as being a root class.
# We consider every class as being a root class
rootClasses = self.getProductConfig().appClassNames
return [self.getAppyClass(k) for k in rootClasses]
@ -749,10 +749,10 @@ class ToolMixin(BaseMixin):
# It is a custom search whose parameters are in the session
fields = self.REQUEST.SESSION['searchCriteria']
res = Search('customSearch', **fields)
elif ':' in name:
elif '*' in name:
# The search is defined in a Ref field with link=popup. Get the
# search, the initiator object and the Ref field.
uid, ref, mode = name.split(':')
uid, ref, mode = name.split('*')
initiator = self.getObject(uid, appy=True)
initiatorField = initiator.getField(ref)
res = getattr(initiator.klass, ref).select

View file

@ -405,8 +405,8 @@ class BaseMixin:
pageInfo = phaseObj.getPageInfo(rq['page'], 'view')
if not pageInfo: urlBack = tool.getHomePage()
else: urlBack = self.getUrl(page=pageInfo.page.name)
self.say(self.translate('object_canceled'))
self.removeLock(rq['page'])
self.say(self.translate('object_canceled'))
if inPopup: return back
return self.goto(urlBack)

View file

@ -403,7 +403,7 @@ function toggleCheckbox(visibleCheckbox, hiddenBoolean) {
else hidden.value = 'False';
}
// JS implementation of Python ''.rsplit.
// JS implementation of Python ''.rsplit
function _rsplit(s, delimiter, limit) {
var elems = s.split(delimiter);
var exc = elems.length - limit;
@ -419,11 +419,11 @@ function _rsplit(s, delimiter, limit) {
return res;
}
// (Un)checks a checkbox corresponding to a linked object.
// (Un)checks a checkbox corresponding to a linked object
function toggleCb(checkbox) {
var name = checkbox.getAttribute('name');
var elems = _rsplit(name, '_', 3);
// Get the DOM node corresponding to the Ref field.
// Get the DOM node corresponding to the Ref field
var node = document.getElementById(elems[0] + '_' + elems[1]);
// Get the array that stores checkbox statuses.
var statuses = node['_appy_' + elems[2] + '_cbs'];
@ -440,17 +440,26 @@ function toggleCb(checkbox) {
}
}
// Initialise checkboxes of a Ref field or Search.
function findNode(node, id) {
/* When coming back from the iframe popup, we are still in the context of the
iframe, which can cause problems for finding nodes. We have found that this
case can be detected by checking node.window. */
if (node.window) var container = node.window.document;
else var container = window.parent.document;
return container.getElementById(id);
}
// Initialise checkboxes of a Ref field or Search
function initCbs(id) {
var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field.
// Get the DOM node corresponding to the Ref field
var node = document.getElementById(elems[0] + '_' + elems[1]);
// Get the array that stores checkbox statuses.
// Get the array that stores checkbox statuses
var statuses = node['_appy_' + elems[2] + '_cbs'];
// Get the array semantics
var semantics = node['_appy_' + elems[2] + '_sem'];
var value = (semantics == 'unchecked')? false: true;
// Update visible checkboxes.
// Update visible checkboxes
var checkboxes = getElementsHavingName('input', id);
for (var i=0; i < checkboxes.length; i++) {
if (checkboxes[i].value in statuses) checkboxes[i].checked = value;
@ -458,15 +467,15 @@ function initCbs(id) {
}
}
// Toggle all checkboxes of a Ref field or Search.
// Toggle all checkboxes of a Ref field or Search
function toggleAllCbs(id) {
var elems = _rsplit(id, '_', 3);
// Get the DOM node corresponding to the Ref field.
// Get the DOM node corresponding to the Ref field
var node = document.getElementById(elems[0] + '_' + elems[1]);
// Empty the array that stores checkbox statuses.
// Empty the array that stores checkbox statuses
var statuses = node['_appy_' + elems[2] + '_cbs'];
for (var key in statuses) delete statuses[key];
// Switch the array semantics.
// Switch the array semantics
var semAttr = '_appy_' + elems[2] + '_sem';
if (node[semAttr] == 'unchecked') node[semAttr] = 'checked';
else node[semAttr] = 'unchecked';
@ -892,7 +901,7 @@ function closePopup(popupId, clean) {
// Reinitialise the enclosing iframe
var iframe = container.getElementById('appyIFrame');
iframe.style.width = null;
iframe.innerHTML = '';
while (iframe.firstChild) iframe.removeChild(iframe.firstChild);
// Leave the form silently if we are on an edit page
iframe.contentWindow.onbeforeunload = null;
}
@ -907,10 +916,10 @@ function backFromPopup() {
function showAppyMessage(message) {
// Fill the message zone with the message to display
var messageZone = document.getElementById('appyMessageContent');
var messageZone = getAjaxHook(':appyMessageContent');
messageZone.innerHTML = message;
// Display the message zone
var messageDiv = document.getElementById('appyMessage');
var messageDiv = getAjaxHook(':appyMessage');
messageDiv.style.display = 'block';
}
@ -1172,12 +1181,12 @@ function onSelectObjects(nodeId, objectUrl, mode, sortKey, sortOrder,
var node = document.getElementById(nodeId);
var uids = stringFromDictKeys(node['_appy_objs_cbs']);
var semantics = node['_appy_objs_sem'];
// Show an error message if no element is selected.
// Show an error message if no element is selected
if ((semantics == 'checked') && (!uids)) {
openPopup('alertPopup', no_elem_selected);
return;
}
// Close the popup.
// Close the popup
closePopup('iframePopup');
/* When refreshing the Ref field we will need to pass all those parameters,
for replaying the popup query. */
@ -1190,7 +1199,7 @@ function onSelectObjects(nodeId, objectUrl, mode, sortKey, sortOrder,
askField(':'+nodeId, objectUrl, 'edit', params, false);
}
else {
// Link the selected objects and refresh the Ref view widget.
// Link the selected objects and refresh the Ref view widget
params['action'] = 'onSelectFromPopup';
askField(':'+nodeId, objectUrl, 'view', params, false);
}

View file

@ -279,7 +279,7 @@ class ToolWrapper(AbstractWrapper):
<!-- The message content -->
<div id="appyMessageContent"></div>
</div>
<script type="text/javascript" var="messages=ztool.consumeMessages()"
<script var="messages=ztool.consumeMessages()"
if="messages">::'showAppyMessage(%s)' % q(messages)</script>''')
# The page footer

View file

@ -728,12 +728,16 @@ class AbstractWrapper(object):
x=resp.setHeader('Content-Language', lang);
x=resp.setHeader('Cache-Control', 'no-cache')">
<!-- If an action is defined, execute it on p_zobj or on p_field. -->
<!-- If an action is defined, execute it on p_zobj or on p_field -->
<x if="action"
var2="msg=ztool.executeAjaxAction(action, obj, field) or '';
x=resp.setHeader('Appy-Message', msg)"></x>
<!-- Then, call the PX on p_obj or on p_field. -->
<!-- Consume and return any session message -->
<x var="msg=ztool.consumeMessages()" if="msg"
var2="x=resp.setHeader('Appy-Message', msg)"></x>
<!-- Then, call the PX on p_obj or on p_field -->
<x if="not field">:getattr(obj, px[0])</x>
<x if="field">:getattr(field, px[-1])</x>
</x>''')