1
0
Fork 0

Phi: Some tweaks for the Airport selection page

- Add a busy message while loading airport list
- Add METAR for the airport (if available)
- Remove cyclic object reference by making map and layer private
This commit is contained in:
Torsten Dreyer 2015-03-30 21:15:16 +02:00
parent 89b304cd1f
commit 872b40828a
2 changed files with 96 additions and 62 deletions

View file

@ -1,71 +1,69 @@
<style> <style>
.ui-autocomplete { .ui-autocomplete {
max-height: 300px; max-height: 300px;
overflow-y: auto; overflow-y: auto;
/* prevent horizontal scrollbar */ /* prevent horizontal scrollbar */
overflow-x: hidden; overflow-x: hidden;
} }
.metric { .metric {
font-style: italic; font-style: italic;
font-size: 90%; font-size: 90%;
} }
</style> </style>
<fieldset data-bind="visible: hasAirports"> <fieldset data-bind="visible: hasAirports">
<legend>Search (enter at least two characters of airport name or id)</legend> <legend>Search (enter at least two characters of airport name or id)</legend>
<input type="text" data-bind="autocomplete: { minLength: 2, source: airports, select: onSelect }" style="width: 100%;"> <input type="text" data-bind="autocomplete: { minLength: 2, source: airports, select: onSelect }" style="width: 100%;">
</fieldset> </fieldset>
<h1 data-bind="visible: isLoading">Please wait... Loading Airports...</h1>
<div style="width=100%" data-bind="with: selectedAirport"> <div style="" data-bind="with: selectedAirport">
<div style="float: left;"> <div style="float: left;">
<div style="font-size: 20pt; font-weight: bold;" data-bind="text: id"></div> <div style="font-size: 20pt; font-weight: bold;" data-bind="text: id"></div>
<div> <div>
<span style="font-size: 12pt; font-weight: normal;">Apt Elev </span> <span style="font-size: 12pt; font-weight: normal;">Apt Elev </span> <span style="font-size: 14pt; font-weight: bold;"
<span style="font-size: 14pt; font-weight: bold;" data-bind="text: elevation"></span> data-bind="text: elevation"></span> <span style="font-size: 14pt; font-weight: bold;">&apos;</span>
<span style="font-size: 14pt; font-weight: bold;">&apos;</span> </div>
<div>
<span style="font-size: 12pt; font-weight: normal;" data-bind="text: arpFormatted"></span>
</div>
</div> </div>
<div> <div style="float: right;">
<span style="font-size: 12pt; font-weight: normal;" data-bind="text: arpFormatted"></span> <div>
</div> <span style="font-size: 20pt; font-weight: normal; float: right" data-bind="text: name"></span>
</div> </div>
<div style="float: right;"> <div>
<div> <!--
<span style="font-size: 20pt; font-weight: normal; float: right" data-bind="text: name"></span>
</div>
<div>
<!--
<span style="font-size: 20pt; font-weight: bold;" data-bind="text: city"></span> <span style="font-size: 20pt; font-weight: bold;" data-bind="text: city"></span>
<span style="font-size: 20pt; font-weight: bold;">, </span> <span style="font-size: 20pt; font-weight: bold;">, </span>
<span style="font-size: 20pt; font-weight: bold;" data-bind="text: country"></span> <span style="font-size: 20pt; font-weight: bold;" data-bind="text: country"></span>
--> -->
</div>
</div> </div>
</div>
</div> </div>
<div class="ui-helper-clearfix"></div> <div class="ui-helper-clearfix"></div>
<fieldset data-bind="with: selectedAirport, visible: selectedAirport"> <fieldset data-bind="with: selectedAirport, visible: selectedAirport">
<legend>Communication</legend> <legend>Communication</legend>
<table style="width: 100%"> <table style="width: 100%">
<tr data-bind="foreach: comm"> <tr data-bind="foreach: comm">
<td> <td>
<div data-bind="text: name" style="text-align: center"></div> <div data-bind="text: name" style="text-align: center"></div>
<div data-bind="foreach: frequencies" style="text-align: center"> <div data-bind="foreach: frequencies" style="text-align: center">
<span data-bind="text: $data"></span> <span data-bind="text: $data"></span>
</div> </div>
</td> </td>
</tr> </tr>
</table> </table>
</fieldset> </fieldset>
<fieldset data-bind="visible: selectedAirport"> <fieldset data-bind="visible: selectedAirport">
<div id="phi-environment-position-map" style="height: 400px;"></div> <div id="phi-environment-position-map" style="height: 400px;"></div>
</fieldset> </fieldset>
<fieldset data-bind="with: selectedAirport, visible: selectedAirport"> <fieldset data-bind="with: selectedAirport, visible: selectedAirport">
<legend>Runway Information</legend> <legend>Runway Information</legend>
<table style="width: 100%"> <table style="width: 100%">
<thead> <thead>
<tr> <tr>
<th style="text-align: left">RWY</th> <th style="text-align: left">RWY</th>
<th style="text-align: right">True</th> <th style="text-align: right">True</th>
@ -77,18 +75,28 @@ overflow-x: hidden;
<th style="text-align: left"></th> <th style="text-align: left"></th>
</tr> </tr>
</thead> </thead>
<tbody data-bind="foreach: runway"> <tbody data-bind="foreach: runway">
<tr> <tr>
<td><span data-bind="text: id"></span></td> <td><span data-bind="text: id"></span></td>
<td style="text-align: right;"><span data-bind="text: heading"></span>&deg;</td> <td style="text-align: right;"><span data-bind="text: heading"></span>&deg;</td>
<td><span data-bind="text: surface"></span></td> <td><span data-bind="text: surface"></span></td>
<td><span data-bind="text: lengthFt"></span>ft <span data-bind="text: lengthM" class="metric"></span><span class="metric">m</span></td> <td><span data-bind="text: lengthFt"></span>ft <span data-bind="text: lengthM" class="metric"></span><span
<td><span data-bind="text: widthFt"></span>ft <span data-bind="text: widthM" class="metric"></span><span class="metric">m</span></td> class="metric">m</span></td>
<td><span data-bind="text: displacedThresholdFt"></span>ft <span data-bind="text: displacedThresholdM" class="metric"></span><span class="metric">m</span></td> <td><span data-bind="text: widthFt"></span>ft <span data-bind="text: widthM" class="metric"></span><span
<td><span data-bind="text: stopwayFt"></span>ft <span data-bind="text: stopwayM" class="metric"></span><span class="metric">m</span></td> class="metric">m</span></td>
<td><button data-bind="button: { text: false, icons: { primary: 'ui-icon-arrowreturnthick-1-e' } }, click: $parent.gotoRwy">Restart here</button></td> <td><span data-bind="text: displacedThresholdFt"></span>ft <span data-bind="text: displacedThresholdM"
</tr> class="metric"></span><span class="metric">m</span></td>
</tbody> <td><span data-bind="text: stopwayFt"></span>ft <span data-bind="text: stopwayM" class="metric"></span><span
</table> class="metric">m</span></td>
<td><button
data-bind="button: { text: false, icons: { primary: 'ui-icon-arrowreturnthick-1-e' } }, click: $parent.gotoRwy">Restart
here</button></td>
</tr>
</tbody>
</table>
</fieldset> </fieldset>
<fieldset data-bind="visible: metarValid">
<legend>Weather</legend>
<div data-bind="text: metar"></div>
</fieldset>

