diff --git a/src/c3nav/mapdata/models/locations.py b/src/c3nav/mapdata/models/locations.py index b9bc9904..3001aad6 100644 --- a/src/c3nav/mapdata/models/locations.py +++ b/src/c3nav/mapdata/models/locations.py @@ -3,6 +3,7 @@ from collections import OrderedDict from django.core.cache import cache from django.db import models +from django.db.models import Q from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ @@ -245,6 +246,34 @@ def get_location(request, name): return filter_queryset_by_package_access(request, AreaLocation.objects.filter(name=name)).first() +def filter_words(queryset, words): + for word in words: + queryset = queryset.filter(Q(name__icontains=word) | Q(titles__icontains=word)) + return queryset + + +def search_location(request, search): + results = [] + location = get_location(request, search) + if location: + results.append(location) + + words = search.split(' ')[:10] + + queryset = AreaLocation.objects.all() + if isinstance(location, AreaLocation): + queryset.exclude(name=location.name) + results += sorted(filter_words(filter_queryset_by_package_access(request, queryset), words), + key=AreaLocation.get_sort_key, reverse=True) + + queryset = LocationGroup.objects.all() + if isinstance(location, LocationGroup): + queryset.exclude(name=location.name) + results += list(filter_words(filter_queryset_by_package_access(request, queryset), words)[:10]) + + return results + + class PointLocation(Location): def __init__(self, level: Level, x: int, y: int): self.level = level diff --git a/src/c3nav/site/static/site/css/c3nav.css b/src/c3nav/site/static/site/css/c3nav.css index d488d50b..c276bfcc 100644 --- a/src/c3nav/site/static/site/css/c3nav.css +++ b/src/c3nav/site/static/site/css/c3nav.css @@ -3,6 +3,14 @@ body, .btn { } +.main-view.mode-location .locations > .origin-select, +.main-view.mode-location .locations > .destination-select, +.main-view.mode-route .locations > .location-select, +.main-view.mode-location .routing { + display:none +} + + .locationselect .input-lg { height: 62px; } @@ -12,10 +20,10 @@ body, .btn { .locationselect .locationselect-selected { display:none; } -.locationselect.selected .locationselect-selected { +.location-group.selected .locationselect-selected { display:block; } -.locationselect.selected .locationselect-input { +.location-group.selected .locationselect-input { display:none; } .locationselect .icons { @@ -33,6 +41,16 @@ body, .btn { .locationselect .icons .reset { background-image:url('../img/icons/cross.svg'); } +.locationselect .icons .link { + background-image:url('../img/icons/link.svg'); +} + +.location-group .only-if-selected { + display:none; +} +.location-group.selected .only-if-selected { + display:block; +} .location { @@ -67,6 +85,9 @@ body, .btn { overflow:hidden; padding-bottom:4px; } +.tt-menu.noscript { + margin-top:0; +} .tt-dataset { background-color: #ffffff; border-width: 1px; @@ -77,8 +98,15 @@ body, .btn { -webkit-box-shadow: 0 0 8px rgba(102, 175, 233, 0.6); box-shadow: 0 0 8px rgba(102, 175, 233, 0.6); } +.noscript .tt-dataset { + border-width:0 1px 1px; + border-color: #E7E7E7; + -webkit-box-shadow: 0 0 8px rgba(231, 231, 231, 0.6); + box-shadow: 0 0 8px rgba(231, 231, 231, 0.6); +} .tt-suggestion { padding: 6px 10px; + display:block; } .tt-suggestion.tt-cursor { color: #fff; @@ -91,6 +119,13 @@ body, .btn { margin: 0; } +.routing { + display:none; +} +.can-route .routing { + display:block; +} + svg { width:100%; height:auto; @@ -183,8 +218,3 @@ circle.pos { vertical-align:middle; line-height: 1.42857143; } - - -.login .container { - max-width:420px; -} diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index 3a9de2ac..f2a14215 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -1,6 +1,6 @@ c3nav = { init: function() { - if (!$('#main_view').length) return; + if (!$('.main-view').length) return; c3nav._typeahead_locations = new Bloodhound({ datumTokenizer: function(data) { @@ -29,19 +29,43 @@ c3nav = { } }; - c3nav.update_history_state(true); c3nav.init_typeahead($('.locationselect input:text')); $('.locationselect:not(.selected) .locationselect-input .tt-input').first().focus(); - $('.locationselect .icons .reset').click(c3nav._locationselect_reset) + $('.locationselect .icons .reset').click(c3nav._locationselect_reset); + $('#route-from-here').click(c3nav._click_route_from_here); + $('#route-to-here').click(c3nav._click_route_to_here); + + window.onpopstate = c3nav._onpopstate; }, _locationselect_reset: function(e) { e.preventDefault(); - var locationselect = $(this).closest('.locationselect'); - locationselect.find('.id-field').val(''); - locationselect.removeClass('selected').find('.tt-input').focus().keyup().removeData('enter_item'); - c3nav.update_history_state(); + var location_group = $(this).closest('.location-group'); + location_group.find('.id-field').val(''); + location_group.removeClass('selected').find('.tt-input').focus().removeData('enter_item'); + location_group,find('.tt-suggestion').remove(); + c3nav._locations_changed(); + }, + locationselect_focus: function() { + $('.location-group:visible:not(.selected) .locationselect-input .tt-input').first().focus(); + }, + + _click_route_from_here: function(e) { + c3nav._click_route_x_here(e, $('.origin-select')); + }, + _click_route_to_here: function(e) { + c3nav._click_route_x_here(e, $('.destination-select')); + }, + _click_route_x_here: function(e, location_group) { + e.preventDefault(); + $('.main-view').removeClass('mode-location').addClass('mode-route'); + from_group = $('.location-select'); + from_group.removeClass('selected'); + location_group.addClass('selected').find('.id-field').val(from_group.find('.id-field').val()); + location_group.find('.locationselect-selected .location').html(from_group.find('.locationselect-selected .location').html()); + c3nav._locations_changed(); + c3nav.locationselect_focus(); }, init_typeahead: function(elem) { @@ -55,6 +79,7 @@ c3nav = { }, _typeahead_keydown: function(e) { if (e.which == 13) { + e.preventDefault(); var target = $(e.target); enter_item = target.data('enter_item'); if (enter_item !== undefined) { @@ -63,16 +88,15 @@ c3nav = { } }, _typeahead_select: function(e, item) { - var locationselect = $(e.target).closest('.locationselect'); - locationselect.addClass('selected'); - var selected = locationselect.find('.locationselect-selected'); + var location_group = $(e.target).closest('.location-group'); + location_group.addClass('selected'); + var selected = location_group.find('.locationselect-selected'); selected.find('.title').text(item.title); selected.find('.subtitle').text(item.subtitle); selected.find('.id-field').val(item.id); e.target.blur(); - c3nav.update_history_state(); - - $('.locationselect:not(.selected) .locationselect-input .tt-input').first().focus(); + c3nav._locations_changed(); + c3nav.locationselect_focus(); }, _typeahead_blur: function(e) { $(e.target).val(''); @@ -81,24 +105,25 @@ c3nav = { $(e.target).data('enter_item', item); }, - update_history_state: function(e, replace) { - var origin = $(':input[name=origin]').val(); - var destination = $(':input[name=destination]').val(); - url = '/'; - if (origin !== '') { - url += origin + '/' - if (destination !== '') { - url += destination + '/' - } - } else if (destination !== '') { - url += '_/' + destination + '/' - } - if (replace) { - history.replaceState({}, '', url); + _locations_changed: function(e) { + var url; + if ($('.main-view').is('.mode-location')) { + url = '/l/'+$(':input[name=location]').val()+'/'; } else { - history.pushState({}, '', url); + var origin = $(':input[name=origin]').val(); + var destination = $(':input[name=destination]').val(); + if (origin !== '') { + url = (destination !== '') ? '/r/'+origin+'/'+destination+'/' : '/o/'+origin+'/'; + } else { + url = (destination !== '') ? '/d/'+destination+'/' : '/'; + } + $('.main-view').toggleClass('can-route', (origin !== '' && destination !== '')); } - + history.pushState({}, '', url); + }, + _onpopstate: function() { + document.location.href = document.location; } + }; $(document).ready(c3nav.init); diff --git a/src/c3nav/site/templates/site/fragment_location.html b/src/c3nav/site/templates/site/fragment_location.html index e3fa2075..f1ab7c15 100644 --- a/src/c3nav/site/templates/site/fragment_location.html +++ b/src/c3nav/site/templates/site/fragment_location.html @@ -1,19 +1,60 @@ {% load i18n %} -