Marker Clustering does not display - javascript

I am trying to cluster markers (each manually created) on my map using the Leaflet.markercluster plugin.
Does anybody know what I am doing incorrectly? I see the map and my two points but not the cluster of the two.
Additionally, I want to populate the map with many markers but it is not working. Thank you!
<!DOCTYPE html>
<html>
<head>
<!-- need jQuery for AJXA -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="screen.css" />
<link rel="stylesheet" href="../Desktop/MarkerCluster.css" />
<link rel="stylesheet" href="../Desktop/MarkerCluster.Default.css" />
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/leaflet.markercluster.js"></script>
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/MarkerCluster.css"></script>
<script src ="https://unpkg.com/browse/leaflet.markercluster#1.4.1/dist/MarkerCluster.Default.css"></script>
<!-- Code from https://github.com/macek/jquery-serialize-object -->
<script>
/**
* jQuery serializeObject
* #copyright 2014, macek <paulmacek#gmail.com>
* #link https://github.com/macek/jquery-serialize-object
* #license BSD
* #version 2.5.0
*/
! function(e, i) {
if ("function" == typeof define && define.amd) define(["exports", "jquery"], function(e, r) {
return i(e, r)
});
else if ("undefined" != typeof exports) {
var r = require("jquery");
i(exports, r)
} else i(e, e.jQuery || e.Zepto || e.ender || e.$)
}(this, function(e, i) {
function r(e, r) {
function n(e, i, r) {
return e[i] = r, e
}
function a(e, i) {
for (var r, a = e.match(t.key); void 0 !== (r = a.pop());)
if (t.push.test(r)) {
var u = s(e.replace(/\[\]$/, ""));
i = n([], u, i)
} else t.fixed.test(r) ? i = n([], r, i) : t.named.test(r) && (i = n({}, r, i));
return i
}
function s(e) {
return void 0 === h[e] && (h[e] = 0), h[e]++
}
function u(e) {
switch (i('[name="' + e.name + '"]', r).attr("type")) {
case "checkbox":
return "on" === e.value ? !0 : e.value;
default:
return e.value
}
}
function f(i) {
if (!t.validate.test(i.name)) return this;
var r = a(i.name, u(i));
return l = e.extend(!0, l, r), this
}
function d(i) {
if (!e.isArray(i)) throw new Error("formSerializer.addPairs expects an Array");
for (var r = 0, t = i.length; t > r; r++) this.addPair(i[r]);
return this
}
function o() {
return l
}
function c() {
return JSON.stringify(o())
}
var l = {},
h = {};
this.addPair = f, this.addPairs = d, this.serialize = o, this.serializeJSON = c
}
var t = {
validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
key: /[a-z0-9_]+|(?=\[\])/gi,
push: /^$/,
fixed: /^\d+$/,
named: /^[a-z0-9_]+$/i
};
return r.patterns = t, r.serializeObject = function() {
return new r(i, this).addPairs(this.serializeArray()).serialize()
}, r.serializeJSON = function() {
return new r(i, this).addPairs(this.serializeArray()).serializeJSON()
}, "undefined" != typeof i.fn && (i.fn.serializeObject = r.serializeObject, i.fn.serializeJSON = r.serializeJSON), e.FormSerializer = r, r
});
</script>
<div id="left">
<div id="google-form">
<form action="https://docs.google.com/forms/d/e/1FAIpQLSe3K5mmm5Fzezpltxb0dmElMxJYMpyMkujwPjbjPbiGRa1MPQ/viewform?usp=sf_link" target="hiddenFrame">
<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>
<h2>Tell us about a time you cried at Yale.</h2>
<p class="caption">Responses may be edited for clarity and length.</p>
<textarea jsname="YPqjbf" jscontroller="gZjhIf" jsaction="input:Lg5SV;ti6hGc:XMgOHc;rcuQ6b:WYd;" required="" name="entry.643682983" dir="auto" data-initial-dir="auto"></textarea>
<div id="buttons">
<input type="button" id="drag" value="Add pin to map" name="entry.2117530617">
<input id="location" type="text" jsname="YPqjbf" autocomplete="off" tabindex="0" name="entry.2117530617" value="" required="" dir="auto" data-initial-dir="auto" data-initial-value="" style="display: none">
<input class="button" id="submit" type="submit" value="Submit" disabled="true">
</div>
</form>
</div>
</div>
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 30%;
right: 0;
}
</style>
<script>
</script>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js">
</script>
<div class="marker-menu">
<img class="draggable-marker" src="images/marker-icon.png" alt="marker" />
</div>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var tiles = L.tileLayer('https://api.maptiler.com/maps/streets/256/{z}/{x}/{y}.png?key=wZnhwGRqtomo0QHvxpxW', {
maxZoom: 18,
attribution: '© OpenStreetMap contributors'
}),
latlng = L.latLng(41.310970, -72.931990);
var map = L.map('map', {center: latlng, zoom: 15, layers: [tiles]});
var markers = L.marker([41.310253,-72.92642]);
map.addLayer(markers);
var markers = L.marker([41.310970, -72.931992]);
map.addLayer(markers);
var markers = L.markerClusterGroup();
markers.on('clusterclick', function (a) {
a.layer.spiderfy();
});
function populate() {
for (var i = 0; i < 1000; i++) {
var m = L.marker(getRandomLatLng(map));
markers.addLayer(m);
}
return false;
}
function getRandomLatLng(map) {
var bounds = map.getBounds(),
southWest = bounds.getSouthWest(),
northEast = bounds.getNorthEast(),
lngSpan = northEast.lng - southWest.lng,
latSpan = northEast.lat - southWest.lat;
return L.latLng(
southWest.lat + latSpan * Math.random(),
southWest.lng + lngSpan * Math.random());
}
populate();
map.addLayer(markers);
</script>
</body>
</html>

