Allow for Field Validators to handle None values, fixed issue 1183, thanks Joe Barnhart
This commit is contained in:
@@ -1 +1 @@
|
|||||||
Version 2.2.1 (2012-11-29 18:20:27) stable
|
Version 2.2.1 (2012-11-29 22:34:41) stable
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ input[type=text],input[type=password],select{width:300px; margin-right:5px}
|
|||||||
border-top:1px #DEDEDE solid;
|
border-top:1px #DEDEDE solid;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
// background:<fill here for header image>;
|
/* background:<fill here for header image>; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,6 +115,10 @@ div.flash {
|
|||||||
z-index:2000;
|
z-index:2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.flash #closeflash{color:inherit; float:right;}
|
||||||
|
.ie-lte7 div.flash
|
||||||
|
#closeflash{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
|
||||||
|
|
||||||
div.flash:hover { opacity:0.25; }
|
div.flash:hover { opacity:0.25; }
|
||||||
|
|
||||||
div.error_wrapper {display:block}
|
div.error_wrapper {display:block}
|
||||||
@@ -182,7 +186,7 @@ div.error {
|
|||||||
* will look better with the declarations below
|
* will look better with the declarations below
|
||||||
* if needed to remove base.css consider keeping these following lines in some css file.
|
* if needed to remove base.css consider keeping these following lines in some css file.
|
||||||
*/
|
*/
|
||||||
// .web2py_table {border:1px solid #ccc}
|
/* .web2py_table {border:1px solid #ccc} */
|
||||||
.web2py_paginator {}
|
.web2py_paginator {}
|
||||||
.web2py_grid {width:100%}
|
.web2py_grid {width:100%}
|
||||||
.web2py_grid table {width:100%}
|
.web2py_grid table {width:100%}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
|
|||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
var flash = jQuery('.flash');
|
var flash = jQuery('.flash');
|
||||||
flash.hide();
|
flash.hide();
|
||||||
if(flash.html()) flash.append('<span style="float:right;">×</span>').slideDown();
|
if(flash.html()) flash.append('<span id="closeflash">×</span>').slideDown();
|
||||||
web2py_ajax_init(document);
|
web2py_ajax_init(document);
|
||||||
web2py_event_handlers();
|
web2py_event_handlers();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<textarea id="output" readonly="readonly">web2py Shell {{=request.env.web2py_version}}</textarea>
|
<textarea id="output" readonly="readonly">web2py Shell {{=request.env.web2py_version}}</textarea>
|
||||||
|
|
||||||
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get">
|
<form id="form" action="{{=URL('callback',args=app)}}" method="get">
|
||||||
<div id="shellwrapper">
|
<div id="shellwrapper">
|
||||||
<div id="caret">>>></div>
|
<div id="caret">>>></div>
|
||||||
<div class="tooltip">
|
<div class="tooltip">
|
||||||
@@ -103,7 +103,7 @@ jQuery(document).ready(function(){
|
|||||||
if(s.length>1 && s.substr(s.length-1,1)=='\n' && s.substr(s.length-2,1)!=':' &&
|
if(s.length>1 && s.substr(s.length-1,1)=='\n' && s.substr(s.length-2,1)!=':' &&
|
||||||
(s.indexOf(':\n ')<0 || s.substr(s.length-2,1)=='\n')) {
|
(s.indexOf(':\n ')<0 || s.substr(s.length-2,1)=='\n')) {
|
||||||
t.val('');
|
t.val('');
|
||||||
jQuery.post("{{=URL(r=request,f='callback',args=app)}}",
|
jQuery.post("{{=URL('callback',args=app)}}",
|
||||||
{statement:s},function(data){o.html(o.html()+data).attr('scrollTop',o.attr('scrollHeight'));});
|
{statement:s},function(data){o.html(o.html()+data).attr('scrollTop',o.attr('scrollHeight'));});
|
||||||
} else { };
|
} else { };
|
||||||
if(event.keyCode==RETURN){
|
if(event.keyCode==RETURN){
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ input[type=text],input[type=password],select{width:300px; margin-right:5px}
|
|||||||
border-top:1px #DEDEDE solid;
|
border-top:1px #DEDEDE solid;
|
||||||
}
|
}
|
||||||
.header {
|
.header {
|
||||||
// background:<fill here for header image>;
|
/* background:<fill here for header image>; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,6 +115,10 @@ div.flash {
|
|||||||
z-index:2000;
|
z-index:2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.flash #closeflash{color:inherit; float:right;}
|
||||||
|
.ie-lte7 div.flash
|
||||||
|
#closeflash{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
|
||||||
|
|
||||||
div.flash:hover { opacity:0.25; }
|
div.flash:hover { opacity:0.25; }
|
||||||
|
|
||||||
div.error_wrapper {display:block}
|
div.error_wrapper {display:block}
|
||||||
@@ -182,7 +186,7 @@ div.error {
|
|||||||
* will look better with the declarations below
|
* will look better with the declarations below
|
||||||
* if needed to remove base.css consider keeping these following lines in some css file.
|
* if needed to remove base.css consider keeping these following lines in some css file.
|
||||||
*/
|
*/
|
||||||
// .web2py_table {border:1px solid #ccc}
|
/* .web2py_table {border:1px solid #ccc} */
|
||||||
.web2py_paginator {}
|
.web2py_paginator {}
|
||||||
.web2py_grid {width:100%}
|
.web2py_grid {width:100%}
|
||||||
.web2py_grid table {width:100%}
|
.web2py_grid table {width:100%}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
|
|||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
var flash = jQuery('.flash');
|
var flash = jQuery('.flash');
|
||||||
flash.hide();
|
flash.hide();
|
||||||
if(flash.html()) flash.append('<span style="float:right;">×</span>').slideDown();
|
if(flash.html()) flash.append('<span id="closeflash">×</span>').slideDown();
|
||||||
web2py_ajax_init(document);
|
web2py_ajax_init(document);
|
||||||
web2py_event_handlers();
|
web2py_event_handlers();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ div.flash {
|
|||||||
z-index:2000;
|
z-index:2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.flash #closeflash{color:inherit; float:right;}
|
||||||
|
.ie-lte7 div.flash
|
||||||
|
#closeflash{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;}
|
||||||
|
|
||||||
div.flash:hover { opacity:0.25; }
|
div.flash:hover { opacity:0.25; }
|
||||||
|
|
||||||
div.error_wrapper {display:block}
|
div.error_wrapper {display:block}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
|
|||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
var flash = jQuery('.flash');
|
var flash = jQuery('.flash');
|
||||||
flash.hide();
|
flash.hide();
|
||||||
if(flash.html()) flash.append('<span style="float:right;">×</span>').slideDown();
|
if(flash.html()) flash.append('<span id="closeflash">×</span>').slideDown();
|
||||||
web2py_ajax_init(document);
|
web2py_ajax_init(document);
|
||||||
web2py_event_handlers();
|
web2py_event_handlers();
|
||||||
});
|
});
|
||||||
|
|||||||
+5
-3
@@ -8495,6 +8495,7 @@ class Field(Expression):
|
|||||||
filter_in = None,
|
filter_in = None,
|
||||||
filter_out = None,
|
filter_out = None,
|
||||||
custom_qualifier = None,
|
custom_qualifier = None,
|
||||||
|
map_none = None,
|
||||||
):
|
):
|
||||||
self._db = self.db = None # both for backward compatibility
|
self._db = self.db = None # both for backward compatibility
|
||||||
self.op = None
|
self.op = None
|
||||||
@@ -8535,6 +8536,7 @@ class Field(Expression):
|
|||||||
self.custom_qualifier = custom_qualifier
|
self.custom_qualifier = custom_qualifier
|
||||||
self.label = label if label!=None else fieldname.replace('_',' ').title()
|
self.label = label if label!=None else fieldname.replace('_',' ').title()
|
||||||
self.requires = requires if requires!=None else []
|
self.requires = requires if requires!=None else []
|
||||||
|
self.map_none = map_none
|
||||||
|
|
||||||
def set_attributes(self,*args,**attributes):
|
def set_attributes(self,*args,**attributes):
|
||||||
self.__dict__.update(*args,**attributes)
|
self.__dict__.update(*args,**attributes)
|
||||||
@@ -8666,7 +8668,7 @@ class Field(Expression):
|
|||||||
def formatter(self, value):
|
def formatter(self, value):
|
||||||
requires = self.requires
|
requires = self.requires
|
||||||
if value is None or not requires:
|
if value is None or not requires:
|
||||||
return value
|
return value or self.map_none
|
||||||
if not isinstance(requires, (list, tuple)):
|
if not isinstance(requires, (list, tuple)):
|
||||||
requires = [requires]
|
requires = [requires]
|
||||||
elif isinstance(requires, tuple):
|
elif isinstance(requires, tuple):
|
||||||
@@ -8681,7 +8683,7 @@ class Field(Expression):
|
|||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
if not self.requires or self.requires == DEFAULT:
|
if not self.requires or self.requires == DEFAULT:
|
||||||
return (value, None)
|
return ((value if value!=self.map_none else None), None)
|
||||||
requires = self.requires
|
requires = self.requires
|
||||||
if not isinstance(requires, (list, tuple)):
|
if not isinstance(requires, (list, tuple)):
|
||||||
requires = [requires]
|
requires = [requires]
|
||||||
@@ -8689,7 +8691,7 @@ class Field(Expression):
|
|||||||
(value, error) = validator(value)
|
(value, error) = validator(value)
|
||||||
if error:
|
if error:
|
||||||
return (value, error)
|
return (value, error)
|
||||||
return (value, None)
|
return ((value if value!=self.map_none else None), None)
|
||||||
|
|
||||||
def count(self, distinct=None):
|
def count(self, distinct=None):
|
||||||
return Expression(self.db, self.db._adapter.COUNT, self, distinct, 'integer')
|
return Expression(self.db, self.db._adapter.COUNT, self, distinct, 'integer')
|
||||||
|
|||||||
Reference in New Issue
Block a user