diff --git a/edbob/pyramid/grids/core.py b/edbob/pyramid/grids/core.py
index 290e8f6..f1de01a 100644
--- a/edbob/pyramid/grids/core.py
+++ b/edbob/pyramid/grids/core.py
@@ -44,13 +44,19 @@ __all__ = ['Grid']
class Grid(edbob.Object):
+ full = False
hoverable = True
clickable = False
checkboxes = False
deletable = 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):
kwargs.setdefault('fields', OrderedDict())
@@ -65,23 +71,38 @@ class Grid(edbob.Object):
def column_header(self, field):
return literal('
%s | ' % (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):
- 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):
return self.fields.itervalues()
@@ -99,15 +120,3 @@ class Grid(edbob.Object):
def row_attrs(self, row, i):
attrs = {'class_': 'odd' if i % 2 else 'even'}
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)
diff --git a/edbob/pyramid/grids/search.py b/edbob/pyramid/grids/search.py
index 4e92fcd..e318d7e 100644
--- a/edbob/pyramid/grids/search.py
+++ b/edbob/pyramid/grids/search.py
@@ -159,7 +159,7 @@ def filter_ilike(field):
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.
"""
@@ -191,7 +191,7 @@ def get_filter_config(name, request, filter_map, **kwargs):
config.update(kwargs)
# 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.
if request.params.get('filters') == 'true':
@@ -201,7 +201,7 @@ def get_filter_config(name, request, filter_map, **kwargs):
for key in config:
if (not key.startswith('filter_factory_')
and not key.startswith('filter_label_')):
- request.session[name+'.'+key] = config[key]
+ request.session[prefix+'.'+key] = config[key]
return config
diff --git a/edbob/pyramid/static/css/crud.css b/edbob/pyramid/static/css/crud.css
deleted file mode 100644
index 671227b..0000000
--- a/edbob/pyramid/static/css/crud.css
+++ /dev/null
@@ -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; */
-/* } */
diff --git a/edbob/pyramid/static/css/edbob.css b/edbob/pyramid/static/css/edbob.css
index 0afce70..dbaa538 100644
--- a/edbob/pyramid/static/css/edbob.css
+++ b/edbob/pyramid/static/css/edbob.css
@@ -9,7 +9,6 @@
html, body {
font-family: sans-serif;
- font-size: .9em;
}
a {
@@ -28,11 +27,6 @@ li {
overflow: auto;
}
-table.wrapper {
- /* border: 1px solid black; */
- width: 100%;
-}
-
.left {
float: 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
******************************/
@@ -201,200 +171,7 @@ div.dialog {
display: none;
}
-#feedback-dialog textarea {
- height: 180px;
- 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; */
+/* #feedback-dialog textarea { */
+/* height: 180px; */
+/* width: 500px; */
/* } */
-
-/* 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;
-}
diff --git a/edbob/pyramid/static/css/filters.css b/edbob/pyramid/static/css/filters.css
new file mode 100644
index 0000000..6cf4e8b
--- /dev/null
+++ b/edbob/pyramid/static/css/filters.css
@@ -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;
+}
diff --git a/edbob/pyramid/static/css/forms.css b/edbob/pyramid/static/css/forms.css
new file mode 100644
index 0000000..67b0eb9
--- /dev/null
+++ b/edbob/pyramid/static/css/forms.css
@@ -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;
+}
diff --git a/edbob/pyramid/static/css/grids.css b/edbob/pyramid/static/css/grids.css
new file mode 100644
index 0000000..2f9eba4
--- /dev/null
+++ b/edbob/pyramid/static/css/grids.css
@@ -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;
+}
diff --git a/edbob/pyramid/static/css/index.css b/edbob/pyramid/static/css/index.css
deleted file mode 100644
index 8beaa9b..0000000
--- a/edbob/pyramid/static/css/index.css
+++ /dev/null
@@ -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; */
-/* } */
diff --git a/edbob/pyramid/static/js/edbob.js b/edbob/pyramid/static/js/edbob.js
index 1bda139..d36fc3e 100644
--- a/edbob/pyramid/static/js/edbob.js
+++ b/edbob/pyramid/static/js/edbob.js
@@ -287,18 +287,13 @@ $(function() {
$(this).toggleClass('selected');
});
- $('div.grid td.delete').live('click', function() {
- var grid = $(this).parents('div.grid:first');
- var url = grid.attr('delurl');
+ $('div.grid table tbody td.delete').live('click', function() {
+ var url = $(this).attr('url');
if (url) {
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() {
diff --git a/edbob/pyramid/templates/crud.mako b/edbob/pyramid/templates/crud.mako
index 6a1a27f..0ca6e40 100644
--- a/edbob/pyramid/templates/crud.mako
+++ b/edbob/pyramid/templates/crud.mako
@@ -1,2 +1,3 @@
<%inherit file="/edbob/crud.mako" />
+
${parent.body()}
diff --git a/edbob/pyramid/templates/edbob/base.mako b/edbob/pyramid/templates/edbob/base.mako
index 346e5d7..b8f3279 100644
--- a/edbob/pyramid/templates/edbob/base.mako
+++ b/edbob/pyramid/templates/edbob/base.mako
@@ -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/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/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/smoothness/jquery-ui-1.8.2.custom.css'))}
${self.head_tags()}
diff --git a/edbob/pyramid/templates/edbob/crud.mako b/edbob/pyramid/templates/edbob/crud.mako
index c8d2e21..c874825 100644
--- a/edbob/pyramid/templates/edbob/crud.mako
+++ b/edbob/pyramid/templates/edbob/crud.mako
@@ -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="head_tags()">
- ${parent.head_tags()}
-
-%def>
-
<%def name="context_menu_items()">%def>
-