more template/css overhaul

This commit is contained in:
Lance Edgar 2012-08-14 13:28:39 -07:00
parent 005fca223f
commit 26ffcc865a
20 changed files with 337 additions and 580 deletions

View file

@ -44,13 +44,19 @@ __all__ = ['Grid']
class Grid(edbob.Object): class Grid(edbob.Object):
full = False
hoverable = True hoverable = True
clickable = False clickable = False
checkboxes = False checkboxes = False
deletable = False deletable = False
partial_only = False partial_only = False
row_route_name = None
row_route_kwargs = None click_route_name = None
click_route_kwargs = None
delete_route_name = None
delete_route_kwargs = None
def __init__(self, request, **kwargs): def __init__(self, request, **kwargs):
kwargs.setdefault('fields', OrderedDict()) kwargs.setdefault('fields', OrderedDict())
@ -65,23 +71,38 @@ class Grid(edbob.Object):
def column_header(self, field): def column_header(self, field):
return literal('<th field="%s">%s</th>' % (field.name, field.label)) return literal('<th field="%s">%s</th>' % (field.name, field.label))
def div_class(self):
if self.clickable:
return 'grid clickable'
if self.hoverable:
return 'grid hoverable'
return 'grid'
def _div_attrs(self):
attrs = {'class_':'grid', 'url':self.request.current_route_url()}
if self.clickable:
attrs['class_'] = 'grid clickable'
elif self.hoverable:
attrs['class_'] = 'grid hoverable'
return attrs
def div_attrs(self): def div_attrs(self):
return format_attrs(**self._div_attrs()) classes = ['grid']
if self.full:
classes.append('full')
if self.clickable:
classes.append('clickable')
if self.hoverable:
classes.append('hoverable')
return format_attrs(
class_=' '.join(classes),
url=self.request.current_route_url())
def get_delete_url(self, row):
kwargs = {}
if self.delete_route_kwargs:
if callable(self.delete_route_kwargs):
kwargs = self.delete_route_kwargs(row)
else:
kwargs = self.delete_route_kwargs
return self.request.route_url(self.delete_route_name, **kwargs)
def get_row_attrs(self, row, i):
attrs = self.row_attrs(row, i)
if self.clickable:
kwargs = {}
if self.click_route_kwargs:
if callable(self.click_route_kwargs):
kwargs = self.click_route_kwargs(row)
else:
kwargs = self.click_route_kwargs
attrs['url'] = self.request.route_url(self.click_route_name, **kwargs)
return format_attrs(**attrs)
def iter_fields(self): def iter_fields(self):
return self.fields.itervalues() return self.fields.itervalues()
@ -99,15 +120,3 @@ class Grid(edbob.Object):
def row_attrs(self, row, i): def row_attrs(self, row, i):
attrs = {'class_': 'odd' if i % 2 else 'even'} attrs = {'class_': 'odd' if i % 2 else 'even'}
return attrs return attrs
def get_row_attrs(self, row, i):
attrs = self.row_attrs(row, i)
if self.row_route_name:
kwargs = {}
if self.row_route_kwargs:
if callable(self.row_route_kwargs):
kwargs = self.row_route_kwargs(row)
else:
kwargs = self.row_route_kwargs
attrs['url'] = self.request.route_url(self.row_route_name, **kwargs)
return format_attrs(**attrs)

View file

@ -159,7 +159,7 @@ def filter_ilike(field):
return {'lk': ilike, 'nl': not_ilike} return {'lk': ilike, 'nl': not_ilike}
def get_filter_config(name, request, filter_map, **kwargs): def get_filter_config(prefix, request, filter_map, **kwargs):
""" """
Returns a configuration dictionary for a search form. Returns a configuration dictionary for a search form.
""" """
@ -191,7 +191,7 @@ def get_filter_config(name, request, filter_map, **kwargs):
config.update(kwargs) config.update(kwargs)
# Update config with data cached in session. # Update config with data cached in session.
update_config(request.session, prefix=name+'.') update_config(request.session, prefix=prefix+'.')
# Update config with data from GET/POST request. # Update config with data from GET/POST request.
if request.params.get('filters') == 'true': if request.params.get('filters') == 'true':
@ -201,7 +201,7 @@ def get_filter_config(name, request, filter_map, **kwargs):
for key in config: for key in config:
if (not key.startswith('filter_factory_') if (not key.startswith('filter_factory_')
and not key.startswith('filter_label_')): and not key.startswith('filter_label_')):
request.session[name+'.'+key] = config[key] request.session[prefix+'.'+key] = config[key]
return config return config