View file

@ -2,6 +2,8 @@ define([
'jquery', 'knockout', 'text!./Position.html', 'sprintf', 'leaflet', 'fgcommand', 'kojqui/autocomplete' 'jquery', 'knockout', 'text!./Position.html', 'sprintf', 'leaflet', 'fgcommand', 'kojqui/autocomplete'
], function( jquery, ko, htmlString, sprintf, leaflet, fgcommand ) { ], function( jquery, ko, htmlString, sprintf, leaflet, fgcommand ) {
var MetarPropertiesPath = "/aaa";
function getAirportList(obs) { function getAirportList(obs) {
if(typeof(Storage) !== "undefined") { if(typeof(Storage) !== "undefined") {
var storedList = sessionStorage.getItem("phiPositionAirportlist"); var storedList = sessionStorage.getItem("phiPositionAirportlist");
@ -59,7 +61,6 @@ define([
function AirportViewModel(geoJson, id) { function AirportViewModel(geoJson, id) {
var self = this; var self = this;
self.geoJson = geoJson;
jquery.get("/navdb?q=airport&id=" + id ).done(function(data) { jquery.get("/navdb?q=airport&id=" + id ).done(function(data) {
// expect geoJSON FeatureCollection // expect geoJSON FeatureCollection
@ -82,6 +83,10 @@ define([
self.name(airport.properties.name); self.name(airport.properties.name);
self.city(airport.properties.name); self.city(airport.properties.name);
self.country(airport.properties.name); self.country(airport.properties.name);
self.hasMetar(airport.properties.metar);
if(self.hasMetar()) {
fgcommand.requestMetar( self.id(), MetarPropertiesPath );
}
var comm = {}; var comm = {};
airport.properties.comm.forEach(function(c){ airport.properties.comm.forEach(function(c){
@ -100,9 +105,9 @@ define([
self.longitude(Number(arp[0]||0)); self.longitude(Number(arp[0]||0));
self.latitude(Number(arp[1]||0)); self.latitude(Number(arp[1]||0));
self.geoJson.clearLayers(); geoJson.clearLayers();
self.geoJson.addData(airport); geoJson.addData(airport);
self.geoJson._map.setView([ self.latitude(), self.longitude() ], 13); geoJson._map.setView([ self.latitude(), self.longitude() ], 13);
}); });
self.id = ko.observable(''); self.id = ko.observable('');
@ -112,6 +117,7 @@ define([
self.elevation = ko.observable(0); self.elevation = ko.observable(0);
self.longitude = ko.observable(0); self.longitude = ko.observable(0);
self.latitude = ko.observable(0); self.latitude = ko.observable(0);
self.hasMetar = ko.observable(false);
self.arpFormatted = ko.pureComputed(function() { self.arpFormatted = ko.pureComputed(function() {
function dm(v) { function dm(v) {
var s = v < 0; var s = v < 0;
@ -189,12 +195,12 @@ define([
function ViewModel(params) { function ViewModel(params) {
var self = this; var self = this;
self.map = leaflet.map("phi-environment-position-map", { var map = leaflet.map("phi-environment-position-map", {
dragging: false, dragging: false,
touchZoom: false, touchZoom: false,
scrollWheelZoom: false, scrollWheelZoom: false,
}); });
self.geoJson = leaflet.geoJson(null,{ var geoJson = leaflet.geoJson(null,{
style : function(feature) { style : function(feature) {
return { return {
color : 'black', color : 'black',
@ -206,8 +212,8 @@ define([
}; };
} }
}); });
self.geoJson._map = self.map; geoJson._map = map;
self.geoJson.addTo(self.map); geoJson.addTo(map);
self.airports = ko.observableArray([]); self.airports = ko.observableArray([]);
getAirportList(self.airports); getAirportList(self.airports);
@ -215,14 +221,34 @@ define([
return self.airports().length; return self.airports().length;
}); });
self.isLoading = ko.pureComputed(function() {
return self.airports().length < 1;
});
self.selectedAirport = ko.observable(); self.selectedAirport = ko.observable();
self.metarValidFlag = ko.observable(0).extend({
observedProperty : MetarPropertiesPath + "/valid"
});
self.metarValid = ko.pureComputed(function(){
return self.metarValidFlag() && self.selectedAirport() && self.selectedAirport().hasMetar();
});
self.metar = ko.observable(0).extend({
observedProperty : MetarPropertiesPath + "/data"
});
self.onSelect = function(ev,ui) { self.onSelect = function(ev,ui) {
self.selectedAirport(new AirportViewModel(self.geoJson,getAirportId(ui.item.value))); var id = getAirportId(ui.item.value);
self.selectedAirport(new AirportViewModel(geoJson,id));
} }
} }
ViewModel.prototype.dispose = function() { ViewModel.prototype.dispose = function() {
fgcommand.clearMetar(MetarPropertiesPath);
self.metar.dispose();
self.metarValidFlag.dispose();
} }
// Return component definition // Return component definition