From a802cbee74d8c83876375890d914252f1adb1c96 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Fri, 24 Nov 2017 14:22:57 -0800 Subject: [PATCH] Search now applies to current filters Combined search into the same form as filters. Closes #133 --- datasette/app.py | 7 ++++++- datasette/static/app.css | 16 +++++++++++++--- datasette/templates/table.html | 9 +++------ datasette/utils.py | 4 +++- tests/test_app.py | 17 +++++++++++++++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 2b82c70f..82ea26fe 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -528,12 +528,14 @@ class TableView(RowTableShared): fts_table = fts_rows[0][0] search = special_args.get('_search') + search_description = None if search and fts_table: where_clauses.append( 'rowid in (select rowid from [{fts_table}] where [{fts_table}] match :search)'.format( fts_table=fts_table ) ) + search_description = 'search matches "{}"'.format(search) params['search'] = search next = special_args.get('_next') @@ -642,10 +644,13 @@ class TableView(RowTableShared): # Almost certainly hit the timeout pass + # human_filter_description combines filters AND search, if provided + human_description = filters.human_description(extra=search_description) + async def extra_template(): return { 'database_hash': hash, - 'human_filter_description': filters.human_description(), + 'human_filter_description': human_description, 'supports_search': bool(fts_table), 'search': search or '', 'use_rowid': use_rowid, diff --git a/datasette/static/app.css b/datasette/static/app.css index d3625b96..13ea503f 100644 --- a/datasette/static/app.css +++ b/datasette/static/app.css @@ -1,4 +1,3 @@ - body { margin: 0 1em; font-family: "Helvetica Neue", sans-serif; @@ -107,11 +106,12 @@ form label { form input[type=text], form input[type=search] { border: 1px solid #ccc; + border-radius: 3px; width: 60%; padding: 9px 4px; - font-family: monospace; display: inline-block; - font-size: 1.1em; + font-size: 1em; + font-family: Helvetica, sans-serif; } @media only screen and (max-width: 576px) { form.sql textarea { @@ -137,6 +137,16 @@ form input[type=submit] { .filter-row { margin-bottom: 0.6em; } +.search-row { + margin-bottom: 1.8em; +} + +.search-row label { + font-size: 1.2em; + padding-right: 0.5em; + display: inline-block; + width: 80px; +} .select-wrapper { border: 1px solid #ccc; diff --git a/datasette/templates/table.html b/datasette/templates/table.html index 572a8819..77d4d8b6 100644 --- a/datasette/templates/table.html +++ b/datasette/templates/table.html @@ -24,13 +24,10 @@ {% endif %} -{% if supports_search %} -
-

-
-{% endif %} -
+ {% if supports_search %} +
+ {% endif %} {% for column, lookup, value in filters.selections() %}
diff --git a/datasette/utils.py b/datasette/utils.py index fe7c58e1..017e9dbb 100644 --- a/datasette/utils.py +++ b/datasette/utils.py @@ -359,8 +359,10 @@ class Filters: for filter in self._filters: yield filter.key, filter.display, filter.no_argument - def human_description(self): + def human_description(self, extra=None): bits = [] + if extra: + bits.append(extra) for column, lookup, value in self.selections(): filter = self._filters_by_key.get(lookup, None) if filter: diff --git a/tests/test_app.py b/tests/test_app.py index 881f5b06..4dc912de 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -404,6 +404,23 @@ def test_existing_filter_redirects(app_client): assert '?' not in response.headers['Location'] +def test_empty_search_parameter_gets_removed(app_client): + path_base = app_client.get( + '/test_tables/simple_primary_key', allow_redirects=False, gather_request=False + ).headers['Location'] + path = path_base + '?' + urllib.parse.urlencode({ + '_search': '', + '_filter_column': 'name', + '_filter_op': 'exact', + '_filter_value': 'chidi', + }) + response = app_client.get(path, allow_redirects=False, gather_request=False) + assert response.status == 302 + assert response.headers['Location'].endswith( + '?name__exact=chidi' + ) + + TABLES = ''' CREATE TABLE simple_primary_key ( pk varchar(30) primary key,