View file

@ -1,98 +0,0 @@
/************************************************************
* crud.css
*
* Styles specific to "object CRUD" pages.
************************************************************/
/******************************
* Wrapper
******************************/
div.crud {
font-size: 10pt;
margin: auto;
}
/******************************
* Context Menu
******************************/
div.crud #context-menu {
float: right;
list-style-type: none;
}
/******************************
* Fieldsets
******************************/
/* div.crud div.field-couple { */
/* clear: both; */
/* overflow: auto; */
/* min-height: 30px; */
/* } */
/* /\* div.crud div.field-couple div.label, *\/ */
/* div.crud div.field-couple label { */
/* display: block; */
/* float: left; */
/* width: 140px; */
/* font-weight: bold; */
/* margin-top: 2px; */
/* white-space: nowrap; */
/* } */
/* div.crud div.field-couple div.field { */
/* display: block; */
/* float: left; */
/* margin-bottom: 5px; */
/* line-height: 25px; */
/* } */
/* div.crud div.field-couple div.field input[type=text], */
/* div.crud div.field-couple div.field input[type=password], */
/* div.crud div.field-couple div.field select { */
/* width: 320px; */
/* } */
/* unbound checkbox field, e.g. 'add another' */
div.crud div.checkbox {
margin: 10px 0px;
padding-left: 3px;
}
/* div.crud div.buttons { */
/* clear: both; */
/* margin-top: 10px; */
/* } */
/* div.crud div.buttons * { */
/* margin-right: 8px; */
/* } */
/* div.crud table.fieldset tbody tr { */
/* vertical-align: top; */
/* } */
/* div.crud table.fieldset tbody td { */
/* height: 30px; */
/* padding: 2px; */
/* } */
/* div.crud table.fieldset td.label { */
/* font-weight: bold; */
/* width: 120px; */
/* } */
/* div.crud table.fieldset tbody td ul { */
/* padding-left: 15px; */
/* } */
/* div.crud table.fieldset tbody td ul li { */
/* line-height: 1em; */
/* margin-bottom: 4px; */
/* } */

View file

