dynamic legend for fusion table map - google-fusion-tables

I have a modified sample of fusion table map and its code is given below.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<title>Fusion Tables Layer Example: Dynamic styles and templates</title>
<style>
body { font-family: Arial, sans-serif; font-size: 12px; }
#map-canvas { height: 660px; width: 100%; }
#map-canvas img { max-width: none; }
#visualization { height: 100%; width: 100%; }
#legend1 { width: 200px; background: #FFF;padding: 10px; margin: 5px;font-size: 12px;font-family: Arial, sans-serif;border: 1px solid black;}
.color {border: 1px solid;height: 12px;width: 15px; margin-right: 3px;float: left;}
.red {background: #C00;}
.blue {background: #06C;}
</style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(37.4, -122.1),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Address',
from: '15UY2pgiz8sRkq37p2TaJd64U7M_2HDVqHT3Quw'
},
map: map,
styleId: 1,
templateId: 1
});
var legend1 = document.createElement('div');
legend1.id = 'legend1';
var content1 = [];
content1.push('<p><div class="color red"></div>Red markers</p>');
legend1.innerHTML = content1.join('');
legend1.index = 1;
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(legend1);
var legend2 = document.createElement('div');
legend2.id = 'legend1';
var content2 = [];
content2.push('<p><div class="color blue"></div>Blue markers</p>');
legend2.innerHTML = content2.join('');
legend2.index = 1;
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(legend2);
google.maps.event.addDomListener(document.getElementById('style'),
'change', function() {
var selectedStyle = this.value;
layer.set('styleId', selectedStyle);
var selectedTemplate = this.value;
layer.set('templateId', selectedTemplate);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div>
<label>Select style:</label>
<select id="style">
<option value="1">Red</option>
<option value="2">Blue</option>
</select>
</div>
</body>
</html>
How can I add dynamic legend to this map so that when selecting blue markers, the legend should show only a blue marker with its name and when selecting red markers it will show the red marker icon in legend.

You must clear the controls(remove all legends) and then add the desired legend again.
right before
google.maps.event.addDomListener(document.getElementById('style')[...]
add this code:
//we need a copy of all legends(nodes),
//otherwise they wouldn't be accessible when they have been removed
var clonedArray = map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.getArray().slice();
//observe changes of the styleId
google.maps.event.addListener(layer,'styleid_changed',function(){
//clear the controls
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].clear();
//add the desired control
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(clonedArray[this.get('styleId')-1])
});
//trigger the event to initially have only the legend
//based on the selected style
google.maps.event.trigger(layer,'styleid_changed');
Demo: http://jsfiddle.net/doktormolle/t3nY6/

Related

Validate Grid Data in ASP.NET MVC

I have created an editable WebGrid in ASP.NET MVC 4 through which I will be able to edit, delete and update the data in the grid itself.
But I can't validate data in edit row in WebGrid.
I tried to search posts, without any result either, maybe I didn't use the right words.
How to do resolve this?
My code is shown below:
View
#model IEnumerable<Customer>
#{
Layout = null;
WebGrid webGrid = new WebGrid(source: Model, canPage: true, canSort: false);
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width"/>
<title>Index</title>
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
.Grid {
border: 1px solid #ccc;
border-collapse: collapse;
}
.Grid th {
background-color: #F7F7F7;
font-weight: bold;
}
.Grid th, .Grid td {
padding: 5px;
width: 150px;
border: 1px solid #ccc;
}
.Grid, .Grid table td {
border: 0px solid #ccc;
}
.Grid th a, .Grid th a:visited {
color: #333;
}
</style>
</head>
<body>
#webGrid.GetHtml(
htmlAttributes: new { #id = "WebGrid", #class = "Grid" },
columns: webGrid.Columns(
webGrid.Column(header: "Customer Id", format: #<span class="label">#item.CustomerId</span>, style: "CustomerId" ),
webGrid.Column(header: "Name", format: #<span><span class="label">#item.Name</span>
<input class="text" type="text" value="#item.Name" style="display:none"/></span>, style: "Name"),
webGrid.Column(header: "Country", format: #<span><span class="label">#item.Country</span>
<input class="text" type="text" value="#item.Country" style="display:none"/></span>, style: "Country"),
webGrid.Column(format:#<span class="link">
<a class="Edit" href="javascript:;">Edit</a>
<a class="Update" href="javascript:;" style="display:none">Update</a>
<a class="Cancel" href="javascript:;" style="display:none">Cancel</a>
</span> )))
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
//Edit event handler.
$("body").on("click", "#WebGrid TBODY .Edit", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find(".text").length > 0) {
$(this).find(".text").show();
$(this).find(".label").hide();
}
});
row.find(".Update").show();
row.find(".Cancel").show();
$(this).hide();
});
//Update event handler.
$("body").on("click", "#WebGrid TBODY .Update", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find(".text").length > 0) {
var span = $(this).find(".label");
var input = $(this).find(".text");
span.html(input.val());
span.show();
input.hide();
}
});
row.find(".Edit").show();
row.find(".Cancel").hide();
$(this).hide();
var customer = {};
customer.CustomerId = row.find(".CustomerId").find(".label").html();
customer.Name = row.find(".Name").find(".label").html();
customer.Country = row.find(".Country").find(".label").html();
$.ajax({
type: "POST",
url: "/Home/UpdateCustomer",
data: '{customer:' + JSON.stringify(customer) + '}',
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
//Cancel event handler.
$("body").on("click", "#WebGrid TBODY .Cancel", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find(".text").length > 0) {
var span = $(this).find(".label");
var input = $(this).find(".text");
input.val(span.html());
span.show();
input.hide();
}
});
row.find(".Edit").show();
row.find(".Update").hide();
$(this).hide();
});
</script>
</body>
</html>

