Refactor grid filters to use colander/deform
This commit is contained in:
parent
f636b98cb3
commit
d9ff59afda
|
@ -898,11 +898,13 @@ class Grid(object):
|
||||||
data['{}.verb'.format(filtr.key)] = filtr.verb
|
data['{}.verb'.format(filtr.key)] = filtr.verb
|
||||||
data[filtr.key] = filtr.value
|
data[filtr.key] = filtr.value
|
||||||
|
|
||||||
form = gridfilters.GridFiltersForm(self.request, self.filters, defaults=data)
|
form = gridfilters.GridFiltersForm(self.filters,
|
||||||
|
request=self.request,
|
||||||
|
defaults=data)
|
||||||
|
|
||||||
kwargs['request'] = self.request
|
kwargs['request'] = self.request
|
||||||
kwargs['grid'] = self
|
kwargs['grid'] = self
|
||||||
kwargs['form'] = gridfilters.GridFiltersFormRenderer(form)
|
kwargs['form'] = form
|
||||||
return render(template, kwargs)
|
return render(template, kwargs)
|
||||||
|
|
||||||
def render_actions(self, row, i):
|
def render_actions(self, row, i):
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2017 Lance Edgar
|
# Copyright © 2010-2018 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -38,10 +38,11 @@ from rattail.core import UNSPECIFIED
|
||||||
from rattail.time import localtime, make_utc
|
from rattail.time import localtime, make_utc
|
||||||
from rattail.util import prettify
|
from rattail.util import prettify
|
||||||
|
|
||||||
from pyramid_simpleform import Form
|
import colander
|
||||||
from pyramid_simpleform.renderers import FormRenderer
|
|
||||||
from webhelpers2.html import HTML, tags
|
from webhelpers2.html import HTML, tags
|
||||||
|
|
||||||
|
from tailbone import forms
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -736,58 +737,33 @@ class GridFilterSet(OrderedDict):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class GridFiltersForm(Form):
|
class GridFiltersForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
Form for grid filters.
|
Form for grid filters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, request, filters, *args, **kwargs):
|
def __init__(self, filters, **kwargs):
|
||||||
super(GridFiltersForm, self).__init__(request, *args, **kwargs)
|
|
||||||
self.filters = filters
|
self.filters = filters
|
||||||
|
if 'schema' not in kwargs:
|
||||||
|
schema = colander.Schema()
|
||||||
|
for key, filtr in self.filters.items():
|
||||||
|
node = colander.SchemaNode(colander.String(), name=key)
|
||||||
|
schema.add(node)
|
||||||
|
kwargs['schema'] = schema
|
||||||
|
super(GridFiltersForm, self).__init__(**kwargs)
|
||||||
|
|
||||||
def iter_filters(self):
|
def iter_filters(self):
|
||||||
return self.filters.itervalues()
|
return self.filters.values()
|
||||||
|
|
||||||
|
|
||||||
class GridFiltersFormRenderer(FormRenderer):
|
|
||||||
"""
|
|
||||||
Renderer for :class:`GridFiltersForm` instances.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def filters(self):
|
|
||||||
return self.form.filters
|
|
||||||
|
|
||||||
def iter_filters(self):
|
|
||||||
return self.form.iter_filters()
|
|
||||||
|
|
||||||
def tag(self, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Convenience method which passes all args to the
|
|
||||||
:meth:`webhelpers2:webhelpers2.html.builder.HTMLBuilder.tag()` method.
|
|
||||||
"""
|
|
||||||
return HTML.tag(*args, **kwargs)
|
|
||||||
|
|
||||||
# TODO: This seems hacky..?
|
|
||||||
def checkbox(self, name, checked=None, **kwargs):
|
|
||||||
"""
|
|
||||||
Custom checkbox implementation.
|
|
||||||
"""
|
|
||||||
if name.endswith('-active'):
|
|
||||||
return tags.checkbox(name, checked=checked, **kwargs)
|
|
||||||
if checked is None:
|
|
||||||
checked = False
|
|
||||||
return super(GridFiltersFormRenderer, self).checkbox(name, checked=checked, **kwargs)
|
|
||||||
|
|
||||||
def filter_verb(self, filtr):
|
def filter_verb(self, filtr):
|
||||||
"""
|
"""
|
||||||
Render the verb selection dropdown for the given filter.
|
Render the verb selection dropdown for the given filter.
|
||||||
"""
|
"""
|
||||||
options = [(v, filtr.verb_labels.get(v, "unknown verb '{0}'".format(v)))
|
options = [tags.Option(filtr.verb_labels.get(v, "unknown verb '{}'".format(v)), v)
|
||||||
for v in filtr.verbs]
|
for v in filtr.verbs]
|
||||||
hide_values = [v for v in filtr.valueless_verbs
|
hide_values = [v for v in filtr.valueless_verbs
|
||||||
if v in filtr.verbs]
|
if v in filtr.verbs]
|
||||||
return self.select('{0}.verb'.format(filtr.key), options, **{
|
return tags.select('{}.verb'.format(filtr.key), filtr.verb, options, **{
|
||||||
'class_': 'verb',
|
'class_': 'verb',
|
||||||
'data-hide-value-for': ' '.join(hide_values)})
|
'data-hide-value-for': ' '.join(hide_values)})
|
||||||
|
|
||||||
|
|
29
tailbone/static/js/jquery.ui.tailbone.js
vendored
29
tailbone/static/js/jquery.ui.tailbone.js
vendored
|
@ -27,6 +27,11 @@
|
||||||
|
|
||||||
// do some extra stuff for grids with checkboxes
|
// do some extra stuff for grids with checkboxes
|
||||||
|
|
||||||
|
// mark rows selected on page load, as needed
|
||||||
|
this.element.find('tr:not(.header) td.checkbox :checkbox:checked').each(function() {
|
||||||
|
$(this).parents('tr:first').addClass('selected');
|
||||||
|
});
|
||||||
|
|
||||||
// (un-)check all rows when clicking check-all box in header
|
// (un-)check all rows when clicking check-all box in header
|
||||||
if (this.element.find('tr.header td.checkbox :checkbox').length) {
|
if (this.element.find('tr.header td.checkbox :checkbox').length) {
|
||||||
this.element.on('click', 'tr.header td.checkbox :checkbox', function() {
|
this.element.on('click', 'tr.header td.checkbox :checkbox', function() {
|
||||||
|
@ -81,7 +86,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
count_selected: function() {
|
count_selected: function() {
|
||||||
return this.element.find('tr:not(.header) td.checkbox input:checked').length;
|
return this.element.find('tr:not(.header) td.checkbox :checkbox:checked').length;
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: deprecate / remove this?
|
// TODO: deprecate / remove this?
|
||||||
|
@ -89,9 +94,21 @@
|
||||||
return this.count_selected();
|
return this.count_selected();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
selected_rows: function() {
|
||||||
|
return this.element.find('tr:not(.header) td.checkbox :checkbox:checked').parents('tr:first');
|
||||||
|
},
|
||||||
|
|
||||||
|
all_uuids: function() {
|
||||||
|
var uuids = [];
|
||||||
|
this.element.find('tr:not(.header)').each(function() {
|
||||||
|
uuids.push($(this).data('uuid'));
|
||||||
|
});
|
||||||
|
return uuids;
|
||||||
|
},
|
||||||
|
|
||||||
selected_uuids: function() {
|
selected_uuids: function() {
|
||||||
var uuids = [];
|
var uuids = [];
|
||||||
this.element.find('tr:not(.header) td.checkbox input:checked').each(function() {
|
this.element.find('tr:not(.header) td.checkbox :checkbox:checked').each(function() {
|
||||||
uuids.push($(this).parents('tr:first').data('uuid'));
|
uuids.push($(this).parents('tr:first').data('uuid'));
|
||||||
});
|
});
|
||||||
return uuids;
|
return uuids;
|
||||||
|
@ -273,6 +290,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
},
|
||||||
|
|
||||||
|
all_uuids: function() {
|
||||||
|
return this.grid.gridcore('all_uuids');
|
||||||
|
},
|
||||||
|
|
||||||
|
selected_uuids: function() {
|
||||||
|
return this.grid.gridcore('selected_uuids');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
## -*- coding: utf-8 -*-
|
## -*- coding: utf-8; -*-
|
||||||
<div class="newfilters">
|
<div class="newfilters">
|
||||||
|
|
||||||
${form.begin(method='get')}
|
${h.form(form.action_url, method='get')}
|
||||||
<input type="hidden" name="reset-to-default-filters" value="false" />
|
${h.hidden('reset-to-default-filters', value='false')}
|
||||||
<input type="hidden" name="save-current-filters-as-defaults" value="false" />
|
${h.hidden('save-current-filters-as-defaults', value='false')}
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Filters</legend>
|
<legend>Filters</legend>
|
||||||
% for filtr in form.iter_filters():
|
% for filtr in form.iter_filters():
|
||||||
<div class="filter" id="filter-${filtr.key}" data-key="${filtr.key}"${' style="display: none;"' if not filtr.active else ''|n}>
|
<div class="filter" id="filter-${filtr.key}" data-key="${filtr.key}"${' style="display: none;"' if not filtr.active else ''|n}>
|
||||||
${form.checkbox('{0}-active'.format(filtr.key), class_='active', id='filter-active-{0}'.format(filtr.key), checked=filtr.active)}
|
${h.checkbox('{}-active'.format(filtr.key), class_='active', id='filter-active-{}'.format(filtr.key), checked=filtr.active)}
|
||||||
<label for="filter-active-${filtr.key}">${filtr.label}</label>
|
<label for="filter-active-${filtr.key}">${filtr.label}</label>
|
||||||
<div class="inputs">
|
<div class="inputs">
|
||||||
${form.filter_verb(filtr)}
|
${form.filter_verb(filtr)}
|
||||||
|
@ -20,19 +20,19 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
${form.tag('button', type='submit', id='apply-filters', c="Apply Filters")}
|
<button type="submit" id="apply-filters">Apply Filters</button>
|
||||||
<select id="add-filter">
|
<select id="add-filter">
|
||||||
<option value="">Add a Filter</option>
|
<option value="">Add a Filter</option>
|
||||||
% for filtr in form.iter_filters():
|
% for filtr in form.iter_filters():
|
||||||
<option value="${filtr.key}"${' disabled="disabled"' if filtr.active else ''|n}>${filtr.label}</option>
|
<option value="${filtr.key}"${' disabled="disabled"' if filtr.active else ''|n}>${filtr.label}</option>
|
||||||
% endfor
|
% endfor
|
||||||
</select>
|
</select>
|
||||||
${form.tag('button', type='button', id='default-filters', c="Default View")}
|
<button type="button" id="default-filters">Default View</button>
|
||||||
${form.tag('button', type='button', id='clear-filters', c="No Filters")}
|
<button type="button" id="clear-filters">No Filters</button>
|
||||||
% if allow_save_defaults and request.user:
|
% if allow_save_defaults and request.user:
|
||||||
${form.tag('button', type='button', id='save-defaults', c="Save Defaults")}
|
<button type="button" id="save-defaults">Save Defaults</button>
|
||||||
% endif
|
% endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${form.end()}
|
${h.end_form()}
|
||||||
</div><!-- newfilters -->
|
</div><!-- newfilters -->
|
||||||
|
|
Loading…
Reference in a new issue