@ -9,7 +9,6 @@
html, body { html, body {
font-family: sans-serif; font-family: sans-serif;
font-size: .9em;
} }
a { a {
@ -28,11 +27,6 @@ li {
overflow: auto; overflow: auto;
} }
table.wrapper {
/* border: 1px solid black; */
width: 100%;
}
.left { .left {
float: left; float: left;
text-align: left; text-align: left;
@ -169,30 +163,6 @@ div.controls label {
} }
/******************************
* Header Table
******************************/
table.header {
padding-bottom: 5px;
width: 100%;
}
table.header td.context-menu {
vertical-align: top;
}
table.header td.context-menu ul {
list-style-type: none;
text-align: right;
}
table.header td.tools {
text-align: right;
vertical-align: bottom;
}
/****************************** /******************************
* Dialogs * Dialogs
******************************/ ******************************/
@ -201,200 +171,7 @@ div.dialog {
display: none; display: none;
} }
#feedback-dialog textarea { /* #feedback-dialog textarea { */
height: 180px; /* height: 180px; */
width: 500px; /* width: 500px; */
}
/******************************
* Filters
******************************/
div.filters div.filter div.value {
display: inline;
}
/******************************
* Grids
******************************/
div.grid {
clear: both;
}
div.grid table {
border-top: 1px solid black;
border-left: 1px solid black;
border-collapse: collapse;
font-size: 9pt;
line-height: normal;
white-space: nowrap;
}
div.grid.full table {
width: 100%;
}
div.grid table th,
div.grid table td {
border-right: 1px solid black;
border-bottom: 1px solid black;
padding: 2px 3px;
}
div.grid table th.sortable a {
display: block;
padding-right: 18px;
}
div.grid table th.sorted {
background-position: right center;
background-repeat: no-repeat;
}
div.grid table th.sorted.asc {
background-image: url(../img/sort_arrow_up.png);
}
div.grid table th.sorted.desc {
background-image: url(../img/sort_arrow_down.png);
}
div.grid table tbody td {
text-align: left;
}
div.grid table tbody td.right {
text-align: right;
}
div.grid table tr.odd {
background-color: #e0e0e0;
}
/* div.grid table thead th.checkbox, */
/* div.grid table tbody td.checkbox { */
/* text-align: center; */
/* vertical-align: middle; */
/* width: 15px; */
/* } */ /* } */
/* div.grid table td.action { */
/* cursor: default; */
/* } */
div.grid table td.delete {
text-align: center;
width: 18px;
background-image: url(../img/delete.png);
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
div.grid table tbody tr.hovering {
background-color: #bbbbbb;
}
div.grid table.hoverable tbody tr {
cursor: default;
}
div.grid.clickable table tbody tr,
div.grid table.selectable tbody tr,
div.grid table.checkable tbody tr {
cursor: pointer;
}
/* div.grid table.selectable tbody tr.selected, */
/* div.grid table.checkable tbody tr.selected { */
/* background-color: #666666; */
/* color: white; */
/* } */
div.pager {
margin-top: 5px;
}
div.pager p {
font-size: 10pt;
margin: 0px;
}
div.pager p.showing {
float: left;
}
div.pager #grid-page-count {
font-size: 8pt;
}
div.pager p.page-links {
float: right;
}
/* /\****************************** */
/* * Sub-Grids */
/* ******************************\/ */
/* div.subgrid { */
/* margin-top: 20px; */
/* } */
/* div.subgrid label { */
/* font-weight: bold; */
/* display: block; */
/* float: left; */
/* margin-bottom: 5px; */
/* } */
/******************************
* Fieldsets
******************************/
div.field-wrapper {
clear: both;
overflow: auto;
min-height: 30px;
}
div.field-wrapper label {
display: block;
float: left;
width: 140px;
font-weight: bold;
margin-top: 2px;
white-space: nowrap;
}
/* div.field-couple div.field-error { */
/* clear: both; */
/* color: #dd6666; */
/* font-weight: bold; */
/* } */
div.field-wrapper div.field {
display: block;
float: left;
margin-bottom: 5px;
line-height: 25px;
}
div.field-wrapper div.field input[type=text],
div.field-wrapper div.field input[type=password],
div.field-wrapper div.field select {
width: 320px;
}
div.buttons {
clear: both;
margin-top: 10px;
}
div.buttons * {
margin-right: 8px;
}

View file

@ -0,0 +1,24 @@
/******************************
* Filters
******************************/
div.filters div.filter {
margin-bottom: 10px;
}
div.filters div.filter label {
margin-right: 8px;
}
div.filters div.filter select.filter-type {
margin-right: 8px;
}
div.filters div.filter div.value {
display: inline;
}
div.filters div.buttons * {
margin-right: 8px;
}

View file

@ -0,0 +1,70 @@
/******************************
* Context Menu
******************************/
div.form-wrapper ul.context-menu {
float: right;
list-style-type: none;
margin: 0px;
text-align: right;
}
/******************************
* Forms
******************************/
div.fieldset-form {
float: left;
margin-left: 50px;
margin-top: 10px;
}
/******************************
* Fieldsets
******************************/
div.field-wrapper {
clear: both;
overflow: auto;
min-height: 30px;
}
div.field-wrapper label {
display: block;
float: left;
width: 140px;
font-weight: bold;
margin-top: 2px;
white-space: nowrap;
}
/* div.field-couple div.field-error { */
/* clear: both; */
/* color: #dd6666; */
/* font-weight: bold; */
/* } */
div.field-wrapper div.field {
display: block;
float: left;
margin-bottom: 5px;
line-height: 25px;
}
div.field-wrapper div.field input[type=text],
div.field-wrapper div.field input[type=password],
div.field-wrapper div.field select {
width: 320px;
}
div.buttons {
clear: both;
margin-top: 10px;
}
div.buttons * {
margin-right: 8px;
}

