many improvements to grid, thanks Paolo
This commit is contained in:
+1
-1
Submodule gluon/packages/dal updated: dda7c65dd7...8b5085ac31
+38
-28
@@ -2322,7 +2322,7 @@ class SQLFORM(FORM):
|
|||||||
create = wenabled and create
|
create = wenabled and create
|
||||||
editable = wenabled and editable
|
editable = wenabled and editable
|
||||||
deletable = wenabled and deletable
|
deletable = wenabled and deletable
|
||||||
details = details and not groupby
|
details = not groupby and details
|
||||||
rows = None
|
rows = None
|
||||||
|
|
||||||
# see issue 1980. Basically we can have keywords in get_vars
|
# see issue 1980. Basically we can have keywords in get_vars
|
||||||
@@ -2385,6 +2385,12 @@ class SQLFORM(FORM):
|
|||||||
b['args'] = args + b.get('args', [])
|
b['args'] = args + b.get('args', [])
|
||||||
localvars = request.get_vars.copy()
|
localvars = request.get_vars.copy()
|
||||||
localvars.update(b.get('vars', {}))
|
localvars.update(b.get('vars', {}))
|
||||||
|
# avoid empty keywords in vars
|
||||||
|
if localvars.get('keywords') == '':
|
||||||
|
del localvars['keywords']
|
||||||
|
# avoid propagating order=None in vars
|
||||||
|
if localvars.get('order') == 'None':
|
||||||
|
del localvars['order']
|
||||||
b['vars'] = localvars
|
b['vars'] = localvars
|
||||||
b['hash_vars'] = False
|
b['hash_vars'] = False
|
||||||
b['user_signature'] = user_signature
|
b['user_signature'] = user_signature
|
||||||
@@ -2414,7 +2420,7 @@ class SQLFORM(FORM):
|
|||||||
|
|
||||||
def gridbutton(buttonclass='buttonadd', buttontext=T('Add'),
|
def gridbutton(buttonclass='buttonadd', buttontext=T('Add'),
|
||||||
buttonurl=url(args=[]), callback=None,
|
buttonurl=url(args=[]), callback=None,
|
||||||
delete=None, trap=True, noconfirm=None, title=None):
|
delete=None, noconfirm=None, title=None):
|
||||||
if showbuttontext:
|
if showbuttontext:
|
||||||
return A(SPAN(_class=ui.get(buttonclass)), CAT(' '),
|
return A(SPAN(_class=ui.get(buttonclass)), CAT(' '),
|
||||||
SPAN(T(buttontext), _title=title or T(buttontext),
|
SPAN(T(buttontext), _title=title or T(buttontext),
|
||||||
@@ -2645,20 +2651,18 @@ class SQLFORM(FORM):
|
|||||||
|
|
||||||
orderby = fix_orderby(orderby)
|
orderby = fix_orderby(orderby)
|
||||||
|
|
||||||
|
# expcolumns start with the visible columns, which
|
||||||
|
# includes visible virtual fields
|
||||||
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
|
|
||||||
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:
|
||||||
if not str(field) in expcolumns:
|
if not str(field) in expcolumns:
|
||||||
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
|
# look for virtual fields not displayed (and virtual method
|
||||||
# fields to be added here?)
|
# fields to be added here?)
|
||||||
for (field_name, field) in iteritems(table):
|
for (field_name, field) in iteritems(table):
|
||||||
@@ -2723,7 +2727,7 @@ class SQLFORM(FORM):
|
|||||||
|
|
||||||
if searchable:
|
if searchable:
|
||||||
sfields = reduce(lambda a, b: a + b,
|
sfields = reduce(lambda a, b: a + b,
|
||||||
[[f for f in t if f.readable] for t in tables])
|
[[f for f in t if f.readable and f.searchable] for t in tables])
|
||||||
if isinstance(search_widget, dict):
|
if isinstance(search_widget, dict):
|
||||||
search_widget = search_widget[tablename]
|
search_widget = search_widget[tablename]
|
||||||
if search_widget == 'default':
|
if search_widget == 'default':
|
||||||
@@ -2732,7 +2736,7 @@ class SQLFORM(FORM):
|
|||||||
spanel_id = '%s_query_fields' % prefix
|
spanel_id = '%s_query_fields' % prefix
|
||||||
sfields_id = '%s_query_panel' % prefix
|
sfields_id = '%s_query_panel' % prefix
|
||||||
skeywords_id = '%s_keywords' % prefix
|
skeywords_id = '%s_keywords' % prefix
|
||||||
# hidden fields to presever keywords in url after the submit
|
# hidden fields to preserve keywords in url after the submit
|
||||||
hidden_fields = [INPUT(_type='hidden', _value=v, _name=k) for k, v in request.get_vars.items() if k not in ['keywords', 'page']]
|
hidden_fields = [INPUT(_type='hidden', _value=v, _name=k) for k, v in request.get_vars.items() if k not in ['keywords', 'page']]
|
||||||
search_widget = lambda sfield, url: CAT(FORM(
|
search_widget = lambda sfield, url: CAT(FORM(
|
||||||
INPUT(_name='keywords', _value=keywords,
|
INPUT(_name='keywords', _value=keywords,
|
||||||
@@ -2748,14 +2752,17 @@ 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)
|
||||||
try:
|
if keywords:
|
||||||
if callable(searchable):
|
try:
|
||||||
subquery = searchable(sfields, keywords)
|
if callable(searchable):
|
||||||
else:
|
subquery = searchable(sfields, keywords)
|
||||||
subquery = SQLFORM.build_query(sfields, keywords)
|
else:
|
||||||
except RuntimeError:
|
subquery = SQLFORM.build_query(sfields, keywords)
|
||||||
|
except RuntimeError:
|
||||||
|
subquery = None
|
||||||
|
error = T('Invalid query')
|
||||||
|
else:
|
||||||
subquery = None
|
subquery = None
|
||||||
error = T('Invalid query')
|
|
||||||
else:
|
else:
|
||||||
subquery = None
|
subquery = None
|
||||||
|
|
||||||
@@ -2768,12 +2775,15 @@ class SQLFORM(FORM):
|
|||||||
error = T('Unsupported query')
|
error = T('Unsupported query')
|
||||||
|
|
||||||
order = request.vars.order or ''
|
order = request.vars.order or ''
|
||||||
|
asc_icon, desc_icon = sorter_icons
|
||||||
if sortable:
|
if sortable:
|
||||||
if order and not order == 'None':
|
if order and not order == 'None':
|
||||||
otablename, ofieldname = order.split('~')[-1].split('.', 1)
|
otablename, ofieldname = order.split('~')[-1].split('.', 1)
|
||||||
sort_field = db[otablename][ofieldname]
|
sort_field = db[otablename][ofieldname]
|
||||||
|
# invert order direction on date/time fields
|
||||||
exception = sort_field.type in ('date', 'datetime', 'time')
|
exception = sort_field.type in ('date', 'datetime', 'time')
|
||||||
if exception:
|
if exception:
|
||||||
|
desc_icon, asc_icon = sorter_icons
|
||||||
orderby = (order[:1] == '~' and sort_field) or ~sort_field
|
orderby = (order[:1] == '~' and sort_field) or ~sort_field
|
||||||
else:
|
else:
|
||||||
orderby = (order[:1] == '~' and ~sort_field) or sort_field
|
orderby = (order[:1] == '~' and ~sort_field) or sort_field
|
||||||
@@ -2782,30 +2792,30 @@ class SQLFORM(FORM):
|
|||||||
if selectable:
|
if selectable:
|
||||||
headcols.append(TH(_class=ui.get('default')))
|
headcols.append(TH(_class=ui.get('default')))
|
||||||
|
|
||||||
ordermatch, marker = orderby, ''
|
ordermatch = orderby; marker = ''
|
||||||
if orderby:
|
if orderby:
|
||||||
# if orderby is a single column, remember to put the marker
|
# if orderby is a single column, remember to put the marker
|
||||||
if isinstance(orderby, Expression):
|
if isinstance(orderby, Expression):
|
||||||
if orderby.first and not orderby.second:
|
if orderby.first and not orderby.second:
|
||||||
ordermatch, marker = orderby.first, '~'
|
ordermatch = orderby.first; marker = '~'
|
||||||
ordermatch = marker + str(ordermatch)
|
ordermatch = marker + str(ordermatch)
|
||||||
for field in columns:
|
for field in columns:
|
||||||
if not field.readable:
|
if not field.readable:
|
||||||
continue
|
continue
|
||||||
key = str(field)
|
key = str(field)
|
||||||
header = headers.get(str(field), field.label or key)
|
header = headers.get(key, field.label or key)
|
||||||
if sortable and not isinstance(field, Field.Virtual):
|
if sortable and not isinstance(field, Field.Virtual):
|
||||||
marker = ''
|
marker = ''
|
||||||
if order:
|
if order:
|
||||||
if key == order:
|
if key == order:
|
||||||
key, marker = '~' + order, sorter_icons[0]
|
key = '~' + order; marker = asc_icon
|
||||||
elif key == order[1:]:
|
elif key == order[1:]:
|
||||||
marker = sorter_icons[1]
|
key = 'None'; marker = desc_icon
|
||||||
else:
|
else:
|
||||||
if key == ordermatch:
|
if key == ordermatch:
|
||||||
key, marker = '~' + ordermatch, sorter_icons[0]
|
key = '~' + ordermatch; marker = asc_icon
|
||||||
elif key == ordermatch[1:]:
|
elif key == ordermatch[1:]:
|
||||||
marker = sorter_icons[1]
|
marker = desc_icon
|
||||||
header = A(header, marker, _href=url(vars=dict(
|
header = A(header, marker, _href=url(vars=dict(
|
||||||
keywords=keywords,
|
keywords=keywords,
|
||||||
order=key)), cid=request.cid)
|
order=key)), cid=request.cid)
|
||||||
@@ -3114,7 +3124,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=keywords or ''))
|
keywords=keywords))
|
||||||
export_links.append(A(T(label), _href=link, _title=title, _class='btn btn-default btn-secondary'))
|
export_links.append(A(T(label), _href=link, _title=title, _class='btn btn-default btn-secondary'))
|
||||||
export_menu = \
|
export_menu = \
|
||||||
DIV(T('Export:'), _class="w2p_export_menu", *export_links)
|
DIV(T('Export:'), _class="w2p_export_menu", *export_links)
|
||||||
@@ -3697,7 +3707,7 @@ class ExporterTSV(ExportClass):
|
|||||||
def __init__(self, rows):
|
def __init__(self, rows):
|
||||||
ExportClass.__init__(self, rows)
|
ExportClass.__init__(self, rows)
|
||||||
|
|
||||||
def export(self): # export TSV with rows.represent
|
def export(self): # export TSV with field.represent
|
||||||
if self.rows:
|
if self.rows:
|
||||||
s = StringIO()
|
s = StringIO()
|
||||||
self.rows.export_to_csv_file(s, represent=True,delimiter='\t',newline='\n')
|
self.rows.export_to_csv_file(s, represent=True,delimiter='\t',newline='\n')
|
||||||
@@ -3714,7 +3724,7 @@ class ExporterTSV_hidden(ExportClass):
|
|||||||
def __init__(self, rows):
|
def __init__(self, rows):
|
||||||
ExportClass.__init__(self, rows)
|
ExportClass.__init__(self, rows)
|
||||||
|
|
||||||
def export(self): # export TSV with rows.represent
|
def export(self):
|
||||||
if self.rows:
|
if self.rows:
|
||||||
s = StringIO()
|
s = StringIO()
|
||||||
self.rows.export_to_csv_file(s,delimiter='\t',newline='\n')
|
self.rows.export_to_csv_file(s,delimiter='\t',newline='\n')
|
||||||
@@ -3732,7 +3742,7 @@ class ExporterCSV(ExportClass):
|
|||||||
def __init__(self, rows):
|
def __init__(self, rows):
|
||||||
ExportClass.__init__(self, rows)
|
ExportClass.__init__(self, rows)
|
||||||
|
|
||||||
def export(self): # export CSV with rows.represent
|
def export(self): # export CSV with field.represent
|
||||||
if self.rows:
|
if self.rows:
|
||||||
s = StringIO()
|
s = StringIO()
|
||||||
self.rows.export_to_csv_file(s, represent=True)
|
self.rows.export_to_csv_file(s, represent=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user