How to check if a selected string contains a substring of an highlight in epubjs

As the title above.
Assume, I have a paragraph:
It will be seen that this mere painstaking burrower and grub-worm of a poor devil of a Sub-Sub appears to have gone through the long Vaticans and street-stalls of the earth..
The bold string is a highlight. When I drag my mouse to select string
grub-worm of a poor devil of a Sub-Sub
Then I want to check if my selected text contains the highlight(or the part of the highlight) or not. How could I do that?
The code below is the example to add a highlight when I select a text.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>EPUB.js Highlights Example</title>
<script src="../dist/epub.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
<link rel="stylesheet" type="text/css" href="examples.css">
<style type="text/css">
::selection {
background: yellow;
}
#extras {
width: 600px;
margin: 40px auto;
}
#highlights {
list-style: none;
margin-left: 0;
padding: 0;
}
#highlights li {
list-style: none;
margin-bottom: 20px;
border-top: 1px solid #E2E2E2;
padding: 10px;
}
#highlights a {
display: block;
}
#viewer.spreads {
top: 0;
margin-top: 50px;
}
[ref="epubjs-mk"] {
background: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycgeG1sbnM6eGxpbms9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnIHg9JzBweCcgeT0nMHB4JyB2aWV3Qm94PScwIDAgNzUgNzUnPjxnIGZpbGw9JyNCREJEQkQnIGlkPSdidWJibGUnPjxwYXRoIGNsYXNzPSdzdDAnIGQ9J00zNy41LDkuNEMxOS42LDkuNCw1LDIwLjUsNSwzNC4zYzAsNS45LDIuNywxMS4zLDcuMSwxNS42TDkuNiw2NS42bDE5LTcuM2MyLjgsMC42LDUuOCwwLjksOC45LDAuOSBDNTUuNSw1OS4yLDcwLDQ4LjEsNzAsMzQuM0M3MCwyMC41LDU1LjQsOS40LDM3LjUsOS40eicvPjwvZz48L3N2Zz4=") no-repeat;
width: 20px;
height: 20px;
cursor: pointer;
margin-left: 0;
}
</style>
</head>
<body>
<div id="frame">
<div id="viewer" class="spreads"></div>
<a id="prev" href="#prev" class="arrow">‹</a>
<a id="next" href="#next" class="arrow">›</a>
</div>
<div id="extras">
<ul id="highlights"></ul>
</div>
<script>
// Load the opf
var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
var rendition = book.renderTo("viewer", {
width: "100%",
height: 600,
ignoreClass: 'annotator-hl',
manager: "continuous"
});
var displayed = rendition.display(6);
// Navigation loaded
book.loaded.navigation.then(function(toc){
// console.log(toc);
});
var next = document.getElementById("next");
next.addEventListener("click", function(){
rendition.next();
}, false);
var prev = document.getElementById("prev");
prev.addEventListener("click", function(){
rendition.prev();
}, false);
var keyListener = function(e){
// Left Key
if ((e.keyCode || e.which) == 37) {
rendition.prev();
}
// Right Key
if ((e.keyCode || e.which) == 39) {
rendition.next();
}
};
rendition.on("keyup", keyListener);
document.addEventListener("keyup", keyListener, false);
rendition.on("relocated", function(location){
// console.log(location);
});
// Apply a class to selected text
rendition.on("selected", function(cfiRange, contents) {
rendition.annotations.highlight(cfiRange, {}, (e) => {
console.log("highlight clicked", e.target);
});
contents.window.getSelection().removeAllRanges();
});
this.rendition.themes.default({
'::selection': {
'background': 'rgba(255,255,0, 0.3)'
},
'.epubjs-hl' : {
'fill': 'yellow', 'fill-opacity': '0.3', 'mix-blend-mode': 'multiply'
}
});
// Illustration of how to get text from a saved cfiRange
var highlights = document.getElementById('highlights');
rendition.on("selected", function(cfiRange) {
book.getRange(cfiRange).then(function (range) {
var text;
var li = document.createElement('li');
var a = document.createElement('a');
var remove = document.createElement('a');
var textNode;
if (range) {
text = range.toString();
textNode = document.createTextNode(text);
a.textContent = cfiRange;
a.href = "#" + cfiRange;
a.onclick = function () {
rendition.display(cfiRange);
};
remove.textContent = "remove";
remove.href = "#" + cfiRange;
remove.onclick = function () {
rendition.annotations.remove(cfiRange);
return false;
};
li.appendChild(a);
li.appendChild(textNode);
li.appendChild(remove);
highlights.appendChild(li);
}
})
});
</script>
</body>
</html>
I assume you only know the functionality of epubjs you listed above. From rendition.on(selected,...), we can get output: cfiRange. From book.getRange(cfiRange).then(function (range)..., we can get output: range.
That means whenever we select a word or sentence, we get cfiRange and range.
cfiRange is epubcfi(/6/10[id139]!/4/2[filepos12266]/6,/3:1,/3:4, which based on position of the selected word. I don't know how it calculates/works but if you do then you can check if the cfiRange contains a existing highlight word's cfiRange.
range.toString() can give you the text. if your application is only storing a word. then you can check if the new selected word == or contain your existing highlight word.

calculateDistances() function doesn't work taking start/end value from a select

I'd like to calculate the distance between 2 points, taking coordinates for each point from a select. The following is the code so far
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Calcola il tuo itinerario</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0;
padding: 0;
}
#panel {
position: absolute;
top: 5px;
left: 20%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
width: 300px;
}
/*
Provide the following styles for both ID and class,
where ID represents an actual existing "panel" with
JS bound to its name, and the class is just non-map
content that may already have a different ID with
JS bound to its name.
*/
#panel, .panel {
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
#panel select, #panel input, .panel select, .panel input {
font-size: 15px;
}
#panel select, .panel select {
width: 100%;
}
#panel i, .panel i {
font-size: 12px;
}<br>
#outputDiv {
font-size: 11px;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var chiesamadre = new google.maps.LatLng(37.485558, 13.987883);
var mapOptions = {
zoom:17,
center: chiesamadre
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function calculateDistances() {
var start = new google.maps.Map(document.getElementById('start').value);
var end = new google.maps.Map(document.getElementById('end').value);
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origin:start,
destination:end,
travelMode: google.maps.TravelMode.WALKING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidHighways: false,
avoidTolls: false
}, callback);
}
function callback(response, status) {
if (status != google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
var origins = response.originAddresses;
var destinations = response.destinationAddresses;
var outputDiv = document.getElementById('outputDiv');
outputDiv.innerHTML = '';
deleteOverlays();
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
addMarker(origins[i], false);
for (var j = 0; j < results.length; j++) {
addMarker(destinations[j], true);
outputDiv.innerHTML += origins[i] + ' to ' + destinations[j]
+ ': ' + results[j].distance.text + ' in '
+ results[j].duration.text + '<br>';
}
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="panel">
<b>Partenza: </b>
<select id="start" onChange="calcRoute();">
<option value="37.485558, 13.987883">Chiesa Madre</option>
<option value="37.484813, 13.983602">Calvario</option>
<option value="37.484474, 13.986312">Torre civica con orologi</option>
<option value="37.485703, 13.986480">Chiesa di San Giuseppe</option>
<option value="37.491049, 13.988843">Torre Con Orologi Cristo re</option>
<option value="37.484507, 13.989363">Chiesa Santa Maria del Rosario</option>
<option value="37.472353, 13.945771">Vassallaggi</option>
</select>
<b>Arrivo: </b>
<select id="end" onChange="calcRoute();">
<option value="37.485558, 13.987883">Chiesa Madre</option>
<option value="37.484813, 13.983602">Calvario</option>
<option value="37.484474, 13.986312">Torre civica con orologi</option>
<option value="37.485703, 13.986480">Chiesa di San Giuseppe</option>
<option value="37.491049, 13.988843">Torre Con Orologi Cristo re</option>
<option value="37.484507, 13.989363">Chiesa Santa Maria del Rosario</option>
<option value="37.472353, 13.945771">Vassallaggi</option>
</select>
<b>Distanza: </b>
<p><button type="button" onClick="calculateDistances();">Calculate
distances</button></p>
<p> <div id="outputDiv"></div></p>
</div>
<div id="map-canvas"></div>
</body>
</html>
calcRoute() function works fine but calculateDistances() function doesn't work, in fact if I click on the "Calculate distances" button after selecting start and end, no text is showed in the white space on the button, where is the div with the expected result of calculated distance. Maybe I did something wrong with the start and end variables of calculateDistances() function. I added this JSfiddle: https://jsfiddle.net/Lnq91j0c/
and this is the link of the page online: http://turismosancataldo.it/calcolo-itinerario-piedi-dist.html
How to fix the function? Thank You for any help.

How to escape "&" character in dryml?

I've got this in my application.dryml file:
<def tag="googlemap">
<html>
<head>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript">
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAIbK8zw8fqY&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var georssLayer = new google.maps.KmlLayer('http://waterwatch.org.au/waterwatch_php/all_sites.php');
georssLayer.setMap(map);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"><div param="map" /></div>
</body>
</html>
</def>
I'm getting an error "Illegal character '&' in raw string" (the param separator in the maps.googleapis.com link.
How do I escape the & character in dryml?

jQuery-UI Date and Time-Range Picker

I'm creating a page to manage the our times at the office (for example when we made home-office). This requires selecting a date and then time-range.
I know about the Date-Picker from jQuery-UI, and there also seems to be something interesting for time picking. But since I need a start and end time, a UI to select date and time range would be perfect. Is there something you could recommend?
Visit jQuery UI datepicker range example and click "view source".
Combine with jquery timepicking solution found here.
That should hopefully get you going in the right direction.
Another interesting option could be handle the date in the date-picker and the time-range with a separated UI component (in this specific case start and end time are in the same day).
You can take a look at these time-range sliders:
$("#slider-range").slider(options_object);
http://jsfiddle.net/jrweinb/MQ6VT/
http://marcneuwirth.com/blog/2010/02/21/using-a-jquery-ui-slider-to-select-a-time-range/
$(document).ready(function(){
$(".datetimepicker").datetimepicker({
timepicker: true,
allowTimes: [
'12:00', '12:30', '13:00','13:30','14:00',
'14:30', '15:00', '15:30', '16:00', ]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.16/jquery.datetimepicker.full.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.16/jquery.datetimepicker.css">
<input type="text" class="datetimepicker" />
You can select time using this slider.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 10px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 23px;
height: 24px;
border: 0;
background: url('https://www.w3schools.com/howto/contrasticon.png');
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 23px;
height: 24px;
border: 0;
background: url('https://www.w3schools.com/howto/contrasticon.png');
cursor: pointer;
}
</style>
</head>
<body>
<div class="slidecontainer">
<input type="range" min="10" max="22" maxvalue="10" class="slider" id="myRange">
<p>Value: <span id="demo">4PM</span></p>
</div>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
slider.oninput = function() {
var time=slider.value;
if(time<12){
time=time+'AM';
}
else if(time>12){
time=time-12+'PM';
}
else if(time=12){
time=12+'PM';
}
//alert(time);
output.innerHTML = time;
}
</script>
</body>
</html>

Resources