View file

@ -0,0 +1,150 @@
/******************************
* Grid Header
******************************/
table.grid-header {
padding-bottom: 5px;
width: 100%;
}
/******************************
* Context Menu
******************************/
table.grid-header td.context-menu {
vertical-align: top;
}
table.grid-header td.context-menu ul {
list-style-type: none;
margin: 0px;
text-align: right;
}
/******************************
* Tools
******************************/
table.grid-header td.tools {
text-align: right;
vertical-align: bottom;
}
/******************************
* Grid
******************************/
div.grid {
clear: both;
}
div.grid table {
border-top: 1px solid black;
border-left: 1px solid black;
border-collapse: collapse;
font-size: 9pt;
line-height: normal;
white-space: nowrap;
}
div.grid.full table {
width: 100%;
}
div.grid table th,
div.grid table td {
border-right: 1px solid black;
border-bottom: 1px solid black;
padding: 2px 3px;
}
div.grid table th.sortable a {
display: block;
padding-right: 18px;
}
div.grid table th.sorted {
background-position: right center;
background-repeat: no-repeat;
}
div.grid table th.sorted.asc {
background-image: url(../img/sort_arrow_up.png);
}
div.grid table th.sorted.desc {
background-image: url(../img/sort_arrow_down.png);
}
div.grid table tbody td {
text-align: left;
}
div.grid table tbody td.right {
text-align: right;
}
div.grid table tr.odd {
background-color: #e0e0e0;
}
/* div.grid table thead th.checkbox, */
/* div.grid table tbody td.checkbox { */
/* text-align: center; */
/* vertical-align: middle; */
/* width: 15px; */
/* } */
div.grid table td.delete {
text-align: center;
width: 18px;
background-image: url(../img/delete.png);
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
div.grid table tbody tr.hovering {
background-color: #bbbbbb;
}
div.grid table.hoverable tbody tr {
cursor: default;
}
div.grid.clickable table tbody tr,
div.grid table.selectable tbody tr,
div.grid table.checkable tbody tr {
cursor: pointer;
}
/* div.grid table.selectable tbody tr.selected, */
/* div.grid table.checkable tbody tr.selected { */
/* background-color: #666666; */
/* color: white; */
/* } */
div.pager {
margin-top: 5px;
}
div.pager p {
font-size: 10pt;
margin: 0px;
}
div.pager p.showing {
float: left;
}
div.pager #grid-page-count {
font-size: 8pt;
}
div.pager p.page-links {
float: right;
}

View file

