Add "Save Defaults" button so user can save personal defaults for any new grid.
This commit is contained in:
parent
d57f5169b0
commit
2b1bdec2f8
|
@ -26,10 +26,13 @@ Core Grid Classes
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from rattail.db.api import get_setting, save_setting
|
||||||
|
|
||||||
from pyramid.renderers import render
|
from pyramid.renderers import render
|
||||||
from webhelpers.html import HTML, tags
|
from webhelpers.html import HTML, tags
|
||||||
from webhelpers.html.builder import format_attrs
|
from webhelpers.html.builder import format_attrs
|
||||||
|
|
||||||
|
from tailbone.db import Session
|
||||||
from tailbone.newgrids import filters
|
from tailbone.newgrids import filters
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +158,10 @@ class Grid(object):
|
||||||
settings['filter.{0}.verb'.format(filtr.key)] = filtr.default_verb
|
settings['filter.{0}.verb'.format(filtr.key)] = filtr.default_verb
|
||||||
settings['filter.{0}.value'.format(filtr.key)] = filtr.default_value
|
settings['filter.{0}.value'.format(filtr.key)] = filtr.default_value
|
||||||
|
|
||||||
|
# If user has default settings on file, apply those first.
|
||||||
|
if self.user_has_defaults():
|
||||||
|
self.apply_user_defaults(settings)
|
||||||
|
|
||||||
# If request contains instruction to reset to default filters, then we
|
# If request contains instruction to reset to default filters, then we
|
||||||
# can skip the rest of the request/session checks.
|
# can skip the rest of the request/session checks.
|
||||||
if self.request.GET.get('reset-to-default-filters') == 'true':
|
if self.request.GET.get('reset-to-default-filters') == 'true':
|
||||||
|
@ -200,7 +207,12 @@ class Grid(object):
|
||||||
|
|
||||||
# Maybe store settings for next time.
|
# Maybe store settings for next time.
|
||||||
if store:
|
if store:
|
||||||
self.store_settings(settings)
|
self.persist_settings(settings, 'session')
|
||||||
|
|
||||||
|
# If request contained instruction to save current settings as defaults
|
||||||
|
# for the current user, then do that.
|
||||||
|
if self.request.GET.get('save-current-filters-as-defaults') == 'true':
|
||||||
|
self.persist_settings(settings, 'defaults')
|
||||||
|
|
||||||
# Update ourself and our filters, to reflect settings.
|
# Update ourself and our filters, to reflect settings.
|
||||||
if self.filterable:
|
if self.filterable:
|
||||||
|
@ -215,6 +227,37 @@ class Grid(object):
|
||||||
self.pagesize = settings['pagesize']
|
self.pagesize = settings['pagesize']
|
||||||
self.page = settings['page']
|
self.page = settings['page']
|
||||||
|
|
||||||
|
def user_has_defaults(self):
|
||||||
|
"""
|
||||||
|
Check to see if the current user has default settings on file for this grid.
|
||||||
|
"""
|
||||||
|
# User defaults should have all or nothing, so just check one key.
|
||||||
|
key = 'tailbone.{0}.grid.{1}.sortkey'.format(self.request.user.uuid, self.key)
|
||||||
|
return get_setting(Session(), key) is not None
|
||||||
|
|
||||||
|
def apply_user_defaults(self, settings):
|
||||||
|
"""
|
||||||
|
Update the given settings dict with user defaults, if any exist.
|
||||||
|
"""
|
||||||
|
def merge(key, coerce=lambda v: v):
|
||||||
|
skey = 'tailbone.{0}.grid.{1}.{2}'.format(self.request.user.uuid, self.key, key)
|
||||||
|
value = get_setting(Session(), skey)
|
||||||
|
settings[key] = coerce(value)
|
||||||
|
|
||||||
|
if self.filterable:
|
||||||
|
for filtr in self.iter_filters():
|
||||||
|
merge('filter.{0}.active'.format(filtr.key), lambda v: v == 'true')
|
||||||
|
merge('filter.{0}.verb'.format(filtr.key))
|
||||||
|
merge('filter.{0}.value'.format(filtr.key))
|
||||||
|
|
||||||
|
if self.sortable:
|
||||||
|
merge('sortkey')
|
||||||
|
merge('sortdir')
|
||||||
|
|
||||||
|
if self.pageable:
|
||||||
|
merge('pagesize', int)
|
||||||
|
merge('page', int)
|
||||||
|
|
||||||
def request_has_settings(self, type_):
|
def request_has_settings(self, type_):
|
||||||
"""
|
"""
|
||||||
Determine if the current request (GET query string) contains any
|
Determine if the current request (GET query string) contains any
|
||||||
|
@ -266,7 +309,7 @@ class Grid(object):
|
||||||
else:
|
else:
|
||||||
value = self.request.session.get('grid.{0}.{1}'.format(self.key, key))
|
value = self.request.session.get('grid.{0}.{1}'.format(self.key, key))
|
||||||
if value is not None:
|
if value is not None:
|
||||||
return value
|
return coerce(value)
|
||||||
|
|
||||||
# If source had nothing, try default/existing settings.
|
# If source had nothing, try default/existing settings.
|
||||||
value = settings.get(key)
|
value = settings.get(key)
|
||||||
|
@ -307,7 +350,8 @@ class Grid(object):
|
||||||
|
|
||||||
else: # source = session
|
else: # source = session
|
||||||
settings['{0}.active'.format(prefix)] = self.get_setting(
|
settings['{0}.active'.format(prefix)] = self.get_setting(
|
||||||
source, settings, '{0}.active'.format(prefix), default=False)
|
source, settings, '{0}.active'.format(prefix),
|
||||||
|
coerce=lambda v: unicode(v).lower() == 'true', default=False)
|
||||||
settings['{0}.verb'.format(prefix)] = self.get_setting(
|
settings['{0}.verb'.format(prefix)] = self.get_setting(
|
||||||
source, settings, '{0}.verb'.format(prefix), default='')
|
source, settings, '{0}.verb'.format(prefix), default='')
|
||||||
settings['{0}.value'.format(prefix)] = self.get_setting(
|
settings['{0}.value'.format(prefix)] = self.get_setting(
|
||||||
|
@ -361,26 +405,31 @@ class Grid(object):
|
||||||
if page is not None:
|
if page is not None:
|
||||||
settings['page'] = page
|
settings['page'] = page
|
||||||
|
|
||||||
def store_settings(self, settings):
|
def persist_settings(self, settings, to='session'):
|
||||||
"""
|
"""
|
||||||
Store settings in current session, for next time.
|
Persist the given settings in some way, as defined by ``func``.
|
||||||
"""
|
"""
|
||||||
def store(key):
|
def persist(key, value=lambda k: settings[k]):
|
||||||
self.request.session['grid.{0}.{1}'.format(self.key, key)] = settings[key]
|
if to == 'defaults':
|
||||||
|
skey = 'tailbone.{0}.grid.{1}.{2}'.format(self.request.user.uuid, self.key, key)
|
||||||
|
save_setting(Session(), skey, value(key))
|
||||||
|
else: # to == session
|
||||||
|
skey = 'grid.{0}.{1}'.format(self.key, key)
|
||||||
|
self.request.session[skey] = value(key)
|
||||||
|
|
||||||
if self.filterable:
|
if self.filterable:
|
||||||
for filtr in self.iter_filters():
|
for filtr in self.iter_filters():
|
||||||
store('filter.{0}.active'.format(filtr.key))
|
persist('filter.{0}.active'.format(filtr.key), value=lambda k: unicode(settings[k]).lower())
|
||||||
store('filter.{0}.verb'.format(filtr.key))
|
persist('filter.{0}.verb'.format(filtr.key))
|
||||||
store('filter.{0}.value'.format(filtr.key))
|
persist('filter.{0}.value'.format(filtr.key))
|
||||||
|
|
||||||
if self.sortable:
|
if self.sortable:
|
||||||
store('sortkey')
|
persist('sortkey')
|
||||||
store('sortdir')
|
persist('sortdir')
|
||||||
|
|
||||||
if self.pageable:
|
if self.pageable:
|
||||||
store('pagesize')
|
persist('pagesize')
|
||||||
store('page')
|
persist('page')
|
||||||
|
|
||||||
def filter_data(self, data):
|
def filter_data(self, data):
|
||||||
"""
|
"""
|
||||||
|
|
32
tailbone/static/js/jquery.ui.tailbone.js
vendored
32
tailbone/static/js/jquery.ui.tailbone.js
vendored
|
@ -17,10 +17,12 @@
|
||||||
|
|
||||||
// Snag some element references.
|
// Snag some element references.
|
||||||
this.filters = this.element.find('.newfilters');
|
this.filters = this.element.find('.newfilters');
|
||||||
|
this.filters_form = this.filters.find('form');
|
||||||
this.add_filter = this.filters.find('#add-filter');
|
this.add_filter = this.filters.find('#add-filter');
|
||||||
this.apply_filters = this.filters.find('#apply-filters');
|
this.apply_filters = this.filters.find('#apply-filters');
|
||||||
this.default_filters = this.filters.find('#default-filters');
|
this.default_filters = this.filters.find('#default-filters');
|
||||||
this.clear_filters = this.filters.find('#clear-filters');
|
this.clear_filters = this.filters.find('#clear-filters');
|
||||||
|
this.save_defaults = this.filters.find('#save-defaults');
|
||||||
this.grid = this.element.find('.newgrid');
|
this.grid = this.element.find('.newgrid');
|
||||||
|
|
||||||
// Enhance filters etc.
|
// Enhance filters etc.
|
||||||
|
@ -28,6 +30,7 @@
|
||||||
this.apply_filters.button('option', 'icons', {primary: 'ui-icon-search'});
|
this.apply_filters.button('option', 'icons', {primary: 'ui-icon-search'});
|
||||||
this.default_filters.button('option', 'icons', {primary: 'ui-icon-home'});
|
this.default_filters.button('option', 'icons', {primary: 'ui-icon-home'});
|
||||||
this.clear_filters.button('option', 'icons', {primary: 'ui-icon-trash'});
|
this.clear_filters.button('option', 'icons', {primary: 'ui-icon-trash'});
|
||||||
|
this.save_defaults.button('option', 'icons', {primary: 'ui-icon-disk'});
|
||||||
if (! this.filters.find('.active:checked').length) {
|
if (! this.filters.find('.active:checked').length) {
|
||||||
this.apply_filters.button('disable');
|
this.apply_filters.button('disable');
|
||||||
}
|
}
|
||||||
|
@ -56,11 +59,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// Intercept filters form submittal, and submit via AJAX instead.
|
// Intercept filters form submittal, and submit via AJAX instead.
|
||||||
this.filters.find('form').on('submit', function() {
|
this.filters_form.on('submit', function() {
|
||||||
var form = $(this);
|
|
||||||
|
|
||||||
var settings = {filter: true, partial: true};
|
var settings = {filter: true, partial: true};
|
||||||
form.find('.filter').each(function() {
|
if (that.filters_form.find('input[name="save-current-filters-as-defaults"]').val() == 'true') {
|
||||||
|
settings['save-current-filters-as-defaults'] = true;
|
||||||
|
}
|
||||||
|
that.filters.find('.filter').each(function() {
|
||||||
|
|
||||||
// currently active filters will be included in form data
|
// currently active filters will be included in form data
|
||||||
if ($(this).gridfilter('active')) {
|
if ($(this).gridfilter('active')) {
|
||||||
|
@ -74,7 +78,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// if no filters are visible, disable submit button
|
// if no filters are visible, disable submit button
|
||||||
if (! form.find('.filter:visible').length) {
|
if (! that.filters.find('.filter:visible').length) {
|
||||||
that.apply_filters.button('disable');
|
that.apply_filters.button('disable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,11 +90,19 @@
|
||||||
// When user clicks Default Filters button, refresh page with
|
// When user clicks Default Filters button, refresh page with
|
||||||
// instructions for the server to reset filters to default settings.
|
// instructions for the server to reset filters to default settings.
|
||||||
this.default_filters.click(function() {
|
this.default_filters.click(function() {
|
||||||
var form = that.filters.find('form');
|
that.filters_form.off('submit');
|
||||||
form.off('submit');
|
that.filters_form.find('input[name="reset-to-default-filters"]').val('true');
|
||||||
form.append('<input type="hidden" name="reset-to-default-filters" value="true" />');
|
|
||||||
that.element.mask("Refreshing data...");
|
that.element.mask("Refreshing data...");
|
||||||
form.submit();
|
that.filters_form.submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// When user clicks Save Defaults button, refresh the grid as with
|
||||||
|
// Apply Filters, but add an instruction for the server to save
|
||||||
|
// current settings as defaults for the user.
|
||||||
|
this.save_defaults.click(function() {
|
||||||
|
that.filters_form.find('input[name="save-current-filters-as-defaults"]').val('true');
|
||||||
|
that.filters_form.submit();
|
||||||
|
that.filters_form.find('input[name="save-current-filters-as-defaults"]').val('false');
|
||||||
});
|
});
|
||||||
|
|
||||||
// When user clicks Clear Filters button, deactivate all filters
|
// When user clicks Clear Filters button, deactivate all filters
|
||||||
|
@ -101,7 +113,7 @@
|
||||||
$(this).gridfilter('active', false);
|
$(this).gridfilter('active', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
that.filters.find('form').submit();
|
that.filters_form.submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh data when user clicks a sortable column header.
|
// Refresh data when user clicks a sortable column header.
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
<div class="newfilters">
|
<div class="newfilters">
|
||||||
|
|
||||||
${form.begin(method='get')}
|
${form.begin(method='get')}
|
||||||
|
<input type="hidden" name="reset-to-default-filters" value="false" />
|
||||||
|
<input type="hidden" name="save-current-filters-as-defaults" value="false" />
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Filters</legend>
|
<legend>Filters</legend>
|
||||||
|
@ -27,6 +29,7 @@
|
||||||
</select>
|
</select>
|
||||||
${form.tag('button', type='button', id='default-filters', c="Default Filters")}
|
${form.tag('button', type='button', id='default-filters', c="Default Filters")}
|
||||||
${form.tag('button', type='button', id='clear-filters', c="Clear Filters")}
|
${form.tag('button', type='button', id='clear-filters', c="Clear Filters")}
|
||||||
|
${form.tag('button', type='button', id='save-defaults', c="Save Defaults")}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${form.end()}
|
${form.end()}
|
||||||
|
|
Loading…
Reference in a new issue