From d29c066873b348f79781093a2b3d4d107cde9f2d Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sat, 09 Feb 2019 17:25:30 +0000 Subject: [PATCH] Refactor panel component and make it collapsible --- map.js | 122 ++++++++++++++++++++---------- lang_en.js | 4 + map.html | 8 +- lang_pl.js | 4 + map.css | 78 +++++++++++++------ 5 files changed, 146 insertions(+), 70 deletions(-) diff --git a/lang_en.js b/lang_en.js index 2e7c18e..22d74bf 100644 --- a/lang_en.js +++ b/lang_en.js @@ -5,6 +5,10 @@ map: 'Map', + action_close: 'Close', + action_expand: 'Expand', + action_collapse: 'Collapse', + jquery_not_loaded: 'Required JavaScript jQuery library failed to load. You may try refreshing the page.', enter_stop_name_to_begin: 'Enter the stop name to begin.', select_stop_click_go: 'Select the stop and click "Go".', diff --git a/lang_pl.js b/lang_pl.js index a2e0818..64f30ad 100644 --- a/lang_pl.js +++ b/lang_pl.js @@ -5,6 +5,10 @@ map: 'Mapa', + action_close: 'Zamknij', + action_expand: 'Rozwiń', + action_collapse: 'Zwiń', + jquery_not_loaded: 'Wymagana biblioteka jQuery nie została poprawnie załadowana. Spróbuj odświeżyć stronę.', enter_stop_name_to_begin: 'Zacznij wpisywać nazwę przystanku.', select_stop_click_go: 'Wyierz przystanek i kliknij "Dalej".', diff --git a/map.css b/map.css index 29178f4..2b1b6c6 100644 --- a/map.css +++ b/map.css @@ -17,42 +17,68 @@ right: auto; } -#popup { +.panel { + opacity: .85; color: black; background: white; padding: 5px; border-left: 1px solid black; font-size: 14px; + overflow-y: auto; + + transition: right .4s, width .4s; position: absolute; width: 350px; right: -365px; top: 0; bottom: 0; - - transition: right .4s, width .4s; - - opacity: .85; - - overflow-y: auto; } - -#popup.show { +.panel.expanded { right: 0; } +.panel .hide { + display: none; +} +.panel.enabled .hide { + display: block; + + position: fixed; + bottom: 20%; + right: 0; + + opacity: .85; + border: 1px solid black; + border-right: 0; + border-radius: 5px 0 0 5px; + background: white; + margin-right: 0px; + padding: 1em 0.2em; + padding-bottom: 1.2em; + + transition: right .4s, margin-right .4s; +} +.panel.expanded .hide { + right: 360px; +} + @media (max-width: 600px) { - #popup { + .panel { width: 80%; right: -100%; } - - #popup.show { + .panel.expanded { right: 0%; + } + + .panel.enabled .hide { + right: 80%; + margin-right: 10px; } } -.close { +.close, .hide { float: right; cursor: pointer; font-size: 20px; @@ -62,50 +88,50 @@ font-size: inherit; height: 1em; } -#popup .type { +.panel .type { padding-bottom: 0; color: #444; font-size: 80%; } -#popup p { +.panel p { margin: 0; padding: 5px; } -#popup .name { +.panel .name { font-weight: bold; } -#popup .vehicleInfo { +.panel .vehicleInfo { font-size: 21px; margin: -4px 0 -5px; } -#popup table { +.panel table { margin-top: 3px; border-top: 1px solid gray; width: 100%; border-collapse: collapse; } -#popup table th { +.panel table th { text-align: left; border-bottom: 1px solid #999; padding-top: 5px; } -#popup table td { +.panel table td { vertical-align: top; } -#popup .active { +.panel .active { background: #f5f5f5; color: gray; } -#popup .success { +.panel .success { background: #dff0d8; } -#popup .warning { +.panel .warning { background: #fcf8e3; } -#popup .danger { +.panel .danger { background: #f2dede; } -#popup table .vehicleInfo { +.panel table .vehicleInfo { float: right; } @@ -117,7 +143,7 @@ background-color: rgba(255,255,255,.6); } -#fail, #popup .error { +#fail, .panel .error { background: red; color: white; font-weight: bold; diff --git a/map.html b/map.html index 87fe214..5e56b69 100644 --- a/map.html +++ b/map.html @@ -5,7 +5,7 @@ <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/css/ol.css" integrity="sha384-C7SzZySesoxngSK5V0BaD1DUap0LPZGWZpnXQGoIwvBXFc8G21y4s1QYvyr84FNa" crossorigin="anonymous"> -<link rel="stylesheet" href="map.css?v2" type="text/css" /> +<link rel="stylesheet" href="map.css?v3" type="text/css" /> </head> <body> <div id="map"> @@ -20,12 +20,12 @@ </svg></button></div> <div id="fail" class="ol-unselectable ol-control"><span></span> <span class="close">×</p></div> </div> -<div id="popup"></div> +<div id="panel"></div> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT" crossorigin="anonymous"></script> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList"></script> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/build/ol.js" integrity="sha384-iQkGyyH4ioz3m+maM3s9MX1Oq67mACa4B9Z3ovUv3Sv37LJ96fx3WnZfLoiC3Wfl" crossorigin="anonymous"></script> -<script tyle="text/javascript" src="lang_pl.js?v4" id="lang_script"></script> +<script tyle="text/javascript" src="lang_pl.js?v5" id="lang_script"></script> <script tyle="text/javascript" src="common.js?v6"></script> -<script tyle="text/javascript" src="map.js?v11"></script> +<script tyle="text/javascript" src="map.js?v12"></script> </body> </html> diff --git a/map.js b/map.js index a8f6b2a..d968325 100644 --- a/map.js +++ b/map.js @@ -46,20 +46,85 @@ var route_layer = null; var map = null; -var popup_element = document.getElementById('popup'); -var popup_close_callback; + +var panel = null; + var fail_element = document.getElementById('fail'); var fail_text = document.querySelector('#fail span'); var ignore_hashchange = false; + +function Panel(element) { + this._element = element; + this._element.classList.add('panel'); + + this._hide = addParaWithText(this._element, '▶'); + this._hide.title = lang.action_collapse; + this._hide.className = 'hide'; + this._hide.addEventListener('click', this.toggleExpanded.bind(this)); + + this._close = addParaWithText(this._element, '×'); + this._close.title = lang.action_close; + this._close.className = 'close'; + this._close.addEventListener('click', this.close.bind(this)); + + this._content = document.createElement('div'); + this._element.appendChild(this._content); +}; +Panel.prototype = { + _element: null, + _hide: null, + _close: null, + _content: null, + + _closeCallback: null, + _runCallback: function() { + var callback = this.closeCallback; + this.closeCallback = null; + if(callback) callback(); + }, + + expand: function() { + this._element.classList.add('expanded'); + setText(this._hide, '▶'); + this._hide.title = lang.action_collapse; + }, + collapse: function() { + this._element.classList.remove('expanded'); + setText(this._hide, '◀'); + this._hide.title = lang.action_expand; + }, + toggleExpanded: function() { + if(this._element.classList.contains('expanded')) { + this.collapse(); + } else { + this.expand(); + } + }, + fail: function(message) { + addParaWithText(this._content, message).className = 'error'; + }, + show: function(contents, closeCallback) { + this._runCallback(); + this.closeCallback = closeCallback; + + deleteChildren(this._content); + + this._content.appendChild(contents); + this._element.classList.add('enabled'); + setTimeout(this.expand.bind(this), 1); + }, + close: function() { + this._runCallback(); + this._element.classList.remove('expanded'); + this._element.classList.remove('enabled'); + }, +}; + function fail(msg) { setText(fail_text, msg); fail_element.style.top = '0.5em'; -} - -function fail_popup(msg) { - addElementWithText(popup_element, 'p', msg).className = 'error'; } function fail_ajax_generic(data, fnc) { @@ -80,7 +145,7 @@ } function fail_ajax_popup(data) { - fail_ajax_generic(data, fail_popup); + fail_ajax_generic(data, panel.fail.bind(panel)); } function getGeometry(object) { @@ -462,38 +527,13 @@ }).fail(fail_ajax_popup); } -function showPanel(contents, closeCallback) { - var old_callback = popup_close_callback; - popup_close_callback = null; - if(old_callback) old_callback(); - popup_close_callback = closeCallback; - - deleteChildren(popup_element); - - var close = addParaWithText(popup_element, '×'); - close.className = 'close'; - close.addEventListener('click', function() { hidePanel(); }); - - popup_element.appendChild(contents); - - $(popup_element).addClass('show'); -} - -function hidePanel() { - var old_callback = popup_close_callback; - popup_close_callback = null; - if(old_callback) old_callback(); - - $(popup_element).removeClass('show'); -} - function featureClicked(feature) { if(feature && !feature.getId()) return; unstyleSelectedFeatures(); if(!feature) { - hidePanel(); + panel.close(); return; } @@ -611,13 +651,13 @@ }) }, 10); - showPanel(div, function() { + panel.show(div, function() { if(!ignore_hashchange) { ignore_hashchange = true; window.location.hash = ''; - feature_clicked = null; unstyleSelectedFeatures(); + feature_clicked = null; if(feature_xhr) feature_xhr.abort(); if(feature_timer) clearTimeout(feature_timer); @@ -689,7 +729,7 @@ div.appendChild(p); } - showPanel(div); + panel.show(div); return; } @@ -724,14 +764,14 @@ } function trackingStop() { - geolocation_button.className = ""; + geolocation_button.classList.remove('clicked'); geolocation.setTracking(false); geolocation_source.clear(); } function trackingStart() { geolocation_set = 0; - geolocation_button.className = "clicked"; + geolocation_button.classList.add('clicked'); geolocation_feature.setGeometry(new ol.geom.Point(map.getView().getCenter())); geolocation_accuracy.setGeometry(new ol.geom.Circle(map.getView().getCenter(), 100000)); @@ -827,6 +867,8 @@ dataType: 'json', timeout: 10000, }); + + panel = new Panel(document.getElementById('panel')); stops_buses_source = new ol.source.Vector({ features: [], @@ -944,7 +986,7 @@ }); geolocation_button = document.querySelector('#track button'); if(!navigator.geolocation) { - geolocation_button.className = 'hidden'; + geolocation_button.classList.add('hidden'); } geolocation = new ol.Geolocation({projection: 'EPSG:3857'}); @@ -969,7 +1011,7 @@ geolocation.on('error', function(error) { fail(lang.error_location + ' ' + error.message); trackingStop(); - geolocation_button.className = 'hidden'; + geolocation_button.classList.add('hidden'); }); geolocation_button.addEventListener('click', trackingToggle); -- Gitblit v1.9.1