@ -1,165 +0,0 @@
/************************************************************
* index.css
*
* Styles specific to "object index" pages.
************************************************************/
/******************************
* Wrapper
******************************/
div.object-index {
font-size: 10pt;
}
div.object-index table.header {
padding-bottom: 5px;
width: 100%;
}
/******************************
* Context Menu
******************************/
div.object-index table.header td.context-menu {
vertical-align: top;
}
div.object-index table.header td.context-menu ul {
list-style-type: none;
text-align: right;
}
/******************************
* Filters
******************************/
div.object-index div.filters div.filter {
margin-bottom: 10px;
}
div.object-index div.filters div.filter label,
div.object-index div.filters div.filter select.filter-type {
margin-right: 8px;
}
div.object-index div.filters div.buttons * {
margin-right: 8px;
}
/******************************
* Tools
******************************/
div.object-index table.header td.tools {
text-align: right;
vertical-align: bottom;
}
/******************************
* Grids
******************************/
/* div.object-index div.grid { */
/* clear: both; */
/* } */
div.object-index div.grid table {
/* border-top: 1px solid black; */
/* border-left: 1px solid black; */
/* border-collapse: collapse; */
/* font-size: 9pt; */
/* line-height: normal; */
/* white-space: nowrap; */
width: 100%;
}
/* div.object-index div.grid table th, */
/* div.object-index div.grid table td { */
/* border-right: 1px solid black; */
/* border-bottom: 1px solid black; */
/* padding: 2px 3px; */
/* } */
/* div.object-index div.grid table th.sortable a { */
/* display: block; */
/* padding-right: 18px; */
/* } */
/* div.object-index div.grid table th.sorted { */
/* background-position: right center; */
/* background-repeat: no-repeat; */
/* } */
/* div.object-index div.grid table th.sorted.asc { */
/* background-image: url(../img/sort_arrow_up.png); */
/* } */
/* div.object-index div.grid table th.sorted.desc { */
/* background-image: url(../img/sort_arrow_down.png); */
/* } */
/* div.object-index div.grid table tbody td { */
/* text-align: left; */
/* } */
/* div.object-index div.grid table tr.even { */
/* background-color: #e0e0e0; */
/* } */
/* div.object-index div.grid table td.delete { */
/* text-align: center; */
/* width: 18px; */
/* background-image: url(../img/delete.png); */
/* background-repeat: no-repeat; */
/* background-position: center; */
/* cursor: pointer; */
/* } */
/* div.object-index div.grid table tbody tr.hovering { */
/* background-color: #bbbbbb; */
/* } */
/* div.object-index div.grid table.hoverable tbody tr { */
/* cursor: default; */
/* } */
/* div.object-index div.grid.clickable table tbody tr, */
/* div.object-index div.grid table.selectable tbody tr, */
/* div.object-index div.grid table.checkable tbody tr { */
/* cursor: pointer; */
/* } */
/* div.grid table.selectable tbody tr.selected, */
/* div.grid table.checkable tbody tr.selected { */
/* background-color: #666666; */
/* color: white; */
/* } */
/* div.object-index div.pager { */
/* margin-top: 5px; */
/* } */
/* div.object-index div.pager p { */
/* font-size: 10pt; */
/* margin: 0px; */
/* } */
/* div.object-index div.pager p.showing { */
/* float: left; */
/* } */
/* div.object-index div.pager #grid-page-count { */
/* font-size: 8pt; */
/* height: 21px; */
/* } */
/* div.object-index div.pager p.page-links { */
/* float: right; */
/* } */

View file

@ -287,18 +287,13 @@ $(function() {
$(this).toggleClass('selected'); $(this).toggleClass('selected');
}); });
$('div.grid td.delete').live('click', function() { $('div.grid table tbody td.delete').live('click', function() {
var grid = $(this).parents('div.grid:first'); var url = $(this).attr('url');
var url = grid.attr('delurl');
if (url) { if (url) {
if (confirm("Do you really wish to delete this object?")) { if (confirm("Do you really wish to delete this object?")) {
location.href = url.replace(/%7Buuid%7D/, get_uuid(this)); location.href = url;
} }
} else {
alert("Hm, I don't know how to delete that..\n\n"
+ "(Add a 'delurl' parameter to the AlchemyGrid instance.)");
} }
return false;
}); });
$('#grid-page-count').live('change', function() { $('#grid-page-count').live('change', function() {

View file

@ -1,2 +1,3 @@
<%inherit file="/edbob/crud.mako" /> <%inherit file="/edbob/crud.mako" />
${parent.body()} ${parent.body()}

View file

@ -18,9 +18,12 @@
${h.javascript_link(request.static_url('edbob.pyramid:static/js/jquery.autocomplete.js'))} ${h.javascript_link(request.static_url('edbob.pyramid:static/js/jquery.autocomplete.js'))}
${h.javascript_link(request.static_url('edbob.pyramid:static/js/edbob.js'))} ${h.javascript_link(request.static_url('edbob.pyramid:static/js/edbob.js'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/smoothness/jquery-ui-1.8.2.custom.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/edbob.css'))} ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/edbob.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/grids.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/filters.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/forms.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/autocomplete.css'))} ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/autocomplete.css'))}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/smoothness/jquery-ui-1.8.2.custom.css'))}
${self.head_tags()} ${self.head_tags()}
</head> </head>

View file

@ -2,26 +2,11 @@
<%def name="title()">${(fieldset.crud_title+' : '+fieldset.get_display_text() if fieldset.edit else 'New '+fieldset.crud_title) if crud else ''|n}</%def> <%def name="title()">${(fieldset.crud_title+' : '+fieldset.get_display_text() if fieldset.edit else 'New '+fieldset.crud_title) if crud else ''|n}</%def>
<%def name="head_tags()">
${parent.head_tags()}
<style type="text/css">
#context-menu {
float: right;
}
div.fieldset {
float: left;
}
</style>
</%def>
<%def name="context_menu_items()"></%def> <%def name="context_menu_items()"></%def>
<div class="wrapper"> <div class="form-wrapper">
<ul id="context-menu"> <ul class="context-menu">
${self.context_menu_items()} ${self.context_menu_items()}
</ul> </ul>

