chaloBEST/chaloBEST/static/js/editstops.js

409 lines
16 KiB
JavaScript

var API_BASE = "/1.0/",
map;
(function() {
$(function() {
initMap();
$('.tabButton').click(function() {
if ($(this).hasClass("selected")) {
return;
}
var $that = $(this);
var name = $that.attr("data-name");
var $listWrapper = $('#' + name);
if ($that.data("loaded")) {
$.noop(); //dont load data
} else {
$that.data("loaded", true);
var $list = $('#' + name + 'List');
var url = API_BASE + name + "/";
var $loadingLi = $('<div />').text("Loading...").appendTo($list);
$.getJSON(url, {'srid': 3857}, function(items) {
$loadingLi.remove();
$.each(items, function(i,v) {
var $li = $('<div />')
.addClass("listItem")
.appendTo($list);
var $txt = $('<span />').addClass("listItemText").text(v).appendTo($li);
});
});
}
$('.listWrapper').hide();
$listWrapper.show();
$('.selected').removeClass("selected");
$that.addClass("selected");
});
$('.list').click(function(e) {
var name = $(this).attr("id").replace("sList", ""); //FIXME: stick name in a data attr or so?
var $target = $(e.target).parent();
if (!$target.hasClass('listItem')) {
return;
}
if ($target.data("loading")) {
return;
}
if ($target.hasClass("selectedListItem")) {
$target.find(".stopsList").hide().remove();
$target.removeClass("selectedListItem");
return;
}
$('.selectedListItem').find(".stopsList").hide().remove();
$('.selectedListItem').removeClass("selectedListItem");
$target.addClass("selectedListItem");
if ($target.data("hasList")) {
var $stopsList = $target.find(".stopsList");
$stopsList.slideDown();
return;
/*
var $stopsList = $target.find(".stopsList");
if (!$stopsList.is(":visible")) {
$stopsList.slideDown();
} else {
$stopsList.slideUp();
$target.removeClass("selectedListItem");
}
return;
*/
}
var url = API_BASE + name + "/" + $target.find(".listItemText").text();
$target.data("loading", true);
var $loading = $('<span />').addClass("loadingSpan").text("Loading...").appendTo($target);
$('#stopForm').remove();
$('#formCol').empty();
$.getJSON(url, {'srid': 3857}, function(obj) {
$loading.remove();
var stopsGeojson = obj.stops;
var stops = stopsGeojson.features;
var $stopsList = getStopsList(stops);
var stopsWithGeom = [];
$.each(stops, function(i,v) {
if (!$.isEmptyObject(v.geometry)) {
stopsWithGeom.push(v);
}
});
stopsGeojson.features = stopsWithGeom;
var currFeatures = jsonLayer.features;
jsonLayer.removeFeatures(currFeatures);
if (stopsWithGeom.length !== 0) {
jsonLayer.addFeatures(geojson_format.read(stopsGeojson));
var maxExtent = jsonLayer.getDataExtent();
map.zoomToExtent(maxExtent);
}
$target.append($stopsList);
// $target.data("hasList", true);
$target.data("loading", false);
});
});
$('.listSearch').keyup(function(e) {
var val = $(this).val();
var name = $(this).attr("id").replace("Search", "");
var $list = $('#' + name + "List");
$list.find(".listItem").each(function() {
var $that = $(this);
var txt = $that.find(".listItemText").text();
if (txt.indexOf(val) == -1) {
$that.hide();
} else {
$that.show();
}
});
});
});
function getStopsList(stops) {
var $ul = $('<ul />')
.addClass("stopsList")
.click(function(e) {
var $target = $(e.target);
if ($target.hasClass("selectedStop")) {
return;
}
// $('.selectedStop').removeClass("selectedStop");
// $target.addClass("selectedStop");
var props = $target.data("properties");
var geom = $target.data("geometry");
var $form = getStopForm(props, geom);
var slug = $target.data("slug");
if ($target.hasClass("has_point")) {
selectStopOnMap(slug);
} else {
selectStopNotOnMap(slug);
}
$('#formCol').find("#stopForm").remove();
$('#formCol').empty();
$('#formCol').append($form);
});
$.each(stops, function(i,v) {
var props = v.properties;
var geom = v.geometry;
var $li = $('<li />')
.addClass("stopItem")
.data("slug", props.slug)
.addClass(props.slug) //FIXME: please dont set data AND addClass AND include slug in properties.
.data("properties", props)
.data("geometry", geom)
.text(props.display_name)
.appendTo($ul);
$.isEmptyObject(geom) ? $li.addClass("no_has_point") : $li.addClass("has_point");
});
return $ul;
}
function getStopForm(stop, geom) {
// console.log(stop);
// console.log(geom);
var lon = !$.isEmptyObject(geom) ? geom.coordinates[0] : '';
var lat = !$.isEmptyObject(geom) ? geom.coordinates[1] : '';
var $div = $('<div />');
var $displayName = $('<h2 />').text(stop.display_name).appendTo($div);
var $slug = $('<div />').addClass("stopSlug").text(stop.slug).appendTo($div);
var $road = $("<div />").addClass("stopRoad").text("Road: " + stop.road).appendTo($div);
var $direction = $("<div />").addClass("stopDirection").text("Direction: " + stop.direction).appendTo($div);
var $routes = $('<div />').text("Routes: " + stop.routes).appendTo($div);
// var $formLabel = $("<div />").text("Edit:").appendTo($div);
var $form = $('<form />').attr("id", "stopForm").appendTo($div);
var $display_name_label = $('<label />').attr("for", "displayName").text("Display Name:").appendTo($form);;
var $display_name_input = $('<input />')
.val(stop.display_name)
.attr("id", "displayName")
.blur(function() {
$form.submit();
})
.appendTo($form);
$('<br />').appendTo($form);
var $name_mr_label = $('<label />').attr("for", "displayNameMr").text("Marathi Name:").appendTo($form);
var $name_mr_input = $('<input />')
.val(stop.name_mr)
.attr("id", "displayNameMr")
.blur(function() {
$form.submit();
})
.appendTo($form);
$('<br />').appendTo($form);
var $alt_names_label = $('<label />').attr("for", "altNames").text("Alternative Names:").appendTo($form);
var $alt_names_input = $('<input />')
.val(stop.alternative_names)
.attr("id", "altNames")
.blur(function() {
$form.submit();
})
.appendTo($form);
$('<br />').appendTo($form);
$('<input />').attr("type","button").val("Save")
.click(function () {
$form.submit();
})
.appendTo($form);
var $lat_input = $('<input />').attr("type", "hidden").val(lat).attr("id", "lat").appendTo($form);
var $lon_input = $('<input />').attr("type", "hidden").val(lon).attr("id", "lon").appendTo($form);
$form.submit(function(e) {
e.preventDefault();
var oldProps = $('.selectedStop').data("properties");
var geojson = {
'type': 'Feature',
'properties': {
'display_name': $display_name_input.val(),
'name_mr': $name_mr_input.val(),
'alternative_names': $alt_names_input.val()
},
'geometry': {
'type': 'Point',
'coordinates': [parseFloat($lon_input.val()), parseFloat($lat_input.val())]
}
};
var props = $.extend(oldProps, geojson.properties);
$('.selectedStop').data("properties", props);
var geojsonString = JSON.stringify(geojson);
//console.log(geojsonString);
var url = API_BASE + "stop/" + stop.slug + "?srid=3857";
var $postXHR = $.post(url, {'geojson': geojsonString}, function(response) {
if (response.errors) {
alert("error saving");
}
//console.log(response);
}, "json");
$postXHR.fail(function(e) {
alert('failed ' + JSON.stringify(e));
});
});
return $div;
}
function initMap() {
var center = new OpenLayers.LonLat(8110203.9998955, 2170000.4068373);
map = new OpenLayers.Map("mapCol", {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
var layers = [];
// layers[0] = new OpenLayers.Layer.OSM();
layers[0] = new OpenLayers.Layer.OSM();
layers[1] = new OpenLayers.Layer.Bing({
name: "Bing Aerial",
type: "Aerial",
key: "AqGpO7N9ioFw3YHoPV3C8crGfJqW5YST4gGKgIOnijrUbitLlgcAS2A0M9SJrUv9",
});
geojson_format = new OpenLayers.Format.GeoJSON();
//
//yes, jsonLayer is global. Yes, I know it's wrong.
jsonLayer = layers[2] = new OpenLayers.Layer.Vector("Bus Stops");
map.addLayers(layers);
jsonLayer.events.on({
'featureselected': onFeatureSelect,
'featureunselected': onFeatureUnselect
});
map.setCenter(center, 12);
var navigationControl = new OpenLayers.Control.Navigation({
defaultDblClick: function(event) {
//var xy = event.xy;
var lonlat = map.getLonLatFromPixel(event.xy);
var $stopForm = $('#stopForm');
if ($stopForm.length === 0) {
return;
}
var slug = $('#formCol').find('.stopSlug').text();
//console.log("slug", slug);
var stop = $('.selectedStop').data("properties");
$('.selectedStop').data("geometry", {
'coordinates': [lonlat.x, lonlat.y]
});
var hasPoint = $('.selectedStop').hasClass('has_point');
$('#lon').val(lonlat.lon);
$('#lat').val(lonlat.lat);
$stopForm.submit();
if (hasPoint) {
var feature = getStopFromSlug(slug);
feature.move(lonlat);
} else {
var pt = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
var feature = new OpenLayers.Feature.Vector(pt, stop);
$('.selectedStop').removeClass("no_has_point").addClass("has_point");
jsonLayer.addFeatures([feature]);
mapControl.select(feature);
}
return;
}
});
map.addControl(navigationControl);
// Feature selection control
mapControl = new OpenLayers.Control.SelectFeature(jsonLayer, {
clickout: false,
toggle: true
});
//map.addControl(new OpenLayers.Control.ZoomPanel());
map.addControl(mapControl);
mapControl.activate();
// Add a LayerSwitcher since we now have Bing
map.addControl(new OpenLayers.Control.LayerSwitcher());
// Add a permalink that opens the relevant view in OSM.org in a different window
var permalink = new OpenLayers.Control.Permalink({base: "http://www.openstreetmap.org/"});
map.addControl(permalink);
$(".olControlPermalink a").attr("target","_blank").html("View in OSM");
}
function onFeatureSelect(e) {
//alert(arguments);
//console.log(feature);
// console.log(e.feature);
var slug = e.feature.attributes.slug;
//alert("selected " + slug);
$('.selectedStop').removeClass("selectedStop");
highlightStop(slug);
var stop = e.feature.attributes;
var geom = {
'coordinates': [e.feature.geometry.x, e.feature.geometry.y]
};
var $form = getStopForm(stop, geom);
$('#stopForm').remove();
$('#formCol').empty();
$('#formCol').append($form);
// var matchedStops = $('.' + slug);
// matchedStops.click();
// matchedStops.addClass('highlightedStop');
}
function onFeatureUnselect(e) {
var slug = e.feature.attributes.slug;
//alert("unselected " + slug);
unhighlightStop(slug);
$('#stopForm').remove();
$('#formCol').empty();
// var matchedStops = $('.' + slug);
// matchedStops.removeClass('selectedStop');
}
function highlightStop(slug) {
$('.' + slug).addClass("selectedStop");
}
function unhighlightStop(slug) {
$('.' + slug).removeClass("selectedStop");
}
function getStopFromSlug(slug) {
var features = jsonLayer.features;
var matchedLayer = false;
for (var i=0; i<features.length; i++) {
var feature = features[i];
if (feature.attributes.slug === slug) {
matchedLayer = feature;
}
}
return matchedLayer;
}
function selectStopNotOnMap(slug) {
var selectedFeature = getCurrentlySelectedFeature();
if (selectedFeature) {
var currentSlug = selectedFeature.attributes.slug;
unhighlightStop(slug);
mapControl.unselect(selectedFeature);
} else {
$('.selectedStop').removeClass("selectedStop");
}
highlightStop(slug);
}
function selectStopOnMap(slug) {
var feature = getStopFromSlug(slug);
var selectedFeature = getCurrentlySelectedFeature();
if (selectedFeature) {
mapControl.unselect(selectedFeature);
} else {
$('.selectedStop').removeClass("selectedStop");
}
mapControl.select(feature);
//map.setCenter(feature.geometry);
var lonLat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
map.setCenter(lonLat);
}
//return currently selected feature or false
function getCurrentlySelectedFeature() {
var selectedFeatures = jsonLayer.selectedFeatures;
if (selectedFeatures.length > 0) {
return jsonLayer.selectedFeatures[0];
// mapControl.unselect(selectedFeature);
} else {
return false;
}
}
})();