While your Leaflet-related JS code seems ok, you probably have errors popping in your browser console (open your browser Developer Tools).
Looking at your HTML code:
you load twice Leaflet, making L namespace being overridden the 2nd time
you try loading Leaflet.markercluster only after the first Leaflet load, making only the "first" L namespace being augmented with L.markerClusterGroup factory, whereas the 2nd (final) L does not have it
you try loading Leaflet.markercluster assets through an incorrect path
Therefore:
loading Leaflet only once is enough
make sure to load Leaflet.markercluster after the last Leaflet load
fix the path to Leaflet.markercluster assets (remove the "browse" part)

Related

How to add row in datatable - DC.js

I have a json file that loads sales data for salespeople based on the current year and the previous year.
I created a table in which I show the total sales for each year for each salesperson and, in the last row, I need to load the total for all salespeople added up. As shown in the image below:
I am using dc.dataTable to create my table.
Can you tell me if there is any way in DC.js to create a row in my table to put the total sales?
Here is my code, thank you in advance.
var vendedorTable = dc.dataTable("#Vendedores");
var url = 'http://www.json-generator.com/api/json/get/cgsUhkPSjS?indent=2';
d3.json(url).then(function(data) {
data.forEach(function(d) {
var myCrossfilter = crossfilter(data);
var all = myCrossfilter.groupAll();
dc.dataCount(".dc-data-count")
.dimension(myCrossfilter)
.group(all);
vendedorDim = myCrossfilter.dimension(function(d) {
return d.vendnm;
});
var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
p.totalAno += +v.Vendas_Ano;
p.totalHomologo += +v.Vendas_Ant;
return p;
}
function reduceRemove(p, v) {
p.totalAno -= v.Vendas_Ano;
p.totalHomologo -= v.Vendas_Ant;
return p;
}
function reduceInitial() {
return {
totalAno: 0,
totalHomologo: 0,
};
}
// formatter = d3.format(".3s");
// formatter2 = d3.format(".0%");
//Fake Dimension
rank = function(p) {
return ""
};
function checkRows(d) {
if (d.value.totalAno <= 0 || isNaN(d.value.totalAno) || d.value.totalHomologo <= 0 || isNaN(d.value.totalHomologo)) {
return 0;
}
return d;
}
//vendedorTable
vendedorTable.width(500)
.height(480)
.dimension(vendedorGroup)
.group(rank)
.columns([function(d) {
d = checkRows(d);
while (d != 0) {
return d.key;
}
},
function(d) {
d = checkRows(d);
while (d != 0) {
return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
},
function(d) {
d = checkRows(d);
while (d != 0) {
return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
}
])
.sortBy(function(d) {
return d.value.totalAno
})
.order(d3.descending)
vendedorTable.on('pretransition', function(table) {
table.selectAll('td.dc-table-column')
.on('click', function(d) {
let filters = table.filters().slice();
if (filters.indexOf(d.key) === -1)
filters.push(d.key);
else
filters = filters.filter(k => k != d.key);
if (filters.length === 0)
vendedorDim.filter(null);
else
vendedorDim.filterFunction(function(d) {
return filters.indexOf(d) !== -1;
})
table.replaceFilter([filters]);
dc.redrawAll();
});
let filters = table.filters();
table.selectAll('tr.dc-table-row')
.classed('sel-rows', d => filters.indexOf(d.key) !== -1);
});
dc.renderAll();
});
$('#reset').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null)
dc.redrawAll();
});
$('#resetTable').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null)
dc.redrawAll();
});
});
<head>
<style>
.dc-table-group {
visibility: collapse;
}
tr.dc-table-row.sel-rows {
background-color: lightblue;
}
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>
<title>Vendedores</title>
</head>
<body>
<div class="container-fluid">
<div class="row content">
<div class="col-md-8" style="padding-left: 20px;">
<div class="row marginClass">
<h4 class="pull-left" id="Introduction"><small>Dados fictícios da empresa | Exemplo de Pesquisa
Detalhada |
</small></h4>
<h6 class="dc-data-count" style="float: left;margin-left:5px;">
<span>
<span class="filter-count"></span> selected out of
<span class="total-count"></span> records |
<a id="reset"> Reset All </a>
</span>
</h6>
</div>
<div class="col-md-6">
<br>
<a id="resetTable"> Reset</a>
<table class="table" id="Vendedores">
<thead>
<tr>
<th>Sales</th>
<th>Current Year</th>
<th>Last Year</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</body>
dc.js is the frontend for crossfilter, which is an in-memory database for JavaScript that is tuned for these kinds of dashboards.
You always want to add data on the database side. So the right place to look is in the crossfilter API, and here it is: crossfilter.add()
I might have just left a comment, but since you were nice enough to include running code, let's try it out!
First, let's reserve one of the vendors out of the dataset:
rows = data0.filter(d => d.vendnm === 'JOÃO LUIS');
var data = data0.filter(d => d.vendnm !== 'JOÃO LUIS');
Then, when the Add Row button is clicked, let's add that data and redraw all the associated charts:
$('#addRow').on('click', function() {
myCrossfilter.add(rows);
dc.redrawAll();
});
Notice that if you click Add Row multiple times, the sales for that vendor will double, then triple, because we are displaying an aggregated group, so that vendor gets more and more sales added in.
That's all there is to it!
var vendedorTable = dc.dataTable("#Vendedores");
// lift crossfilter and row so they are visible to addRow handler
var myCrossfilter, rows;
var url = 'http://www.json-generator.com/api/json/get/cgsUhkPSjS?indent=2';
d3.json(url).then(function(data0) {
// save Joao for later
rows = data0.filter(d => d.vendnm === 'JOÃO LUIS');
var data = data0.filter(d => d.vendnm !== 'JOÃO LUIS');
data.forEach(function(d) {
myCrossfilter = crossfilter(data);
var all = myCrossfilter.groupAll();
dc.dataCount(".dc-data-count")
.dimension(myCrossfilter)
.group(all);
vendedorDim = myCrossfilter.dimension(function(d) {
return d.vendnm;
});
var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
function reduceAdd(p, v) {
p.totalAno += +v.Vendas_Ano;
p.totalHomologo += +v.Vendas_Ant;
return p;
}
function reduceRemove(p, v) {
p.totalAno -= v.Vendas_Ano;
p.totalHomologo -= v.Vendas_Ant;
return p;
}
function reduceInitial() {
return {
totalAno: 0,
totalHomologo: 0,
};
}
// formatter = d3.format(".3s");
// formatter2 = d3.format(".0%");
//Fake Dimension
rank = function(p) {
return ""
};
function checkRows(d) {
if (d.value.totalAno <= 0 || isNaN(d.value.totalAno) || d.value.totalHomologo <= 0 || isNaN(d.value.totalHomologo)) {
return 0;
}
return d;
}
//vendedorTable
vendedorTable.width(500)
.height(480)
.dimension(vendedorGroup)
.group(rank)
.columns([function(d) {
d = checkRows(d);
while (d != 0) {
return d.key;
}
},
function(d) {
d = checkRows(d);
while (d != 0) {
return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
},
function(d) {
d = checkRows(d);
while (d != 0) {
return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
minimumFractionDigits: 2
}) + '€';
}
}
])
.sortBy(function(d) {
return d.value.totalAno
})
.order(d3.descending)
vendedorTable.on('pretransition', function(table) {
table.selectAll('td.dc-table-column')
.on('click', function(d) {
let filters = table.filters().slice();
if (filters.indexOf(d.key) === -1)
filters.push(d.key);
else
filters = filters.filter(k => k != d.key);
if (filters.length === 0)
vendedorDim.filter(null);
else
vendedorDim.filterFunction(function(d) {
return filters.indexOf(d) !== -1;
})
table.replaceFilter([filters]);
dc.redrawAll();
});
let filters = table.filters();
table.selectAll('tr.dc-table-row')
.classed('sel-rows', d => filters.indexOf(d.key) !== -1);
});
dc.renderAll();
});
$('#reset').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null)
dc.redrawAll();
});
$('#resetTable').on('click', function() {
vendedorTable.filter(null);
vendedorDim.filter(null)
dc.redrawAll();
});
$('#addRow').on('click', function() {
myCrossfilter.add(rows);
dc.redrawAll();
});
});
<head>
<style>
.dc-table-group {
visibility: collapse;
}
tr.dc-table-row.sel-rows {
background-color: lightblue;
}
</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>
<title>Vendedores</title>
</head>
<body>
<div class="container-fluid">
<div class="row content">
<div class="col-md-8" style="padding-left: 20px;">
<div class="row marginClass">
<h4 class="pull-left" id="Introduction"><small>Dados fictícios da empresa | Exemplo de Pesquisa
Detalhada |
</small></h4>
<h6 class="dc-data-count" style="float: left;margin-left:5px;">
<span>
<span class="filter-count"></span> selected out of
<span class="total-count"></span> records |
<a id="reset"> Reset All </a>
</span>
</h6>
</div>
<div>
<a id="addRow"> Add Row </a>
</div>
<div class="col-md-6">
<br>
<a id="resetTable"> Reset</a>
<table class="table" id="Vendedores">
<thead>
<tr>
<th>Sales</th>
<th>Current Year</th>
<th>Last Year</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</body>

