diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py
index 98d4395a..898e53fe 100644
--- a/gluon/sqlhtml.py
+++ b/gluon/sqlhtml.py
@@ -14,13 +14,18 @@ Holds:
"""
+import datetime
+import urllib
+import re
+import cStringIO
+
import os
-from gluon.http import HTTP
-from gluon.html import XmlComponent
-from gluon.html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG, SCRIPT, P
+from gluon.http import HTTP, redirect
+from gluon.html import XmlComponent, truncate_string
+from gluon.html import XML, SPAN, TAG, A, DIV, CAT, UL, LI, TEXTAREA, BR, IMG
from gluon.html import FORM, INPUT, LABEL, OPTION, SELECT, COL, COLGROUP
-from gluon.html import TABLE, THEAD, TBODY, TR, TD, TH, STYLE, DEFAULT_PASSWORD_DISPLAY
-from gluon.html import URL, truncate_string, FIELDSET
+from gluon.html import TABLE, THEAD, TBODY, TR, TD, TH, STYLE, SCRIPT
+from gluon.html import URL, FIELDSET, P, DEFAULT_PASSWORD_DISPLAY
from gluon.dal import DAL, Field
from gluon.dal.base import DEFAULT
from gluon.dal.objects import Table, Row, Expression
@@ -29,16 +34,12 @@ from gluon.dal.helpers.methods import smart_query, bar_encode, sqlhtml_validator
from gluon.dal.helpers.classes import Reference, SQLCustomType
from gluon.storage import Storage
from gluon.utils import md5_hash
-from gluon.validators import IS_EMPTY_OR, IS_NOT_EMPTY, IS_LIST_OF, IS_DATE, \
- IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE, IS_STRONG
+from gluon.validators import IS_EMPTY_OR, IS_NOT_EMPTY, IS_LIST_OF, IS_DATE
+from gluon.validators import IS_DATETIME, IS_INT_IN_RANGE, IS_FLOAT_IN_RANGE
+from gluon.validators import IS_STRONG
import gluon.serializers as serializers
-import datetime
-import urllib
-import re
-import cStringIO
from gluon.globals import current
-from gluon.http import redirect
try:
import gluon.settings as settings
@@ -49,7 +50,7 @@ widget_class = re.compile('^\w*')
def add_class(a, b):
- return a+' '+b if a else b
+ return a + ' ' + b if a else b
def represent(field, value, record):
@@ -85,11 +86,11 @@ def show_if(cond):
if not cond:
return None
base = "%s_%s" % (cond.first.tablename, cond.first.name)
- if ((cond.op.__name__ == 'EQ' and cond.second == True) or
- (cond.op.__name__ == 'NE' and cond.second == False)):
+ if ((cond.op.__name__ == 'EQ' and cond.second is True) or
+ (cond.op.__name__ == 'NE' and cond.second is False)):
return base, ":checked"
- if ((cond.op.__name__ == 'EQ' and cond.second == False) or
- (cond.op.__name__ == 'NE' and cond.second == True)):
+ if ((cond.op.__name__ == 'EQ' and cond.second is False) or
+ (cond.op.__name__ == 'NE' and cond.second is True)):
return base, ":not(:checked)"
if cond.op.__name__ == 'EQ':
return base, "[value='%s']" % cond.second
@@ -305,7 +306,8 @@ class ListWidget(StringWidget):
_class = 'string'
requires = field.requires if isinstance(
field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None
- if isinstance(value, str): value = [value]
+ if isinstance(value, str):
+ value = [value]
nvalue = value or ['']
items = [LI(INPUT(_id=_id, _class=_class, _name=_name,
value=v, hideerror=k < len(nvalue) - 1,
@@ -351,7 +353,6 @@ class RadioWidget(OptionsWidget):
else:
value = str(value)
-
attr = cls._attributes(field, {}, **attributes)
attr['_class'] = add_class(attr.get('_class'), 'web2py_radiowidget')
@@ -626,7 +627,7 @@ class AutocompleteWidget(object):
self.help_fields = help_fields or []
self.help_string = help_string
if self.help_fields and not self.help_string:
- self.help_string = ' '.join('%%(%s)s'%f.name
+ self.help_string = ' '.join('%%(%s)s' % f.name
for f in self.help_fields)
self.request = request
@@ -900,7 +901,7 @@ def formstyle_bootstrap3_inline_factory(col_label_size=3):
label['_for'] = None
label.insert(0, controls)
_controls = DIV(DIV(label, _help, _class="checkbox"),
- _class="%s %s" % (offset_class, col_class))
+ _class="%s %s" % (offset_class, col_class))
label = ''
elif isinstance(controls, SELECT):
controls.add_class('form-control')
@@ -1132,7 +1133,7 @@ class SQLFORM(FORM):
if fieldname.find('.') >= 0:
continue
- field = (self.table[fieldname] if fieldname in self.table.fields
+ field = (self.table[fieldname] if fieldname in self.table.fields
else self.extra_fields[fieldname])
comment = None
@@ -1184,7 +1185,7 @@ class SQLFORM(FORM):
cond = readonly or \
(not ignore_rw and not field.writable and field.readable)
- if default is not None and not cond:
+ if default is not None and not cond:
default = field.formatter(default)
dspval = default
@@ -1192,10 +1193,6 @@ class SQLFORM(FORM):
if cond:
- # ## if field.re field.requires = sqlhtml_validators(field) field.requires = sqlhtml_validators(field)present is available else
- # ## ignore blob and preview uploaded images
- # ## format everything else
-
if field.represent:
inp = represent(field, default, record)
elif field.type in ['blob']:
@@ -1272,7 +1269,7 @@ class SQLFORM(FORM):
(olname.replace('.', '__') + SQLFORM.ID_ROW_SUFFIX,
'', widget, col3.get(olname, '')))
self.custom.linkto[olname.replace('.', '__')] = widget
-#
+ #
# when deletable, add delete? checkbox
self.custom.delete = self.custom.deletable = ''
@@ -1291,16 +1288,15 @@ class SQLFORM(FORM):
)
xfields.append(
(self.FIELDKEY_DELETE_RECORD + SQLFORM.ID_ROW_SUFFIX,
- LABEL(
+ LABEL(
T(delete_label), sep,
_for=self.FIELDKEY_DELETE_RECORD,
- _id=self.FIELDKEY_DELETE_RECORD + \
- SQLFORM.ID_LABEL_SUFFIX),
+ _id=self.FIELDKEY_DELETE_RECORD +
+ SQLFORM.ID_LABEL_SUFFIX),
widget,
col3.get(self.FIELDKEY_DELETE_RECORD, '')))
self.custom.delete = self.custom.deletable = widget
-
# when writable, add submit button
self.custom.submit = ''
if not readonly:
@@ -1480,7 +1476,7 @@ class SQLFORM(FORM):
# that does not pass validation, yet it should be deleted
for fieldname in self.fields:
- field = (self.table[fieldname]
+ field = (self.table[fieldname]
if fieldname in self.table.fields
else self.extra_fields[fieldname])
### this is a workaround! widgets should always have default not None!
@@ -1995,6 +1991,18 @@ class SQLFORM(FORM):
details = details and not groupby
rows = None
+ # see issue 1980. Basically we can have keywords in get_vars
+ # (i.e. when the search term is propagated through page=2&keywords=abc)
+ # but if there is keywords in post_vars (i.e. POSTing a search request)
+ # the one in get_vars should be replaced by the new one
+ keywords = ''
+ if 'keywords' in request.post_vars:
+ keywords = request.post_vars.keywords
+ elif 'keywords' in request.get_vars:
+ keywords = request.get_vars.keywords
+
+ print 'keyworkds are', keywords
+
def fetch_count(dbset):
##FIXME for google:datastore cache_count is ignored
## if it's not an integer
@@ -2051,7 +2059,7 @@ class SQLFORM(FORM):
'/'.join(str(a) for a in args) == '/'.join(request.args) or
URL.verify(request, user_signature=user_signature,
hash_vars=False) or
- (request.args(len(args))=='view' and not logged)):
+ (request.args(len(args))=='view' and not logged)):
session.flash = T('not authorized')
redirect(referrer)
@@ -2096,8 +2104,8 @@ class SQLFORM(FORM):
else:
fields = []
columns = []
- filter1 = lambda f:isinstance(f, Field)
- filter2 = lambda f:isinstance(f, Field) and f.readable
+ filter1 = lambda f: isinstance(f, Field)
+ filter2 = lambda f: isinstance(f, Field) and f.readable
for table in tables:
fields += filter(filter1, table)
columns += filter(filter2, table)
@@ -2111,15 +2119,18 @@ class SQLFORM(FORM):
if groupby is None:
field_id = tables[0]._id
elif groupby and isinstance(groupby, Field):
- field_id = groupby #take the field passed as groupby
+ #take the field passed as groupby
+ field_id = groupby
elif groupby and isinstance(groupby, Expression):
- field_id = groupby.first #take the first groupby field
- while not(isinstance(field_id, Field)): # Navigate to the first Field of the expression
+ #take the first groupby field
+ field_id = groupby.first
+ while not(isinstance(field_id, Field)):
+ # Navigate to the first Field of the expression
field_id = field_id.first
table = field_id.table
tablename = table._tablename
if not any(str(f) == str(field_id) for f in fields):
- fields = [f for f in fields]+[field_id]
+ fields = [f for f in fields] + [field_id]
if upload == '':
upload = lambda filename: url(args=['download', filename])
if request.args(-2) == 'download':
@@ -2283,8 +2294,10 @@ class SQLFORM(FORM):
expcolumns = [str(f) for f in columns]
selectable_columns = [str(f) for f in columns if not isinstance(f, Field.Virtual)]
if export_type.endswith('with_hidden_cols'):
- #expcolumns = [] start with the visible columns, which includes visible virtual fields
- selectable_columns = [] #like expcolumns but excluding virtual
+ # expcolumns = [] start with the visible columns, which
+ # includes visible virtual fields
+ selectable_columns = []
+ #like expcolumns but excluding virtual
for table in tables:
for field in table:
if field.readable and field.tablename in tablenames:
@@ -2292,19 +2305,21 @@ class SQLFORM(FORM):
expcolumns.append(str(field))
if not(isinstance(field, Field.Virtual)):
selectable_columns.append(str(field))
- #look for virtual fields not displayed (and virtual method fields to be added here?)
+ #look for virtual fields not displayed (and virtual method
+ #fields to be added here?)
for (field_name, field) in table.iteritems():
if isinstance(field, Field.Virtual) and not str(field) in expcolumns:
expcolumns.append(str(field))
if export_type in exportManager and exportManager[export_type]:
- if request.vars.keywords:
+ if keywords:
try:
- #the query should be constructed using searchable fields but not virtual fields
+ #the query should be constructed using searchable
+ #fields but not virtual fields
sfields = reduce(lambda a, b: a + b,
[[f for f in t if f.readable and not isinstance(f, Field.Virtual)] for t in tables])
dbset = dbset(SQLFORM.build_query(
- sfields, request.vars.get('keywords', '')))
+ sfields, keywords))
rows = dbset.select(left=left, orderby=orderby,
cacheable=True, *selectable_columns)
except Exception, e:
@@ -2316,7 +2331,8 @@ class SQLFORM(FORM):
value = exportManager[export_type]
clazz = value[0] if hasattr(value, '__getitem__') else value
- rows.colnames = expcolumns # expcolumns is all cols to be exported including virtual fields
+ # expcolumns is all cols to be exported including virtual fields
+ rows.colnames = expcolumns
oExp = clazz(rows)
filename = '.'.join(('rows', oExp.file_ext))
response.headers['Content-Type'] = oExp.content_type
@@ -2330,8 +2346,7 @@ class SQLFORM(FORM):
elif not request.vars.records:
request.vars.records = []
- session['_web2py_grid_referrer_' + formname] = \
- url2(vars=request.get_vars)
+ session['_web2py_grid_referrer_' + formname] = url2(vars=request.get_vars)
console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
error = None
if create:
@@ -2357,7 +2372,7 @@ class SQLFORM(FORM):
sfields_id = '%s_query_panel' % prefix
skeywords_id = '%s_keywords' % prefix
search_widget = lambda sfield, url: CAT(FORM(
- INPUT(_name='keywords', _value=request.vars.keywords,
+ INPUT(_name='keywords', _value=keywords,
_id=skeywords_id,_class='form-control',
_onfocus="jQuery('#%s').change();jQuery('#%s').slideDown();" % (spanel_id, sfields_id) if advanced_search else ''
),
@@ -2368,7 +2383,6 @@ class SQLFORM(FORM):
form = search_widget and search_widget(sfields, url()) or ''
console.append(add)
console.append(form)
- keywords = request.vars.get('keywords', '')
try:
if callable(searchable):
subquery = searchable(sfields, keywords)
@@ -2428,7 +2442,7 @@ class SQLFORM(FORM):
elif key == ordermatch[1:]:
marker = sorter_icons[1]
header = A(header, marker, _href=url(vars=dict(
- keywords=request.vars.keywords or '',
+ keywords=keywords,
order=key)), cid=request.cid)
headcols.append(TH(header, _class=ui.get('default')))
@@ -2466,17 +2480,22 @@ class SQLFORM(FORM):
if paginate and dbset._db._adapter.dbengine == 'google:datastore':
cursor = request.vars.cursor or True
limitby = (0, paginate)
- try: page = int(request.vars.page or 1)-1
- except ValueError: page = 0
- elif paginate and paginate NPAGES + 1:
@@ -2660,7 +2691,8 @@ class SQLFORM(FORM):
_style='width:100%;overflow-x:auto;-ms-overflow-x:scroll')
if selectable:
if not callable(selectable):
- #now expect that selectable and related parameters are iterator (list, tuple, etc)
+ #now expect that selectable and related parameters are
+ #iterator (list, tuple, etc)
inputs = []
for i, submit_info in enumerate(selectable):
submit_text = submit_info[0]
@@ -2708,7 +2740,7 @@ class SQLFORM(FORM):
link = url2(vars=dict(
order=request.vars.order or '',
_export_type=k,
- keywords=request.vars.keywords or ''))
+ keywords=keywords or ''))
export_links.append(A(T(label), _href=link, _title=title, _class='btn btn-default'))
export_menu = \
DIV(T('Export:'), _class="w2p_export_menu", *export_links)
@@ -2797,7 +2829,7 @@ class SQLFORM(FORM):
elif callable(table._format):
return table._format(row)
else:
- return '#'+str(row.id)
+ return '#' + str(row.id)
try:
nargs = len(args) + 1
previous_tablename, previous_fieldname, previous_id = \
@@ -2876,7 +2908,7 @@ class SQLFORM(FORM):
opts = [OPTION(T('References')+':', _value='')]
linked = []
if linked_tables:
- for item in linked_tables:
+ for item in linked_tables:
tb = None
if isinstance(item, Table) and item._tablename in check:
tablename = item._tablename