View file

@ -1,16 +1,11 @@
<%inherit file="/base.mako" /> <%inherit file="/base.mako" />
<%def name="head_tags()">
${parent.head_tags()}
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/index.css'))}
</%def>
<%def name="context_menu_items()"></%def> <%def name="context_menu_items()"></%def>
<%def name="tools()"></%def> <%def name="tools()"></%def>
<div class="object-index"> <div class="grid-wrapper">
<table class="header"> <table class="grid-header">
<tr> <tr>
% if search: % if search:
<td rowspan="2" class="filters"> <td rowspan="2" class="filters">
@ -30,8 +25,8 @@
${self.tools()} ${self.tools()}
</td> </td>
</tr> </tr>
</table> </table><!-- grid-header -->
${grid} ${grid}
</div> </div><!-- grid-wrapper -->

View file

@ -0,0 +1,3 @@
<%inherit file="/edbob/grid.mako" />
${parent.body()}

View file

@ -29,7 +29,7 @@
<td class="noclick ${col.name}">${col.callback(row)}</td> <td class="noclick ${col.name}">${col.callback(row)}</td>
% endfor % endfor
% if grid.deletable: % if grid.deletable:
<td class="delete">&nbsp;</td> <td class="noclick delete" url="${grid.get_delete_url(row)}">&nbsp;</td>
% endif % endif
</tr> </tr>
% endfor % endfor

View file

@ -1,2 +0,0 @@
<%inherit file="/edbob/index.mako" />
${parent.body()}

View file

@ -134,6 +134,8 @@ class Crud(object):
model = Session.query(self.mapped_class).get(uuid) if uuid else None model = Session.query(self.mapped_class).get(uuid) if uuid else None
assert model assert model
Session.delete(model) Session.delete(model)
self.request.session.flash("The %s has been deleted." %
self.mapped_class.__name__)
return HTTPFound(location=self.home_url) return HTTPFound(location=self.home_url)
@classmethod @classmethod

View file