How to get function to run after previous function has executed

So I have been working on a website what gets some information from a google sheet cell and it uses that to color a google maps overlay. The problem i'm running into is that the map overlay seems to be running before the cell information is retrieved. I'm not sure how to get the map overlay to wait until it has the info it needs.
Ultimately i'm going to have to get multiple cell values so I don't want to call my map every time I run getCell() hence me not putting myMap() inside the done() of $.getJSON
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<style type="text/css">
</style>
<script>
/** This is the ID of the google sheet **/
//This is the google sheet ID of the google sheet with the graphs for the event.
var theSheetID = "1eAP6dugifHIHRSgnc8Mx-FdzriDBP5r0vn8yq0ShknA";
var typeOfEvent = "Event";
var eventManager = "Jeb";
var managerCell = "123-456-789";
//This is the google sheet ID of the google sheet with the lot values for the event.
var theMapSheetID = "1oUW8EvxlSMArW1qTQMxVJua1QrgCOgo5G545Jb4OZ-4";
var workSheetID = "default";
//duplicate these for every cell you are want to access
var theRow = "1";
var theColumn = "1";
//make duplicates of this variable for each lot you have
//i.e. lot
var theLot;
var theLot1;
//theLot=20;
$(document).ready(function() {
getCell = function() {
var api = 'https://spreadsheets.google.com/feeds/cells/';
var spreadsheet = theMapSheetID;
var worksheet = workSheetID;
var row = theRow;
var col = theColumn;
var row1 = 2;
var col2 = 2;
var url = api + spreadsheet + '/' + worksheet + '/public/basic/R' + row + 'C' + col + '?alt=json';
$.getJSON(url)
.done(function(data) {
console.log(data)
if (data.entry) {
theLot = parseInt(data.entry.content['$t']);
// return $.Deferred();
//myMap();
} else {}
})
.fail(function() {});
}
//$.when(getCell()).then(myMap());
//myMap();
});
</script>
<script>
function myMap() {
//theLot = 15;
var p1 = new google.maps.LatLng(41.051651, -75.515626);
var p2 = new google.maps.LatLng(41.048082, -75.521755);
var p3 = new google.maps.LatLng(41.048006, -75.522286);
var p4 = new google.maps.LatLng(41.051565, -75.5288822);
var p5 = new google.maps.LatLng(41.056059, -75.523349);
var p6 = new google.maps.LatLng(41.053316, -75.520697);
var mapCanvas = document.getElementById("map");
var mapOptions = {
center: p2,
zoom: 15
};
var map = new google.maps.Map(mapCanvas, mapOptions);
// var map = new google.maps.Map(document.getElementById("googleMap"),mapOptions);
var theColor;
//alert(theLot);
var myCenter = new google.maps.LatLng(41.051629, -75.522953);
var marker = new google.maps.Marker({
position: myCenter
});
marker.setMap(map);
var infowindow = new google.maps.InfoWindow({
content: theLot.toString()
});
infowindow.open(map, marker);
if (theLot < 25) {
theColor = "#ff0000";
} else if (theLot > 25 && theLot < 50) {
theColor = "#fff200";
} else if (theLot > 50 && theLot < 75) {
theColor = "#aaff00";
} else {
theColor = "#00ff00";
}
var lotOverlay = new google.maps.Polygon({
path: [p1, p2, p3, p4, p5, p6],
strokeColor: "#000000",
strokeOpacity: 0.0,
strokeWeight: 2,
fillColor: theColor,
fillOpacity: 0.5
});
lotOverlay.setMap(map);
}
</script>
<body>
<br />
<br />
<div class="container">
</div>
<br />
<div class="container" style="text-align:center; max-width: 42em;">
<div class="jumbotron">
<!-- Event Name -->
<div align="center">
<h2>Graduation 2017</h2>
<h4>Please contact us for more detailed information:</h4>
<script type="text/javascript">
document.write("<h4>" + typeOfEvent + " Manager: " + eventManager + "</h4><br />");
document.write(" <div class=\"row\"> Call &nbsp Text</div>");
</script>
</div>
</div>
<!-- Link to ELP -->
View Event Logistics Plan (ELP)
</div>
<hr width="100%" size="3" color="#0000FF" />
<div class="container" align="Center">
<div class="row">
<div class="col-lg-6">
<!-- Google Sheet Overview -->
<script type="text/javascript">
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubchart?oid=784983700&format=interactive&chrome=false\" width=\"600\" height =\"400\" frameborder=\"0\"></iframe>");
</script>
</div>
<div class="col-lg-6">
<!-- Google Sheet Flow -->
<script>
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubhtml?gid=225087979&single=true&headers=false&chrome=false\" width=\"600\" height =\"400\" frameborder=\"0\"></iframe>");
</script>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<!-- Google Sheet Deatils -->
<script>
document.write("<iframe src=\"https://docs.google.com/spreadsheets/d/" + theSheetID + "/pubhtml?gid=328375376&gridlines=false&range=a1:l20&chrome=false\" width = \"1000\" height =\"600\" frameborder=\"0\"></iframe>");
</script>
</div>
<div class="col-lg-12">
<div id="map" style="width:80%;height:500px"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBfWJMAiVJy9LcuMF_vogE_KawTRFaFxig&callback=myMap"></script>
</div>
</div>
</div>
<br />
<br />
</body>
</html>
JavaScript statements are executed line by line. However, with effects, the next line of code can be run even though the effect is not finished. This can create errors.
To prevent this, you can create a callback function. All it is, you can pass the function as an argument and it will be executed last.
$("button").click(function(){
$("p").hide("slow", function(){
alert("The paragraph is now hidden");
});
});
https://www.w3schools.com/jquery/jquery_callback.asp
if you gonna call it like that, then you can get an alert before hide is finished executing.
$("button").click(function(){
$("p").hide("slow");
alert("The paragraph is now hidden");
});

