[gen] Added field.persist to avoid storing values for fields that do not require it (like master fields only used to determine selectable values among slave fields).
This commit is contained in:
parent
b8ceb66a49
commit
ea08d7981f
|
@ -61,8 +61,7 @@ class Field:
|
|||
value=zobj.getFormattedFieldValue(name, rawValue, showChanges);
|
||||
requestValue=zobj.getRequestFieldValue(name);
|
||||
inRequest=req.has_key(name);
|
||||
errors=errors|();
|
||||
inError=name in errors;
|
||||
error=req.get('%s_error' % name);
|
||||
isMultiple=(field.multiplicity[1] == None) or \
|
||||
(field.multiplicity[1] > 1);
|
||||
masterCss=field.slaves and ('master_%s' % name) or '';
|
||||
|
@ -86,8 +85,8 @@ class Field:
|
|||
src=":url('help')"/></acronym>''')
|
||||
|
||||
# Displays validation-error-related info about a field.
|
||||
pxValidation = Px('''<x><acronym if="inError" title=":errors[name]"><img
|
||||
src=":url('warning')"/></acronym><img if="not inError"
|
||||
pxValidation = Px('''<x><acronym if="error" title=":error"><img
|
||||
src=":url('warning')"/></acronym><img if="not error"
|
||||
src=":url('warning_no.gif')"/></x>''')
|
||||
|
||||
# Displays the fact that a field is required.
|
||||
|
@ -107,7 +106,7 @@ class Field:
|
|||
layouts, move, indexed, searchable, specificReadPermission,
|
||||
specificWritePermission, width, height, maxChars, colspan,
|
||||
master, masterValue, focus, historized, sync, mapping, label,
|
||||
sdefault, scolspan, swidth, sheight):
|
||||
sdefault, scolspan, swidth, sheight, persist):
|
||||
# The validator restricts which values may be defined. It can be an
|
||||
# interval (1,None), a list of string values ['choice1', 'choice2'],
|
||||
# a regular expression, a custom function, a Selection instance, etc.
|
||||
|
@ -215,6 +214,10 @@ class Field:
|
|||
# Width and height for the search widget
|
||||
self.swidth = swidth or width
|
||||
self.sheight = sheight or height
|
||||
# "persist" indicates if field content must be stored in the database.
|
||||
# For some fields it is not wanted (ie, fields used only as masters to
|
||||
# update slave's selectable values).
|
||||
self.persist = persist
|
||||
|
||||
def init(self, name, klass, appName):
|
||||
'''When the application server starts, this secondary constructor is
|
||||
|
@ -584,26 +587,14 @@ class Field:
|
|||
res += '+'
|
||||
return res
|
||||
|
||||
def getOnChange(self, name, zobj, layoutType):
|
||||
def getOnChange(self, zobj, layoutType):
|
||||
'''When this field is a master, this method computes the call to the
|
||||
Javascript function that will be called when its value changes (in
|
||||
order to update slaves).'''
|
||||
if not self.slaves: return ''
|
||||
q = zobj.getTool().quote
|
||||
# Create the dict of request values for slave fields.
|
||||
rvs = {}
|
||||
req = zobj.REQUEST
|
||||
for slave in self.slaves:
|
||||
name = slave.name
|
||||
if not req.has_key(name): continue
|
||||
if not req[name]: continue
|
||||
rvs[name] = req[name]
|
||||
if rvs:
|
||||
rvs = ',%s' % sutils.getStringDict(rvs)
|
||||
else:
|
||||
rvs = ''
|
||||
return 'updateSlaves(this,null,%s,%s%s)' % \
|
||||
(q(zobj.absolute_url()), q(layoutType), rvs)
|
||||
return 'updateSlaves(this,null,%s,%s)' % \
|
||||
(q(zobj.absolute_url()), q(layoutType))
|
||||
|
||||
def isEmptyValue(self, value, obj=None):
|
||||
'''Returns True if the p_value must be considered as an empty value.'''
|
||||
|
@ -680,7 +671,7 @@ class Field:
|
|||
def store(self, obj, value):
|
||||
'''Stores the p_value (produced by m_getStorableValue) that complies to
|
||||
p_self type definition on p_obj.'''
|
||||
setattr(obj, self.name, value)
|
||||
if self.persist: setattr(obj, self.name, value)
|
||||
|
||||
def callMethod(self, obj, method, cache=True):
|
||||
'''This method is used to call a p_method on p_obj. p_method is part of
|
||||
|
|
|
@ -74,7 +74,7 @@ class Action(Field):
|
|||
move, indexed, False, specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
master, masterValue, focus, historized, False, mapping,
|
||||
label, None, None, None, None)
|
||||
label, None, None, None, None, False)
|
||||
self.validable = False
|
||||
|
||||
def getDefaultLayouts(self): return {'view': 'l-f', 'edit': 'lrv-f'}
|
||||
|
|
|
@ -23,19 +23,17 @@ from appy.gen.layout import Table
|
|||
class Boolean(Field):
|
||||
'''Field for storing boolean values.'''
|
||||
|
||||
pxView = pxCell = Px('''
|
||||
<x><x>:value</x>
|
||||
pxView = pxCell = Px('''<x>:value</x>
|
||||
<input type="hidden" if="masterCss"
|
||||
class=":masterCss" value=":rawValue" name=":name" id=":name"/>
|
||||
</x>''')
|
||||
class=":masterCss" value=":rawValue" name=":name" id=":name"/>''')
|
||||
|
||||
pxEdit = Px('''
|
||||
<x var="isChecked=field.isChecked(zobj, rawValue)">
|
||||
<input type="checkbox" name=":name + '_visible'" id=":name"
|
||||
class=":masterCss" checked=":isChecked"
|
||||
onclick=":'toggleCheckbox(%s, %s); %s' % (q(name), \
|
||||
q('%s_hidden' % name), field.getOnChange(name, zobj, \
|
||||
layoutType))"/>
|
||||
q('%s_hidden' % name), \
|
||||
field.getOnChange(zobj, layoutType))"/>
|
||||
<input type="hidden" name=":name" id=":'%s_hidden' % name"
|
||||
value=":isChecked and 'True' or 'False'"/>
|
||||
</x>''')
|
||||
|
@ -64,13 +62,14 @@ class Boolean(Field):
|
|||
specificWritePermission=False, width=None, height=None,
|
||||
maxChars=None, colspan=1, master=None, masterValue=None,
|
||||
focus=False, historized=False, mapping=None, label=None,
|
||||
sdefault=False, scolspan=1, swidth=None, sheight=None):
|
||||
sdefault=False, scolspan=1, swidth=None, sheight=None,
|
||||
persist=True):
|
||||
Field.__init__(self, validator, multiplicity, default, show, page,
|
||||
group, layouts, move, indexed, searchable,
|
||||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
self.pythonType = bool
|
||||
|
||||
# Layout including a description
|
||||
|
|
|
@ -222,7 +222,7 @@ class Calendar(Field):
|
|||
layouts, move, False, False, specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
master, masterValue, focus, False, True, mapping, label,
|
||||
None, None, None, None)
|
||||
None, None, None, None, True)
|
||||
# eventTypes can be a "static" list or tuple of strings that identify
|
||||
# the types of events that are supported by this calendar. It can also
|
||||
# be a method that computes such a "dynamic" list or tuple. When
|
||||
|
|
|
@ -70,7 +70,7 @@ class Computed(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, sync, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, False)
|
||||
self.validable = False
|
||||
|
||||
def getValue(self, obj):
|
||||
|
|
|
@ -173,7 +173,8 @@ class Date(Field):
|
|||
specificWritePermission=False, width=None, height=None,
|
||||
maxChars=None, colspan=1, master=None, masterValue=None,
|
||||
focus=False, historized=False, mapping=None, label=None,
|
||||
sdefault=None, scolspan=1, swidth=None, sheight=None):
|
||||
sdefault=None, scolspan=1, swidth=None, sheight=None,
|
||||
persist=True):
|
||||
self.format = format
|
||||
self.calendar = calendar
|
||||
self.startYear = startYear
|
||||
|
@ -186,7 +187,7 @@ class Date(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
|
||||
def getCss(self, layoutType, res):
|
||||
# CSS files are only required if the calendar must be shown.
|
||||
|
|
|
@ -279,7 +279,7 @@ class File(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, True)
|
||||
|
||||
@staticmethod
|
||||
def getFileObject(filePath, fileName=None, zope=False):
|
||||
|
|
|
@ -58,7 +58,7 @@ class Float(Field):
|
|||
maxChars=13, colspan=1, master=None, masterValue=None,
|
||||
focus=False, historized=False, mapping=None, label=None,
|
||||
sdefault=('',''), scolspan=1, swidth=None, sheight=None,
|
||||
precision=None, sep=(',', '.'), tsep=' '):
|
||||
persist=True, precision=None, sep=(',', '.'), tsep=' '):
|
||||
# The precision is the number of decimal digits. This number is used
|
||||
# for rendering the float, but the internal float representation is not
|
||||
# rounded.
|
||||
|
@ -80,7 +80,7 @@ class Float(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, maxChars, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
self.pythonType = float
|
||||
|
||||
def getFormattedValue(self, obj, value, showChanges=False):
|
||||
|
|
|
@ -34,6 +34,6 @@ class Info(Field):
|
|||
move, indexed, False, specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
master, masterValue, focus, historized, False, mapping,
|
||||
label, None, None, None, None)
|
||||
label, None, None, None, None, False)
|
||||
self.validable = False
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -54,13 +54,14 @@ class Integer(Field):
|
|||
specificWritePermission=False, width=5, height=None,
|
||||
maxChars=13, colspan=1, master=None, masterValue=None,
|
||||
focus=False, historized=False, mapping=None, label=None,
|
||||
sdefault=('',''), scolspan=1, swidth=None, sheight=None):
|
||||
sdefault=('',''), scolspan=1, swidth=None, sheight=None,
|
||||
persist=True):
|
||||
Field.__init__(self, validator, multiplicity, default, show, page,
|
||||
group, layouts, move, indexed, searchable,
|
||||
specificReadPermission, specificWritePermission, width,
|
||||
height, maxChars, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
self.pythonType = long
|
||||
|
||||
def validateValue(self, obj, value):
|
||||
|
|
|
@ -83,7 +83,8 @@ class List(Field):
|
|||
group, layouts, move, indexed, False,
|
||||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, None, None, None, None)
|
||||
historized, True, mapping, label, None, None, None, None,
|
||||
True)
|
||||
self.validable = True
|
||||
# Tuples of (names, Field instances) determining the format of every
|
||||
# element in the list.
|
||||
|
|
|
@ -54,7 +54,7 @@ class Ogone(Field):
|
|||
move, False, False,specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
master, masterValue, focus, False, True, mapping, label,
|
||||
None, None, None, None)
|
||||
None, None, None, None, False)
|
||||
# orderMethod must contain a method returning a dict containing info
|
||||
# about the order. Following keys are mandatory:
|
||||
# * orderID An identifier for the order. Don't use the object UID
|
||||
|
|
|
@ -84,7 +84,9 @@ class Pod(Field):
|
|||
move, indexed, searchable, specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
master, masterValue, focus, historized, False, mapping,
|
||||
label, None, None, None, None)
|
||||
label, None, None, None, None, True)
|
||||
# Param "persist" is set to True but actually, persistence for a pod
|
||||
# field is determined by freezing.
|
||||
self.validable = False
|
||||
|
||||
def isFrozen(self, obj):
|
||||
|
|
|
@ -286,7 +286,7 @@ class Ref(Field):
|
|||
uids=[o.UID() for o in \
|
||||
field.getLinkedObjects(zobj).objects]"
|
||||
name=":name" id=":name" size=":isMultiple and field.height or ''"
|
||||
onchange=":field.getOnChange(name, zobj, layoutType)"
|
||||
onchange=":field.getOnChange(zobj, layoutType)"
|
||||
multiple=":isMultiple">
|
||||
<option value="" if="not isMultiple">:_('choose_a_value')</option>
|
||||
<option for="ztied in zobjects" var2="uid=ztied.o.UID()"
|
||||
|
@ -328,8 +328,8 @@ class Ref(Field):
|
|||
label=None, queryable=False, queryFields=None, queryNbCols=1,
|
||||
navigable=False, searchSelect=None, changeOrder=True,
|
||||
sdefault='', scolspan=1, swidth=None, sheight=None,
|
||||
render='list', menuIdMethod=None, menuInfoMethod=None,
|
||||
menuUrlMethod=None):
|
||||
persist=True, render='list', menuIdMethod=None,
|
||||
menuInfoMethod=None, menuUrlMethod=None):
|
||||
self.klass = klass
|
||||
self.attribute = attribute
|
||||
# May the user add new objects through this ref ?
|
||||
|
@ -431,7 +431,7 @@ class Ref(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, None, colspan, master, masterValue, focus,
|
||||
historized, sync, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
self.validable = self.link
|
||||
|
||||
def getDefaultLayouts(self):
|
||||
|
@ -662,6 +662,7 @@ class Ref(Field):
|
|||
* a Zope object;
|
||||
* a Appy object;
|
||||
* a list of Appy or Zope objects.'''
|
||||
if not self.persist: return
|
||||
# Standardize p_value into a list of Zope objects
|
||||
objects = value
|
||||
if not objects: objects = []
|
||||
|
@ -759,6 +760,11 @@ class Ref(Field):
|
|||
res = self.masterValue(obj, masterValues)
|
||||
return res
|
||||
else:
|
||||
# If this field is a ajax-updatable slave, no need to compute
|
||||
# selectable objects: it will be overridden by method
|
||||
# self.masterValue by a subsequent ajax request (=the "if" statement
|
||||
# above).
|
||||
if self.masterValue and callable(self.masterValue): return []
|
||||
if not self.select:
|
||||
# No select method has been defined: we must retrieve all
|
||||
# objects of the referred type that the user is allowed to
|
||||
|
|
|
@ -110,7 +110,7 @@ class String(Field):
|
|||
withTranslations=True, withBlankValue=True)"
|
||||
name=":name" id=":name" class=":masterCss"
|
||||
multiple=":isMultiple and 'multiple' or ''"
|
||||
onchange=":field.getOnChange(name, zobj, layoutType)"
|
||||
onchange=":field.getOnChange(zobj, layoutType)"
|
||||
size=":isMultiple and field.height or 1">
|
||||
<option for="val in possibleValues" value=":val[0]"
|
||||
selected=":field.isSelected(zobj, name, val[0], rawValue)"
|
||||
|
@ -292,8 +292,9 @@ class String(Field):
|
|||
width=None, height=None, maxChars=None, colspan=1, master=None,
|
||||
masterValue=None, focus=False, historized=False, mapping=None,
|
||||
label=None, sdefault='', scolspan=1, swidth=None, sheight=None,
|
||||
transform='none', styles=('p','h1','h2','h3','h4'),
|
||||
allowImageUpload=True, inlineEdit=False):
|
||||
persist=True, transform='none',
|
||||
styles=('p','h1','h2','h3','h4'), allowImageUpload=True,
|
||||
inlineEdit=False):
|
||||
# According to format, the widget will be different: input field,
|
||||
# textarea, inline editor... Note that there can be only one String
|
||||
# field of format CAPTCHA by page, because the captcha challenge is
|
||||
|
@ -318,7 +319,7 @@ class String(Field):
|
|||
specificReadPermission, specificWritePermission, width,
|
||||
height, maxChars, colspan, master, masterValue, focus,
|
||||
historized, True, mapping, label, sdefault, scolspan,
|
||||
swidth, sheight)
|
||||
swidth, sheight, persist)
|
||||
self.isSelect = self.isSelection()
|
||||
# If self.isSelect, self.sdefault must be a list of value(s).
|
||||
if self.isSelect and not sdefault:
|
||||
|
@ -390,6 +391,7 @@ class String(Field):
|
|||
|
||||
def store(self, obj, value):
|
||||
'''When the value is XHTML, we perform some cleanup.'''
|
||||
if not self.persist: return
|
||||
if (self.format == String.XHTML) and value:
|
||||
# When image upload is allowed, ckeditor inserts some "style" attrs
|
||||
# (ie for image size when images are resized). So in this case we
|
||||
|
|
|
@ -417,7 +417,7 @@ class BaseMixin:
|
|||
# Trigger field-specific validation
|
||||
self.intraFieldValidation(errors, values)
|
||||
if errors.__dict__:
|
||||
rq.set('errors', errors.__dict__)
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
self.say(errorMessage)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -425,7 +425,7 @@ class BaseMixin:
|
|||
msg = self.interFieldValidation(errors, values)
|
||||
if not msg: msg = errorMessage
|
||||
if errors.__dict__:
|
||||
rq.set('errors', errors.__dict__)
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
self.say(msg)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -814,19 +814,27 @@ class BaseMixin:
|
|||
res.append(field)
|
||||
return res
|
||||
|
||||
def getSlaveFieldsRequestValues(self, pageName):
|
||||
'''Returns the list of slave fields having a masterValue being a
|
||||
method.'''
|
||||
res = {}
|
||||
def getSlavesRequestInfo(self, pageName):
|
||||
'''When slave fields must be updated via Ajax requests, we must carry
|
||||
some information from the global request object to the ajax requests:
|
||||
- the selected values in slave fields;
|
||||
- validation errors.'''
|
||||
requestValues = {}
|
||||
errors = {}
|
||||
req = self.REQUEST
|
||||
for field in self.getAllAppyTypes():
|
||||
if field.page.name != pageName: continue
|
||||
if field.masterValue and callable(field.masterValue):
|
||||
# We have such a field
|
||||
# We have a slave field that is updated via ajax requests.
|
||||
name = field.name
|
||||
# Remember the request value for this field if present.
|
||||
if req.has_key(name) and req[name]:
|
||||
res[name] = req[name]
|
||||
return sutils.getStringDict(res)
|
||||
requestValues[name] = req[name]
|
||||
# Remember the validation error for this field if present.
|
||||
errorKey = '%s_error' % name
|
||||
if req.has_key(errorKey):
|
||||
errors[name] = req[errorKey]
|
||||
return sutils.getStringDict(requestValues), sutils.getStringDict(errors)
|
||||
|
||||
def getCssJs(self, fields, layoutType, res):
|
||||
'''Gets, in p_res ~{'css':[s_css], 'js':[s_js]}~ the lists of
|
||||
|
|
|
@ -83,6 +83,20 @@ function evalInnerScripts(xhrObject, hookElem) {
|
|||
for (var i=0; i<scripts.length; i++) { eval(scripts[i].innerHTML) }
|
||||
}
|
||||
|
||||
function injectChunk(elem, content){
|
||||
if (!isIe) elem.innerHTML = content;
|
||||
else {
|
||||
if (elem.tagName != 'TABLE') elem.innerHTML = content;
|
||||
else {
|
||||
/* IE doesn't want to replace content of a table. Force it to do so via
|
||||
a temporary DOM element. */
|
||||
var temp = document.createElement('div');
|
||||
temp.innerHTML = content;
|
||||
elem.replaceChild(temp.firstChild, elem.firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getAjaxChunk(pos) {
|
||||
// This function is the callback called by the AJAX machinery (see function
|
||||
// askAjaxChunk below) when an Ajax response is available.
|
||||
|
@ -93,13 +107,14 @@ function getAjaxChunk(pos) {
|
|||
if (xhrObjects[pos].xhr.readyState == 1) {
|
||||
// The request has been initialized: display the waiting radar
|
||||
var hookElem = document.getElementById(hook);
|
||||
if (hookElem) hookElem.innerHTML = "<div align=\"center\"><img src=\"ui/waiting.gif\"/><\/div>";
|
||||
if (hookElem)
|
||||
injectChunk(hookElem, "<div align=\"center\"><img src=\"ui/waiting.gif\"/><\/div>");
|
||||
}
|
||||
if (xhrObjects[pos].xhr.readyState == 4) {
|
||||
// We have received the HTML chunk
|
||||
var hookElem = document.getElementById(hook);
|
||||
if (hookElem && (xhrObjects[pos].xhr.status == 200)) {
|
||||
hookElem.innerHTML = xhrObjects[pos].xhr.responseText;
|
||||
injectChunk(hookElem, xhrObjects[pos].xhr.responseText);
|
||||
// Call a custom Javascript function if required
|
||||
if (xhrObjects[pos].onGet) {
|
||||
xhrObjects[pos].onGet(xhrObjects[pos], hookElem);
|
||||
|
@ -229,12 +244,13 @@ function askComputedField(hookId, objectUrl, fieldName) {
|
|||
}
|
||||
|
||||
function askField(hookId, objectUrl, layoutType, showChanges, masterValues,
|
||||
requestValue){
|
||||
requestValue, error){
|
||||
// Sends an Ajax request for getting the content of any field.
|
||||
var fieldName = hookId.split('_')[1];
|
||||
var params = {'layoutType': layoutType, 'showChanges': showChanges};
|
||||
if (masterValues) params['masterValues'] = masterValues.join('*');
|
||||
if (requestValue) params[fieldName] = requestValue;
|
||||
if (error) params[fieldName + '_error'] = error;
|
||||
askAjaxChunk(hookId, 'GET', objectUrl, fieldName+':pxRender', params, null,
|
||||
evalInnerScripts);
|
||||
}
|
||||
|
@ -354,7 +370,7 @@ function getSlaves(master) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function updateSlaves(master, slave, objectUrl, layoutType, requestValues){
|
||||
function updateSlaves(master,slave,objectUrl,layoutType,requestValues,errors){
|
||||
/* Given the value(s) in a master field, we must update slave's visibility or
|
||||
value(s). If p_slave is given, it updates only this slave. Else, it updates
|
||||
all slaves of p_master. */
|
||||
|
@ -382,15 +398,19 @@ function updateSlaves(master, slave, objectUrl, layoutType, requestValues){
|
|||
var reqValue = null;
|
||||
if (requestValues && (slaveName in requestValues))
|
||||
reqValue = requestValues[slaveName];
|
||||
askField(slaveId, objectUrl, layoutType, false, masterValues, reqValue);
|
||||
var err = null;
|
||||
if (errors && (slaveName in errors))
|
||||
err = errors[slaveName];
|
||||
askField(slaveId,objectUrl,layoutType,false,masterValues,reqValue,err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initSlaves(objectUrl, layoutType, requestValues) {
|
||||
function initSlaves(objectUrl, layoutType, requestValues, errors) {
|
||||
/* When the current page is loaded, we must set the correct state for all
|
||||
slave fields. p_requestValues are those from the slave fields that must
|
||||
be ajax-updated. */
|
||||
slave fields. For those that are updated via Ajax requests, their
|
||||
p_requestValues and validation p_errors must be carried to those
|
||||
requests. */
|
||||
slaves = getElementsHavingName('table', 'slave');
|
||||
i = slaves.length -1;
|
||||
while (i >= 0) {
|
||||
|
@ -398,8 +418,7 @@ function initSlaves(objectUrl, layoutType, requestValues) {
|
|||
master = document.getElementById(masterName);
|
||||
// If master is not here, we can't hide its slaves when appropriate.
|
||||
if (master) {
|
||||
updateSlaves(master, slaves[i], objectUrl, layoutType, requestValues);
|
||||
}
|
||||
updateSlaves(master,slaves[i],objectUrl,layoutType,requestValues,errors);}
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,9 +141,10 @@ class ToolWrapper(AbstractWrapper):
|
|||
</x>''')
|
||||
|
||||
pxPageBottom = Px('''
|
||||
<script type="text/javascript">:'initSlaves(%s,%s,%s)' % \
|
||||
(q(zobj.absolute_url()), q(layoutType), \
|
||||
zobj.getSlaveFieldsRequestValues(page))</script>''')
|
||||
<script var="info=zobj.getSlavesRequestInfo(page)"
|
||||
type="text/javascript">:'initSlaves(%s,%s,%s,%s)' % \
|
||||
(q(zobj.absolute_url()), q(layoutType), info[0], info[1])
|
||||
</script>''')
|
||||
|
||||
pxPortlet = Px('''
|
||||
<x var="toolUrl=tool.url;
|
||||
|
|
|
@ -533,7 +533,7 @@ class AbstractWrapper(object):
|
|||
|
||||
pxEdit = Px('''
|
||||
<x var="x=zobj.allows('write', raiseError=True);
|
||||
errors=req.get('errors', None) or {};
|
||||
errors=req.get('errors', {});
|
||||
layout=zobj.getPageLayout(layoutType);
|
||||
cssJs={};
|
||||
phaseObj=zobj.getAppyPhases(currentOnly=True, \
|
||||
|
|
Loading…
Reference in a new issue