SQLFORM().accepts(onvalidation=dict(onchange=lambda....)), thanks Alan

This commit is contained in:
mdipierro
2012-09-23 19:24:05 -05:00
parent a9b6c4f1a3
commit 4027a3cda3
3 changed files with 44 additions and 8 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.0.9 (2012-09-23 19:16:20) stable Version 2.0.9 (2012-09-23 19:24:01) stable
+24 -2
View File
@@ -1938,6 +1938,7 @@ class FORM(DIV):
# check formname and formkey # check formname and formkey
status = True status = True
changed = False
request_vars = self.request_vars request_vars = self.request_vars
if session: if session:
formkey = session.get('_formkey[%s]' % formname, None) formkey = session.get('_formkey[%s]' % formname, None)
@@ -1950,18 +1951,23 @@ class FORM(DIV):
# check if editing a record that has been modified by the server # check if editing a record that has been modified by the server
if hasattr(self,'record_hash') and self.record_hash != formkey: if hasattr(self,'record_hash') and self.record_hash != formkey:
status = False status = False
self.record_changed = True self.record_changed = changed = True
status = self._traverse(status,hideerror) status = self._traverse(status,hideerror)
status = self.assert_status(status, request_vars) status = self.assert_status(status, request_vars)
if onvalidation: if onvalidation:
if isinstance(onvalidation, dict): if isinstance(onvalidation, dict):
onsuccess = onvalidation.get('onsuccess', None) onsuccess = onvalidation.get('onsuccess', None)
onfailure = onvalidation.get('onfailure', None) onfailure = onvalidation.get('onfailure', None)
onchange = onvalidation.get('onchange', None)
if onsuccess and status: if onsuccess and status:
onsuccess(self) onsuccess(self)
if onfailure and request_vars and not status: if onfailure and request_vars and not status:
onfailure(self) onfailure(self)
status = len(self.errors) == 0 status = len(self.errors) == 0
if changed:
if onchange and self.record_changed and \
self.detect_record_change:
onchange(self)
elif status: elif status:
if isinstance(onvalidation, (list, tuple)): if isinstance(onvalidation, (list, tuple)):
[f(self) for f in onvalidation] [f(self) for f in onvalidation]
@@ -2030,8 +2036,13 @@ class FORM(DIV):
onfailure = 'flash' - will show message_onfailure in response.flash onfailure = 'flash' - will show message_onfailure in response.flash
None - will do nothing None - will do nothing
can be a function (lambda form: pass) can be a function (lambda form: pass)
onchange = 'flash' - will show message_onchange in response.flash
None - will do nothing
can be a function (lambda form: pass)
message_onsuccess message_onsuccess
message_onfailure message_onfailure
message_onchange
next = where to redirect in case of success next = where to redirect in case of success
any other kwargs will be passed for form.accepts(...) any other kwargs will be passed for form.accepts(...)
""" """
@@ -2042,13 +2053,17 @@ class FORM(DIV):
onsuccess = kwargs.get('onsuccess','flash') onsuccess = kwargs.get('onsuccess','flash')
onfailure = kwargs.get('onfailure','flash') onfailure = kwargs.get('onfailure','flash')
onchange = kwargs.get('onchange', 'flash')
message_onsuccess = kwargs.get('message_onsuccess', message_onsuccess = kwargs.get('message_onsuccess',
current.T("Success!")) current.T("Success!"))
message_onfailure = kwargs.get('message_onfailure', message_onfailure = kwargs.get('message_onfailure',
current.T("Errors in form, please check it out.")) current.T("Errors in form, please check it out."))
message_onchange = kwargs.get('message_onchange',
current.T("Form consecutive submissions not allowed. " +
"Try re-submitting or refreshing the form page."))
next = kwargs.get('next',None) next = kwargs.get('next',None)
for key in ('message_onsuccess','message_onfailure','onsuccess', for key in ('message_onsuccess','message_onfailure','onsuccess',
'onfailure','next'): 'onfailure','next', 'message_onchange', 'onchange'):
if key in kwargs: if key in kwargs:
del kwargs[key] del kwargs[key]
@@ -2075,6 +2090,13 @@ class FORM(DIV):
elif callable(onfailure): elif callable(onfailure):
onfailure(self) onfailure(self)
return False return False
elif hasattr(self, "record_changed"):
if self.record_changed and self.detect_record_change:
if onchange == 'flash':
current.response.flash = message_onchange
elif callable(onchange):
onchange(self)
return False
def process(self, **kwargs): def process(self, **kwargs):
""" """
+19 -5
View File
@@ -888,6 +888,8 @@ class SQLFORM(FORM):
self.ignore_rw = ignore_rw self.ignore_rw = ignore_rw
self.formstyle = formstyle self.formstyle = formstyle
self.readonly = readonly self.readonly = readonly
# Default dbio setting
self.detect_record_change = None
nbsp = XML(' ') # Firefox2 does not display fields with blanks nbsp = XML(' ') # Firefox2 does not display fields with blanks
FORM.__init__(self, *[], **attributes) FORM.__init__(self, *[], **attributes)
@@ -1165,6 +1167,7 @@ class SQLFORM(FORM):
dbio=True, dbio=True,
hideerror=False, hideerror=False,
detect_record_change=False, detect_record_change=False,
**kwargs
): ):
""" """
@@ -1189,7 +1192,8 @@ class SQLFORM(FORM):
# implement logic to detect whether record exist but has been modified # implement logic to detect whether record exist but has been modified
# server side # server side
self.record_changed = None self.record_changed = None
if detect_record_change: self.detect_record_change = detect_record_change
if self.detect_record_change:
if self.record: if self.record:
self.record_changed = False self.record_changed = False
serialized = '|'.join(str(self.record[k]) for k in self.table.fields()) serialized = '|'.join(str(self.record[k]) for k in self.table.fields())
@@ -1245,6 +1249,7 @@ class SQLFORM(FORM):
keepvalues, keepvalues,
onvalidation, onvalidation,
hideerror=hideerror, hideerror=hideerror,
**kwargs
) )
self.deleted = \ self.deleted = \
@@ -1254,10 +1259,19 @@ class SQLFORM(FORM):
auch = record_id and self.errors and self.deleted auch = record_id and self.errors and self.deleted
# auch is true when user tries to delete a record if self.record_changed and self.detect_record_change:
# that does not pass validation, yet it should be deleted message_onchange = \
kwargs.setdefault("message_onchange",
if not ret and not auch: current.T("A record change was detected. " +
"Consecutive update self-submissions " +
"are not allowed. Try re-submitting or " +
"refreshing the form page."))
if message_onchange is not None:
current.response.flash = message_onchange
return ret
elif (not ret) and (not auch):
# auch is true when user tries to delete a record
# that does not pass validation, yet it should be deleted
for fieldname in self.fields: for fieldname in self.fields:
field = self.table[fieldname] field = self.table[fieldname]
### this is a workaround! widgets should always have default not None! ### this is a workaround! widgets should always have default not None!