Only one of two practically identical JavaScript functions being run

I'm probably being very stupid here...
I have two JavaScript functions that are practically identical except each one refers to a different element.
The idea is to show and hide a toast/notification when the document loads.
For one element (errorexplanationcontainer), it works... For the other (alert), it doesn't...
CODE FOR errorexplanationcontainer (WORKS)
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.onload = function() {
var z = document.getElementById("errorexplanationcontainer")
z.className = "show";
setTimeout(function(){ z.className = z.className.replace("show", ""); }, 3000);
}
</script>
^^ This is copied and pasted from the inspect window within Google Chrome. As you can see, the script ran successfully. We know this because class="" is absent in the source document and has been added by the script (after showing class="show" for 3 seconds).
CODE FOR alert (DOESN'T WORK)
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.onload = function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function(){ y.className = y.className.replace("show", ""); }, 3000);
}
</script>
^^ No class="" here! The script has not worked...
FULL HTML DOC
<html class="mdl-js"><head>
<title>Dennis' Coffee Hut | CuppaDesk</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/assets/favicon-16x16-347e46971826b54de74f354ae410242483f471bb3051a5f948d83af70770dadc.png" sizes="16x16">
<link rel="icon" type="image/png" href="/assets/favicon-32x32-ac516884b2aa2ea870ddfbd0ae383c0dd66ec1a640181174ac7adaba8e7ccd7d.png" sizes="32x32">
<link rel="apple-touch-icon" type="image/x-icon" href="/assets/apple-touch-icon-af3f73bee131a689a15fede0d2d6f7cf9698786524670279ac74cd128ec5dc40.png" sizes="180x180">
<link rel="mask-icon" type="image/x-icon" href="/assets/safari-pinned-tab-4f97411db829aebf4a4796a8f216e788ba4eeddf4d062a0a1efe473ee10fce3b.svg" color="#99cc33">
<link rel="icon" type="image/png" href="/assets/android-chrome-192x192-cb0ced957daf2743c293b898f5e595fcf07fc0842b9d0aeef37c08b8c5f74d42.png" sizes="192x192">
<link rel="manifest" href="/manifest.json">
<meta name="apple-mobile-web-app-title" content="CuppaDesk">
<meta name="application-name" content="CuppaDesk">
<meta name="msapplication-TileColor" content="#99cc33">
<meta name="msapplication-TileImage" content="/assets/mstile-144x144-5de954b6d137b31283af01b9a7645c90440392de2b44ec88949fdba65cca75e7.png">
<meta name="theme-color" content="#99cc33">
<meta name="csrf-param" content="authenticity_token">
<meta name="csrf-token" content="wphb5Z8aebicMl6E2CiCJiNPnQowqP2TVUrXOWclCukQwiX/xrbLf3jBE4YRyyswVMEaPEszTO/7xxl1/iClsw==">
<link rel="stylesheet" media="all" href="/assets/main.self-b06bcba5344c9fc9a5c6491a38f0780f4594d723339bc0543a25138d83fe3de3.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/places.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/scaffolds.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/application.self-f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1" data-turbolinks-track="reload">
<script src="/assets/rails-ujs.self-56055fe2ac3f3902deb9d12c17b2d725d432162b48fc443946daf7dfbc96d88a.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/action_cable.self-be3674a79bb9d13d41d259b2c17fad23aef20946dab3603b9d02374ea795005f.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/cable.self-8484513823f404ed0c0f039f75243bfdede7af7919dda65f2e66391252443ce9.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/places.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/application.self-eba3cb53a585a0960ade5a8cb94253892706bb20e3f12097a13463b1f12a4528.js?body=1" data-turbolinks-track="reload"></script>
<!-- BEGIN MATERIAL DESIGN LITE -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<!-- <link rel="stylesheet" href="/material.min.css"> -->
<script defer="" src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<!-- END MATERIAL DESIGN LITE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.onload = function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function(){ y.className = y.className.replace("show", ""); }, 3000);
}
</script>
<div id="login-container">
<div id="cuppadesk-logo-large"></div>
<div id="card-white">
<h1>Log in</h1>
<div class="dropdown-dots">
<button onclick="dotsDropdown()" class="dropbtn-dots"></button>
<div id="dotsDropdown" class="dropdown-content">
<a href="/users/sign_up">
<div class="dropdown-content-item">Sign up</div>
</a>
<a href="/users/password/new">
<div class="dropdown-content-item">Forgot password</div>
</a>
<a href="/users/confirmation/new">
<div class="dropdown-content-item">Didn't recieve email confirmation</div>
</a>
<a href="/users/unlock/new">
<div class="dropdown-content-item">Didn't receive unlock instructions</div>
</a>
<a href="/users/auth/facebook">
<div class="dropdown-content-item">Log in with
Facebook
</div>
</a>
</div>
</div>
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function dotsDropdown() {
document.getElementById("dotsDropdown").classList.toggle("show-dots");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn-dots')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show-dots')) {
openDropdown.classList.remove('show-dots');
}
}
}
}
</script>
<form class="new_user" id="new_user" action="/users/sign_in" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="wphb5Z8aebicMl6E2CiCJiNPnQowqP2TVUrXOWclCukQwiX/xrbLf3jBE4YRyyswVMEaPEszTO/7xxl1/iClsw==">
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.onload = function() {
var z = document.getElementById("errorexplanationcontainer")
z.className = "show";
setTimeout(function(){ z.className = z.className.replace("show", ""); }, 3000);
}
</script>
<div class="field-white">
<input autofocus="autofocus" placeholder="Email" type="email" value="" name="user[email]" id="user_email">
</div>
<div class="field-white">
<input autocomplete="off" placeholder="Password" type="password" name="user[password]" id="user_password">
</div>
<div class="checkbox">
<input name="user[remember_me]" type="hidden" value="0"><input class="css-checkbox" type="checkbox" value="1" name="user[remember_me]" id="user_remember_me">
<label class="css-label clr" for="user_remember_me">Remember me</label>
</div>
<script>
// generic tools to help with the custom checkbox
function UTIL() { }
UTIL.prototype.bind_onclick = function(o, f) { // chain object onclick event to preserve prior statements (like jquery bind)
var prev = o.onclick;
if (typeof o.onclick != 'function') o.onclick = f;
else o.onclick = function() { if (prev) { prev(); } f(); };
};
UTIL.prototype.bind_onload = function(f) { // chain window onload event to preserve prior statements (like jquery bind)
var prev = window.onload;
if (typeof window.onload != 'function') window.onload = f;
else window.onload = function() { if (prev) { prev(); } f(); };
};
// generic css class style match functions similar to jquery
UTIL.prototype.trim = function(h) {
return h.replace(/^\s+|\s+$/g,'');
};
UTIL.prototype.sregex = function(n) {
return new RegExp('(?:^|\\s+)' + n + '(?:\\s+|$)');
};
UTIL.prototype.hasClass = function(o, n) {
var r = this.sregex(n);
return r.test(o.className);
};
UTIL.prototype.addClass = function(o, n) {
if (!this.hasClass(o, n))
o.className = this.trim(o.className + ' ' + n);
};
UTIL.prototype.removeClass = function(o, n) {
var r = this.sregex(n);
o.className = o.className.replace(r, '');
o.className = this.trim(o.className);
};
var U = new UTIL();
function getElementsByClassSpecial(node, classname) {
var a = [];
var re = new RegExp('(^| )'+classname+'( |$)');
var els = node.getElementsByTagName("*");
for(var i=0,j=els.length; i<j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
// specific to customized checkbox
function chk_labels(obj, init) {
var objs = document.getElementsByTagName('LABEL');
for (var i = 0; i < objs.length; i++) {
if (objs[i].htmlFor == obj.id) {
if (!init) { // cycle through each label belonging to checkbox
if (!U.hasClass(objs[i], 'chk')) { // adjust class of label to checked style, set checked
if (obj.type.toLowerCase() == 'radio') {
var radGroup = objs[i].className;
var res = radGroup.split(" ");
var newRes = res[0] + " " + res[1];
var relLabels = getElementsByClassSpecial(document.body,newRes);
for (var r = 0; r < relLabels.length; r++) {
U.removeClass(relLabels[r], 'chk');
U.addClass(relLabels[r], 'clr');
}
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
obj.checked = true;
}
else {
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
obj.checked = true;
}
} else { // adjust class of label to unchecked style, clear checked
U.removeClass(objs[i], 'chk');
U.addClass(objs[i], 'clr');
obj.checked = false;
}
return true;
} else { // initialize on page load
if (obj.checked) { // adjust class of label to checked style
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
} else { // adjust class of label to unchecked style
U.removeClass(objs[i], 'chk');
U.addClass(objs[i], 'clr')
}
}
}
}
}
function chk_events(init) {
var objs = document.getElementsByTagName('INPUT');
if (typeof init == 'undefined') init = false;
else init = init ? true : false;
for(var i = 0; i < objs.length; i++) {
if (objs[i].type.toLowerCase() == 'checkbox' || objs[i].type.toLowerCase() == 'radio' ) {
if (!init) {
U.bind_onclick(objs[i], function() {
chk_labels(this, init); // bind checkbox click event handler
});
}
else chk_labels(objs[i], init); // initialize state of checkbox onload
}
}
}
U.bind_onload(function() { // bind window onload event
chk_events(false); // bind click event handler to all checkboxes
chk_events(true); // initialize
});
</script>
<div class="green-submit">
<input type="submit" name="commit" value="Log in" data-disable-with="Log in">
</div>
</form>
</div>
</div>
</body></html>
Again, I'm probably missing something obvious here... I'm completely new to developing and JavaScript is something I particularly struggle with. I've read through many resources but in my mind, the code still looks correct...
Obviously, I'm wrong... So any help will be greatly appreciated!
Use window.addEventListener instead of overwriting window.onload.
For errorexplanationcontainer,
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.addEventListener("load", function() {
var z = document.getElementById("errorexplanationcontainer");
z.className = "show";
setTimeout(function() {
z.className = z.className.replace("show", "");
}, 3000);
}, false);
</script>
For alert,
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.addEventListener("load", function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function() {
y.className = y.className.replace("show", "");
}, 3000);
}, false);
</script>