@ -31,6 +31,7 @@ from webhelpers import paginate
from edbob.pyramid import grids from edbob.pyramid import grids
from edbob.pyramid import Session from edbob.pyramid import Session
from edbob.pyramid.views.grids.core import GridView from edbob.pyramid.views.grids.core import GridView
from edbob.util import requires_impl
__all__ = ['AlchemyGridView', 'SortableAlchemyGridView', __all__ = ['AlchemyGridView', 'SortableAlchemyGridView',
@ -64,6 +65,11 @@ class SortableAlchemyGridView(AlchemyGridView):
sort = None sort = None
@property
@requires_impl(is_property=True)
def config_prefix(self):
pass
def join_map(self): def join_map(self):
return {} return {}
@ -79,7 +85,7 @@ class SortableAlchemyGridView(AlchemyGridView):
def make_sort_config(self, **kwargs): def make_sort_config(self, **kwargs):
return grids.util.get_sort_config( return grids.util.get_sort_config(
self.route_name, self.request, **kwargs) self.config_prefix, self.request, **kwargs)
def sort_config(self): def sort_config(self):
return self.make_sort_config(sort=self.sort) return self.make_sort_config(sort=self.sort)
@ -111,6 +117,8 @@ class SortableAlchemyGridView(AlchemyGridView):
class PagedAlchemyGridView(SortableAlchemyGridView): class PagedAlchemyGridView(SortableAlchemyGridView):
full = True
def make_pager(self): def make_pager(self):
config = self._sort_config config = self._sort_config
query = self.query() query = self.query()
@ -144,7 +152,7 @@ class SearchableAlchemyGridView(PagedAlchemyGridView):
def make_filter_config(self, **kwargs): def make_filter_config(self, **kwargs):
return grids.search.get_filter_config( return grids.search.get_filter_config(
self.route_name, self.request, self.filter_map(), **kwargs) self.config_prefix, self.request, self.filter_map(), **kwargs)
def filter_config(self): def filter_config(self):
return self.make_filter_config() return self.make_filter_config()

View file

@ -39,13 +39,19 @@ class GridView(View):
route_url = None route_url = None
renderer = None renderer = None
permission = None permission = None
full = False
checkboxes = False checkboxes = False
clickable = False clickable = False
deletable = False
partial_only = False partial_only = False
def update_grid_kwargs(self, kwargs): def update_grid_kwargs(self, kwargs):
kwargs.setdefault('full', self.full)
kwargs.setdefault('checkboxes', self.checkboxes) kwargs.setdefault('checkboxes', self.checkboxes)
kwargs.setdefault('clickable', self.clickable) kwargs.setdefault('clickable', self.clickable)
kwargs.setdefault('deletable', self.deletable)
kwargs.setdefault('partial_only', self.partial_only) kwargs.setdefault('partial_only', self.partial_only)
def make_grid(self, **kwargs): def make_grid(self, **kwargs):

View file

@ -34,17 +34,16 @@ from formalchemy.fields import SelectFieldRenderer
import edbob import edbob
from edbob.db.auth import set_user_password from edbob.db.auth import set_user_password
from edbob.pyramid import Session from edbob.pyramid import Session
from edbob.pyramid.filters import filter_ilike from edbob.pyramid.views import SearchableAlchemyGridView
from edbob.pyramid.grids import sorter
from edbob.pyramid.views import GridView
from edbob.pyramid.views.crud import Crud from edbob.pyramid.views.crud import Crud
class UserGrid(GridView): class UsersGrid(SearchableAlchemyGridView):
mapped_class = edbob.User mapped_class = edbob.User
route_name = 'users.list' route_name = 'users'
route_prefix = 'user' route_url = '/users'
sort = 'username'
def join_map(self): def join_map(self):
return { return {
@ -55,27 +54,22 @@ class UserGrid(GridView):
def filter_map(self): def filter_map(self):
return self.make_filter_map( return self.make_filter_map(
ilike=['username'], ilike=['username'],
person=filter_ilike(edbob.Person.display_name)) person=self.filter_ilike(edbob.Person.display_name))
def search_config(self, fmap): def filter_config(self):
return self.make_search_config( return self.make_filter_config(
fmap,
include_filter_username=True, include_filter_username=True,
filter_type_username='lk', filter_type_username='lk',
include_filter_person=True, include_filter_person=True,
filter_type_person='lk') filter_type_person='lk')
def grid_config(self, search, fmap):
return self.make_grid_config(search, fmap,
sort='username')
def sort_map(self): def sort_map(self):
return self.make_sort_map( return self.make_sort_map(
'username', 'username',
person=sorter(edbob.Person.display_name)) person=self.sorter(edbob.Person.display_name))
def grid(self, data, config): def grid(self):
g = self.make_grid(data, config) g = self.make_grid()
g.configure( g.configure(
include=[ include=[
g.username, g.username,
@ -219,5 +213,5 @@ class UserCrud(Crud):
def includeme(config): def includeme(config):
UserGrid.add_route(config, 'users.list', '/users') UsersGrid.add_route(config)
UserCrud.add_routes(config) UserCrud.add_routes(config)