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