How can I display four images randomly with link and without duplicates using Javascript?

I'm trying to display four images randomly with a related link, by avoiding to display duplicated images each time. I've found how to randomly display a random image with the link, but I have no idea how to create the loop part and how to check for duplicates. I would appreciate your help.
<script>
function random_imglink(){
var myimages=new Array()
myimages[1]="image1.gif"
myimages[2]="image2.gif"
myimages[3]="image3.gif"
myimages[4]="image4.gif"
myimages[5]="image5.gif"
myimages[6]="image6.gif"
var imagelinks=new Array()
imagelinks[1]="http://www.page1.com"
imagelinks[2]="http://www.page2.com"
imagelinks[3]="http://www.page3.com"
imagelinks[4]="http://www.page4.com"
imagelinks[5]="http://www.page5.com"
imagelinks[6]="http://www.page6.com"
var ry=Math.floor(Math.random()*myimages.length);
if (ry==0)
ry=1;
document.write('<a href='+'"'+imagelinks[ry]+'"'+'><img src="'+myimages[ry]+'" border=0></a>');
}
random_imglink()
</script>
Thanks in advance :)
As stated on this answer, you can create a method for checking of duplicates.
method:
var contains = function(needle) {
// Per spec, the way to identify NaN is that it is not equal to itself
var findNaN = needle !== needle;
var indexOf;
if(!findNaN && typeof Array.prototype.indexOf === 'function') {
indexOf = Array.prototype.indexOf;
} else {
indexOf = function(needle) {
var i = -1, index = -1;
for(i = 0; i < this.length; i++) {
var item = this[i];
if((findNaN && item !== item) || item === needle) {
index = i;
break;
}
}
return index;
};
}
return indexOf.call(this, needle) > -1;
};
usage:
var imagelinks= [0,1,2],
index = contains.call(imagelinks, imagelinks[ry]); //boolean
Outside of your function, declare an array to hold elements that are already displayed:
var displayed = [];
Then after your if (ry==0) condition add this:
if (displayed.indexOf(ry) !== -1){
displayed.push(ry);
document.write('<a href='+'"'+imagelinks[ry]+'"'+'><img src="'+myimages[ry]+'" border=0></a>');
} else {
random_imglink();
}
You should learn about Constructors. When you call new on them they return an Object which has separate properties based on the Constructor. Below is some code that will help you along your journey.
//<![CDATA[
// external.js
var doc, bod, htm, C, E, inArray, ShuffleMagic; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body; htm = doc.documentElement;
C = function(tag){
return doc.createElement(tag);
}
E = function(id){
return doc.getElementById(id);
}
inArray = function(needle, haystack){
for(var i=0,l=haystack.length; i<l; i++){
if(haystack[i] === needle){
return true;
}
}
return false;
}
function ShuffleMagic(haystack){
var a;
this.haystack = haystack;
this.alterOriginal = false;
this.shuffle = function(limit){
var r, s = this.haystack;
if(!a){
a = [].slice.call(s), l = a.length;
for(var i=0,n=1,f,h; i<l; i++,n++){
f = Math.floor(Math.random()*n); h = a[i]; a[i] = a[f]; a[f] = h;
}
}
if(limit){
if(a.length >= limit){
r = a.splice(0, limit);
if(a.length < limit)a = undefined;
}
else{
a = undefined;
return this.shuffle(s.length);
}
}
else{
r = a; a = undefined;
}
if(this.alterOriginal){
s.splice.apply(s, [0, s.length].concat(r)); a = undefined;
}
return r;
}
}
var imagelinks = ['http://www.page1.com', 'http://www.page2.com', 'http://www.page3.com', 'http://www.page4.com', 'http://www.page5.com', 'http://www.page6.com', 'http://www.page7.com', 'http://www.page8.com', 'http://www.page9.com',
'http://www.page10.com', 'http://www.page11.com', 'http://www.page12.com', 'http://www.page13.com', 'http://www.page14.com', 'http://www.page15.com', 'http://www.page16.com', 'http://www.page17.com', 'http://www.page18.com', 'http://www.page19.com'];
var max = E('limit'), out = E('out');
var wow = new ShuffleMagic(imagelinks);
// wow.alterOriginal = true;
// wow.haystack = ['Replace', 'other', 'array, 'example'];
E('testButton').addEventListener('click', function(){
out.innerHTML = wow.shuffle(+max.value).join('<br />');
});
});
//]]>
/* external.css */
html,body{
margin:0; padding:0;
}
.main{
width:980px; margin:0 auto;
}
#limit{
width:30px; padding-left:3px;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<title>Shuffle Magic</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='test.js'></script>
</head>
<body>
<div class='main'>
<label for='limit'>Limit:</label><input id='limit' name='limit' type='text' value='4' /><input id='testButton' type='button' value='Click Me' />
<div id='out'></div>
</div>
</body>
</html>
With this version, which is recursive (probably beyond your understanding right now), the array elements only recycle once they've been completely or nearly completely gone through. Enjoy!

all permutations of a string jquery

I have gotten the code for all permutations of a string from another user on stackoverflow and i am trying to make it work in my webpage. Are there any problems with this code? I get an error in the javascript console when i try to submit a word. The error flashes for a short time so i cannot read it.
$(document).ready(function() {
$('form#anagram').submit(function(event) {
function findAllPermutations(str, index, buffer) {
if (typeof str == "string") {
str = str.split("") };
if (typeof index == "undefined") {
index = 0 };
if (typeof buffer == "undefined") {
buffer = [] };
if (index >= str.length) {
return buffer };
for (var i = index; i < str.length; i++) {
buffer.push(ToggleLetters(str, index, i));
}
return FindAllPermutations(str, index + 1, buffer);
}
function ToggleLetters(str, index1, index2) {
if (index1 != index2) {
var temp = str[index1]
str[index1] = str[index2]
str[index2] = temp
};
return str.join("");
}
list = $('input#word').val();
$('#resulttext').append("<p>" + findAllPermutations(list) + "</p>")
event.preventDefault();
});
});
here is the HTML:
<!DOCTYPE html>
<html>
<head>
<link href="css/bootstrap.css" rel="stylesheet" type="text/css">
<link href="css/styles.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.11.1.js"></script>
<script src="js/scripts3.js"></script>
<title>Anagram finder</title>
</head>
<body>
<div class="container">
<div class="band">
<h1>Anagram Finder</h1>
</div>
<form id="anagram">
<div class="form-group">
<label for="word">Your Word</label>
<input id="word" type="text">
</div>
<button type="submit" class="btn">Find!</button>
</form>
<div id="resulttext">
</div>
</div>
</body>
</html>
There was a mistake in the function name and as event.preventDefault() was at the end of the function, you wan not being able to see the error as the page was being refreshed.
Try it:-
<!DOCTYPE html>
<script src="jquery.js"></script>
<title>Anagram finder</title>
</head>
<body>
<script>
$(document).ready(function() {
$('form#anagram').submit(function(event) {
event.preventDefault();
function findAllPermutations(str, index, buffer) {
if (typeof str == "string") {
str = str.split("") };
if (typeof index == "undefined") {
index = 0 };
if (typeof buffer == "undefined") {
buffer = [] };
if (index >= str.length) {
return buffer };
for (var i = index; i < str.length; i++) {
buffer.push(ToggleLetters(str, index, i));
}
return findAllPermutations(str, index + 1, buffer);
}
function ToggleLetters(str, index1, index2) {
if (index1 != index2) {
var temp = str[index1]
str[index1] = str[index2]
str[index2] = temp
};
return str.join("");
}
list = $('input#word').val();
$('#resulttext').append("<p>" + findAllPermutations(list) + "</p>")
});
});
</script>
<div class="container">
<div class="band">
<h1>Anagram Finder</h1>
</div>
<form id="anagram">
<div class="form-group">
<label for="word">Your Word</label>
<input id="word" type="text">
</div>
<button type="submit" class="btn">Find!</button>
</form>
<div id="resulttext">
</div>
</div>
</body>
</html>

Categories