Issue Converting HTML Table into CSV Format - html

Trouble converting a series of HTML Tables into a single CSV document.
Everything works fine until I get to a multi-line in my html.
The converter takes: <td> Restarted the following servers for maintenance:
-Car Care: CarCareServer -DWA: DWAHost, Server-1, Terminal -Homemasters: Homemasters, SRV0 -Monolith: Monolith, Server </td>
And converts it into: 5 new CSV cells (one for each line). But, what I need is for all this text to be funneled into one, single, CSV cell.
Please help!
Here's my converter.
$('#CSVFiltDownBtn').click(function() {
var titles = [];
var data = [];
/*
* Get the table headers, this will be CSV headers
* The count of headers will be CSV string separator
*/
$('#filtered_table thead:first th').each(function() {
titles.push($(this).text());
});
/*
* Get the actual data, this will contain all the data, in 1 array
*/
$('#filtered_table td').each(function() {
//data.push($(this).text());
var cellData = $(this).text();
//var cleanData = escape(cellData);
var cleanData = cellData.replace(/,/g, "").replace(/-/g, "").replace(/<br>/g, "");
data.push(cleanData);
});
/*
* Convert our data to CSV string
*/
var CSVString = prepCSVRow(titles, titles.length, '');
CSVString = prepCSVRow(data, titles.length, CSVString);
/*
* Make CSV downloadable
*/
var downloadLink = document.createElement("a");
var blob = new Blob(["\ufeff", CSVString]);
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = "data.csv";
/*
* Actually download CSV
*/
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
});
The tables are tricky to demonstrate because their numbers, and the numbers of columns, are dictated by the user (it's a filtered list), and I'm converting multiple resulting tables into a single CSV.
All tables have the same numbers of columns, and the same headers.
My primary issue is how to make sure these multi-lined td's are converting into a single CSV block.
Thoughts?

Don't use jQuery's text use the native innerText.
Replace
var cellData = $(this).text();
With
var cellData = this.text();
See the snippet below for a quick and dirty demo of the difference:
var div = document.querySelector("div");
console.log(div.innerText);
console.log($("div").text());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
Some
Text
</div>

I don't know the CSV parser you are using, so I made one showing you the technique, following the example here: https://en.wikipedia.org/wiki/Comma-separated_values#Example .
/* js/external.js */
//<![CDATA[
var doc, bod, I, S, Q, special, unspecial, csv; // for use on other loads
addEventListener('load', function(){
doc = document; bod = doc.body;
I = function(id){
return doc.getElementById(id);
}
S = function(selector, within){
var w = within || doc;
return w.querySelector(selector);
}
Q = function(selector, within){
var w = within || doc;
return w.querySelectorAll(selector);
}
special = function(str){
return str.replace(/&/g, '&').replace(/'/g, '&apos;').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
}
unspecial = function(str){
return str.replace(/&/g, '&').replace(/&apos;/g, "'").replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
}
csv = function(tableElement, linkElement){
var thead_tr = Q('thead>tr', tableElement), tfoot_tr = Q('tfoot>tr', tableElement), tbody_tr = Q('tbody>tr', tableElement), s = '';
for(var i=0,c=thead_tr,row,col,l=c.length; i<l; i++){
row = thead_tr[i].childNodes;
for(var n=0,a=[],q=row.length; n<q; n++){
col = row[n];
if(col.nodeType === 1)a.push('"'+unspecial(col.innerHTML).replace(/"/g, '""')+'"');
}
s += a.join(',')+'\n';
}
for(var i=0,c=tbody_tr,l=c.length; i<l; i++){
row = tbody_tr[i].childNodes;
for(var n=0,a=[],q=row.length; n<q; n++){
col = row[n];
if(col.nodeType === 1)a.push('"'+unspecial(col.innerHTML).replace(/"/g, '""')+'"');
}
s += a.join(',')+'\n';
}
for(var i=0,c=tfoot_tr,l=c.length; i<l; i++){
row = tfoot_tr[i].childNodes;
for(var n=0,a=[],q=row.length; n<q; n++){
col = row[n];
if(col.nodeType === 1)a.push('"'+unspecial(col.innerHTML).replace(/"/g, '""')+'"');
}
s += a.join(',')+'\n';
}
linkElement.href = URL.createObjectURL(new Blob([s], {type:'text/csv'}));
}
csv(I('wiki_cars'), I('downloadLink'));
});
//]]>
/* css/external.css */
*{
box-sizing:border-box; padding:0; margin:0;
}
html,body{
width:100%; height:100%;
}
body{
position:relative; background:#ccc;
}
table{
background:#fff; border-collapse:collapse;
}
th,td{
border:1px solid #000; padding:3px 5px;
}
#link_container{
text-align:center; margin:7px 0;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' />
<title>Test Template</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script type='text/javascript' src='js/external.js'></script>
</head>
<body>
<div id='link_container'><a id='downloadLink' download='data.csv'>Click to Test</a></div>
<table id='wiki_cars'>
<thead>
<tr>
<th>Year</th><th>Make</th><th>Model</th><th>Description</th><th>Price</th>
</tr>
</thead>
<tfoot>
<tr>
<th>total</th><th></th><th></th><th></th><th>17699.00</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>1997</td><td>Ford</td><td>E350</td><td>ac, abs, moon</td><td>3000.00</td>
</tr>
<tr>
<td>1999</td><td>Chevy</td><td>Venture "Extended Edition"</td><td></td><td> 4900.00</td>
</tr>
<tr>
<td>1999</td><td>Chevy</td><td>Venture "Extended Edition, Very Large"</td><td></td><td>5000.00</td>
</tr>
<tr>
<td>1996</td><td>Jeep</td><td>Grand Cherokee</td><td>"MUST SELL! air, moon roof, loaded"</td><td>4799.00</td>
</tr>
</tbody>
</table>
</body>
</html>
I did add a footer to that table. Hopefully this helps!
PS
Personally, I wouldn't use the download attribute, since it won't work on Safari on iOS. You can always create a CSV file on your Server. .csvs should attempt to download automatically if you link to them, since the Browser won't know what to do with that file type.

Related

Read csv file using JavaScript and display into an html table

I am a beginner in programming and I could really use your help to understand why this piece of code does not work and fix it. I get no error, simply nothing happens.
I want to read a csv file using JavaScript and display its contents in an html table.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript">
var fileInput = document.querySelector('notes.csv');
function read(callback){
var file = fileInput.files.item(0);
var reader = new FileReader();
reader.onload = function (e){
callback(reader.result);
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for (var i = 0; i < rows.length; i++){
var cells = rows[i].split(",");
if (cells.length > 1){
var row = table.insertRow(-1);
for (var j = 0; j < cells.length; j++){
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
}
}
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
}
reader.readAsText(fileInput);
}
</script>
<div id="dvCSV"></div>
</body>
</html>

AmCharts4 - Unable to load file - external JSON file produced from SQL database

I'm struggling to open my json arranged data in AmCharts4. In my previous charts I used very simple script (chart.data = ;), which unfortunately does not work this time. So I'm using chart.dataSource.url function proposed by AmCharts documentation. When, I load example file found on web everything works fine, as soon as I switch to my file the chart is not able to load file. I'm not able to find a similar problem on web, therefore I would be very grateful for help.
Here is my example with working url and my not working file.
Thanks in advance:
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<style>
</style>
</head>
<body>
<div id="chartdiv"></div>
</body>
</html>
<!-- Styles -->
<style>
#chartdiv {
width: 100%;
height: 500px;
}
</style>
<!-- Resources -->
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<!-- Chart code -->
<script>
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create('chartdiv', am4charts.XYChart)
// Modify chart's colors
chart.colors.list = [
am4core.color("#264B29"),
am4core.color("#94B255"),
am4core.color("#456C39"),
am4core.color("#C4D563"),
am4core.color("#698F47"),
am4core.color("#F9F871"),
];
chart.legend = new am4charts.Legend()
chart.legend.position = 'top'
chart.legend.paddingBottom = 20
chart.legend.labels.template.maxWidth = 95
var xAxis = chart.xAxes.push(new am4charts.CategoryAxis())
xAxis.dataFields.category = 'year'
xAxis.renderer.cellStartLocation = 0.1
xAxis.renderer.cellEndLocation = 0.9
xAxis.renderer.grid.template.location = 0;
var yAxis = chart.yAxes.push(new am4charts.ValueAxis());
function createSeries(value, name) {
var series = chart.series.push(new am4charts.ColumnSeries())
series.dataFields.valueY = value
series.dataFields.categoryX = 'year'
series.name = name
series.events.on("hidden", arrangeColumns);
series.events.on("shown", arrangeColumns);
var bullet = series.bullets.push(new am4charts.LabelBullet())
bullet.interactionsEnabled = false
bullet.dy = 30;
bullet.label.text = '{valueY}'
bullet.label.fill = am4core.color('#ffffff')
return series;
}
// Add data
//Working url
//chart.dataSource.url = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/sample_data_serial.json";
//My SQL produced JSON file is not working
chart.dataSource.url = "data/my-file.php";
chart.dataSource.adapter.add("parsedData", function(data) {
var newData = [];
data.forEach(function(dataItem) {
var newDataItem = {};
Object.keys(dataItem).forEach(function(key) {
if (typeof dataItem[key] === "object") {
newDataItem["_id"] = dataItem[key]["#id"];
dataItem[key]["Column"].forEach(function(dataItem) {
newDataItem[dataItem["#name"]] = dataItem["#id"];
});
} else {
newDataItem[key] = dataItem[key];
}
});
newData.push(newDataItem);
});
data = newData;
return data;
});
createSeries('cars', 'The First');
createSeries('motorcycles', 'The Second');
createSeries('bicycles', 'The Third');
//createSeries('bilanca_lsk_lst', 'T4');
function arrangeColumns() {
var series = chart.series.getIndex(0);
var w = 1 - xAxis.renderer.cellStartLocation - (1 - xAxis.renderer.cellEndLocation);
if (series.dataItems.length > 1) {
var x0 = xAxis.getX(series.dataItems.getIndex(0), "yearX");
var x1 = xAxis.getX(series.dataItems.getIndex(1), "yearX");
var delta = ((x1 - x0) / chart.series.length) * w;
if (am4core.isNumber(delta)) {
var middle = chart.series.length / 2;
var newIndex = 0;
chart.series.each(function(series) {
if (!series.isHidden && !series.isHiding) {
series.dummyData = newIndex;
newIndex++;
}
else {
series.dummyData = chart.series.indexOf(series);
}
})
var visibleCount = newIndex;
var newMiddle = visibleCount / 2;
chart.series.each(function(series) {
var trueIndex = chart.series.indexOf(series);
var newIndex = series.dummyData;
var dx = (newIndex - trueIndex + middle - newMiddle) * delta
series.animate({ property: "dx", to: dx }, series.interpolationDuration, series.interpolationEasing);
series.bulletsContainer.animate({ property: "dx", to: dx }, series.interpolationDuration, series.interpolationEasing);
})
}
}
}
});
// end am4core.ready()
</script>
I found a typing error in my-file.php
Anyhow, after I solved typing issue the chart.dataSource.url function still did not work, but It worked using next php include script.
chart.data = <?php include './data/my-file.php'; ?>;

how to create html table results from JSON data

I have code that uses AJAX and JSON to output a chunk of SQL data when you do a search and I am trying to separate the data some and have it display into an HTML table. At first it was just the SQL data but I put some tags into the innerHTML line to at least visually separate it, however I would really like to be able to put each column into a separate table cell. Any ideas on how to do that would be greatly appreciated. Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-2.2.2.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<title>AJAX Search Example</title>
<script>
function fetch() {
// (A) GET SEARCH TERM
var data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
// (B) AJAX SEARCH REQUEST
var xhr = new XMLHttpRequest();
// (CHANGE1) USING ONREADYSTATECHNAGE INSTEAD OF ONLOAD
xhr.onreadystatechange = function (event) {
// (CHANGE2) we will check if ajax process has completed or not it goes from 1,2,3,4 means end.
if(this.readyState == 4){
// (CHANGE2) when ready state comes to 4 we then check what response status was it if it is 200 good else error.
if(this.status == 200){
// (CHANGE3) MOVED ALL YOUR CODE HERE
// (CHANGE4) we need to use responseText instead of response because JSON comes as string that is why we are parsing it to be converted into array
var results = JSON.parse(this.responseText);
//I have added just a measure to check what the out put is you can remove it latter. open dev console to get the result.
console.log(results);
wrapper = document.getElementById("results");
if (results.length > 0) {
wrapper.innerHTML = "";
// (CHANGE5) UPDATED data ref with results
for (i = 0; i < results.length; i++) {
let line = document.createElement("div");
//it is just as simple to create id only it must start with alphabet not number
line.id=`res${[i]}`;
//we created span tag to display price and this is what we will change. on that span we will create a data-price attribute which will hold original price and we will run calculations using that number
//BIG CHANGE
//BIG CHANGE
//since after parsing individual record will be in Js object so we dont need to access them like array results[i]['item']
//we access them with dot notation results[i].item
line.innerHTML = `Category:${results[i].category} - OEM #:${results[i].oemnumber} - Price:$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
%70
%60
%50 100%`;
wrapper.appendChild(line);
}
// (CHANGE6) We moved event listeners here so any newly added elements will be updated.
//get all the links and apply event listener through loop
var links = document.querySelectorAll('a');
for ( ii = 0; ii < links.length; ii++) {
links[ii].addEventListener("click", function(event) {
//capture link value and get number to be converted to percentage
var percentage = event.target.innerText.match(/\d+/)[0]/100;
//capture the data-price which is within same div as anchor link
var pricetarget = event.target.parentElement.querySelector('[data-price]');
//get value of data-price
var actualprice= pricetarget.dataset.price;
//run math and chnage the value on display
pricetarget.innerHTML=(actualprice*percentage).toFixed(2);
});
}
} else { wrapper.innerHTML = "No results found"; }
} else {
//if reponse code is other ethan 200
alert('INTERNET DEAD OR AJAX FAILED ');
}
}
};
// (CHANGE7) We moved open event to end so everything is ready before it fires.
xhr.open('POST', "2-search.php");
xhr.send(data);
return false;
};
</script>
</head>
<body>
<!-- (A) SEARCH FORM -->
<form ID='myForm' onsubmit="return fetch();">
<h1>SEARCH FOR CATALYTIC CONVERTER</h1>
<input type="text" id="search" required/>
<input type="submit" value="Search"/>
</form>
<!-- (B) SEARCH RESULTS -->
<div id="results"></div>
</body>
</html>
Here is where I added the tags to at least visually separate it: "line.innerHTML = `Category:${results[i].category} - OEM #:${results[i].oemnumber} - Price:$${results[i].price}"
What I want to do is have Category, OEM #, and price each in a separate table cell. Thank you for any help offered.
You can simply generate trs inside your for (i = 0; i < results.len.. like you are already doing for divs . So , just use += to append every new tr inside tbody and then append this to your table
Demo Code :
//suppose json look like below :)
var results = [{
"category": "A",
"price": 13,
"oemnumber": "d1A"
}, {
"category": "B",
"price": 15,
"oemnumber": "d1B"
}, {
"category": "C",
"price": 12,
"oemnumber": "d1C"
}]
fetch();
function fetch() {
/* var data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
var xhr = new XMLHttpRequest();
// (CHANGE1) USING ONREADYSTATECHNAGE INSTEAD OF ONLOAD
//some codes/..
console.log(results);*/
wrapper = document.getElementById("results");
wrapper.innerHTML = "";
var rows = "";
if (results.length > 0) {
for (i = 0; i < results.length; i++) {
//generate trs
rows += `<tr id=res${[i]}><td>${results[i].category}</td><td>${results[i].oemnumber}</td><td>$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
%70
%60
%50 100%</td></tr>`;
}
wrapper.innerHTML = `<table class="table">
<thead><th>Category</th><th>OEM</th><th>Price</th></thead><tbody>${rows}</tbody></table>`;
//sme other codes,,
}
};
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<div id="results">
</div>

How to save a Google maps overlay shape in the database?

I want to save a Google maps overlay shape in the database. This is my code. It works perfectly but I just need to save all_shapes array in the database.
<html>
<head>
<style type="text/css">
#map, html, body
{
padding: 0;
margin: 0;
height: 100%;
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&libraries=drawing,geometry"></script>
<script>
var coordinates = [];
var all_shapes = [];
var selectedShape;
</script>
<script>
function draw_shape()
{
for(var i = 0; i < all_shapes.length; i++)
{
all_shapes[i].setMap(null);
}
for(var i = 0; i < all_shapes.length; i++)
{
all_shapes[i].setMap(map);
}
}
</script>
<script>
function clearSelection()
{
if(selectedShape)
{
selectedShape.setEditable(false);
selectedShape = null;
}
}
function setSelection(shape)
{
clearSelection();
selectedShape = shape;
shape.setEditable(true);
}
function deleteSelectedShape()
{
if (selectedShape)
{
selectedShape.setMap(null);
}
}
</script>
<script>
function save_coordinates_to_array(newShapeArg)
{
if(newShapeArg.type == google.maps.drawing.OverlayType.POLYGON)
{
var polygonBounds = newShapeArg.getPath();
for(var i = 0 ; i < polygonBounds.length ; i++)
{
coordinates.push(polygonBounds.getAt(i).lat(), polygonBounds.getAt(i).lng());
}
}
else
{
//alert("Not polygon");/////////////
}
}
</script>
<script>
var map;
function initialize()
{
map = new google.maps.Map(document.getElementById('map'), {zoom: 12, center: new google.maps.LatLng(32.344, 51.048)});
var drawingManager = new google.maps.drawing.DrawingManager();
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
newShape.type = e.type;
all_shapes.push(newShape);
setSelection(newShape);
save_coordinates_to_array(newShape);
google.maps.event.addListener(newShape, 'click', function() {setSelection(newShape)});
});
google.maps.event.addListener(map, 'click', function(e) {clearSelection();});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<table border="1">
<tr>
<td>Name</td>
<td><input name="name" id="name" type="text"></td>
</tr>
<tr>
<td>Color</td>
<td>
<table border="1" width="100%">
<tr>
<td bgcolor="#FF0000"> </td>
<td bgcolor="#00FF00"> </td>
<td bgcolor="#0000FF"> </td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2"><input name="save" type="button" value="Save" onClick="draw_shape()"></td>
</tr>
<tr>
<td colspan="2"><input name="delete" type="button" value="Delete" onClick="deleteSelectedShape()"></td>
</tr>
</table>
<div id="map"></div>
</body>
</html>
Where and how can I save the created overlay shapes in the database. All shapes are saved in the var all_shapes = []; array. What kind of type I have to choose for the field in database? I mean for example int, char, etc.
I'm going to use MySQL and PHP.
When you simply want to store the shapes somehow, you may use a JSON-string, store it in e.g. a Text-column(char would be to small to store detailed polygons/polylines )
Note: when you create the JSON-string, you must convert the properties(e.g. to native arrays or objects), you cannot store for example LatLng's directly, because the prototype will be lost when saving it. Pathes of polylines/polygons may be stored encoded
Another approach:
use multiple columns, e.g.
a column(varchar) where you store the type(LatLng, Circle,Polyline,etc.)
a column(geometry) where you store the geometric features(LatLng,Polygon or Polyline)
a column(int) where you store a radius(used when you insert a circle)
optionally column(text) where you store the style-options(when needed)
The first suggestion would be sufficient when you simply want to store it.
When you must be able to select particular shapes, e.g for a given area, use the 2nd suggestion.
See http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html for details of the spatial extensions
2 functions that either remove the circular references and create storable objects, or restore the overlays from these stored objects.
var IO={
//returns array with storable google.maps.Overlay-definitions
IN:function(arr,//array with google.maps.Overlays
encoded//boolean indicating if pathes should be stored encoded
){
var shapes = [],
goo=google.maps,
shape,tmp;
for(var i = 0; i < arr.length; i++)
{
shape=arr[i];
tmp={type:this.t_(shape.type),id:shape.id||null};
switch(tmp.type){
case 'CIRCLE':
tmp.radius=shape.getRadius();
tmp.geometry=this.p_(shape.getCenter());
break;
case 'MARKER':
tmp.geometry=this.p_(shape.getPosition());
break;
case 'RECTANGLE':
tmp.geometry=this.b_(shape.getBounds());
break;
case 'POLYLINE':
tmp.geometry=this.l_(shape.getPath(),encoded);
break;
case 'POLYGON':
tmp.geometry=this.m_(shape.getPaths(),encoded);
break;
}
shapes.push(tmp);
}
return shapes;
},
//returns array with google.maps.Overlays
OUT:function(arr,//array containg the stored shape-definitions
map//map where to draw the shapes
){
var shapes = [],
goo=google.maps,
map=map||null,
shape,tmp;
for(var i = 0; i < arr.length; i++)
{
shape=arr[i];
switch(shape.type){
case 'CIRCLE':
tmp=new goo.Circle({radius:Number(shape.radius),
center:this.pp_.apply(this,shape.geometry)});
break;
case 'MARKER':
tmp=new goo.Marker({position:this.pp_.apply(this,shape.geometry)});
break;
case 'RECTANGLE':
tmp=new goo.Rectangle({bounds:this.bb_.apply(this,shape.geometry)});
break;
case 'POLYLINE':
tmp=new goo.Polyline({path:this.ll_(shape.geometry)});
break;
case 'POLYGON':
tmp=new goo.Polygon({paths:this.mm_(shape.geometry)});
break;
}
tmp.setValues({map:map,id:shape.id})
shapes.push(tmp);
}
return shapes;
},
l_:function(path,e){
path=(path.getArray)?path.getArray():path;
if(e){
return google.maps.geometry.encoding.encodePath(path);
}else{
var r=[];
for(var i=0;i<path.length;++i){
r.push(this.p_(path[i]));
}
return r;
}
},
ll_:function(path){
if(typeof path==='string'){
return google.maps.geometry.encoding.decodePath(path);
}
else{
var r=[];
for(var i=0;i<path.length;++i){
r.push(this.pp_.apply(this,path[i]));
}
return r;
}
},
m_:function(paths,e){
var r=[];
paths=(paths.getArray)?paths.getArray():paths;
for(var i=0;i<paths.length;++i){
r.push(this.l_(paths[i],e));
}
return r;
},
mm_:function(paths){
var r=[];
for(var i=0;i<paths.length;++i){
r.push(this.ll_.call(this,paths[i]));
}
return r;
},
p_:function(latLng){
return([latLng.lat(),latLng.lng()]);
},
pp_:function(lat,lng){
return new google.maps.LatLng(lat,lng);
},
b_:function(bounds){
return([this.p_(bounds.getSouthWest()),
this.p_(bounds.getNorthEast())]);
},
bb_:function(sw,ne){
return new google.maps.LatLngBounds(this.pp_.apply(this,sw),
this.pp_.apply(this,ne));
},
t_:function(s){
var t=['CIRCLE','MARKER','RECTANGLE','POLYLINE','POLYGON'];
for(var i=0;i<t.length;++i){
if(s===google.maps.drawing.OverlayType[t[i]]){
return t[i];
}
}
}
}
The array returned by IO.IN may be sended to a serverside script. The serverside script should iterate over this array and INSERT a JSON-string into the table:
<?php
$mysqli = new mysqli(/*args*/);
$stmt = $mysqli->prepare('INSERT INTO `tableName`(`columnName`) VALUES (?)');
$stmt->bind_param('s', $json);
foreach($_POST['shapes'] as $value){
$json = json_encode($value);
$stmt->execute();
}
?>
to restore the shapes fetch them:
<?php
$json=array();
$res=$mysqli->query('SELECT `columnName` from `tableName`');
while ($row = $res->fetch_assoc()) {
$json[]=json_decode($row['columnName']);
}
$res->close();
$json=json_encode($json);
?>
and pass the result to IO.OUT():
IO.OUT(<?php echo $json;?>, someGoogleMapsInstance);
Demo: http://jsfiddle.net/doktormolle/EdZk4/show/
Simple GeoJson Editor is an example of drawing, editing, dropping and saving shapes as geoJson on google maps. The author ( a Google intern) described the project in this post.
The Javascript and HTML are not minified.
An even better opensource tool can be found at Geojson.io
Strange behavior I found in the code http://jsfiddle.net/doktormolle/EdZk4/show/
I added next code to IN function:
if (tmp.type != 'MARKER') {
tmp.strokeColor = shape.strokeColor;
tmp.strokeWeight = shape.strokeWeight;
tmp.fillColor = shape.fillColor;
tmp.fillOpacity = shape.fillOpacity;
tmp.editable = shape.getEditable();
if (tmp.type == 'POLYLINE' || tmp.type == 'POLYGON')
tmp.infoWindowContent = shape.infoWindow.content;
}
All shapes are editable, but only the last shows editable as true. For example, I add one editable polyline and it is editable in the result.
"[{"type":"POLYLINE","id":null,"draggable":false,"geometry":["gn_sFwt`eEvmd#ig|B"],
"strokeColor":"red","strokeWeight":3,"fillOpacity":0.35,"editable":true,
"infoWindowContent":"Polyline Length: 58.80 kms"}]"
I add second editable polyline, but in the result the first is uneditable and second editable.
"[{"type":"POLYLINE","id":null,"draggable":false,"geometry":["gn_sFwt`eEvmd#ig|B"],
"strokeColor":"red","strokeWeight":3,"fillOpacity":0.35,"editable":false,
"infoWindowContent":"Polyline Length: 58.80 kms"},
{"type":"POLYLINE","id":null,"draggable":false,"geometry":["qoiqFgvheEcsw#ygz#"],
"strokeColor":"red","strokeWeight":3,"fillOpacity":0.35,"editable":true,
"infoWindowContent":"Polyline Length: 41.41 kms"}]"
If you need to store the path just to restore it later on a map, you can also use Google Maps Encoding Utility. It is not as powerful as Dr.Molle's answer but can be useful for storing polygons and polylines.

How to display html table looping through multiple rows read from a file

I am trying to display the json response into a html table. One of the fields is an image that I want to be shown in the table. My current code just displays the last key/value from the json response, instead of all in the table.
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<link rel="stylesheet" type="text/css" href="http://www.tutorialspoint.com/scripts/style.css" />
<script type="application/javascript">
function loadJSON()
{
var http_request = new XMLHttpRequest();
var data_file = "/vcaWS/api/sources";
http_request.onreadystatechange = function(){
if (http_request.readyState == 4 )
{
// Javascript function JSON.parse to parse JSON data
var jsonObj = JSON.parse(http_request.responseText);
for(var i=0;i<jsonObj.length;i++){
document.getElementById("title").innerHTML = jsonObj[i].title;
document.getElementById("logo_sm").innerHTML = jsonObj[i].logo_sm;
}
}
}
http_request.open("GET", data_file, true);
http_request.send();
}
</script>
<title>Test JSON</title>
</head>
<body style="width:960px">
<h1>Test JSON</h1>
<table class="src">
<tr><th>Title</th><th>Logo_Small</th></tr>
<tr>
<td><div id="title">Youtube</div></td>
<td><div id="logo_sm">Youtube</div></td>
</tr>
</table>
<div class="central">
<button type="button" onclick="loadJSON();">JSON Store </button>
</body>
</html>
The json response is as below:
[
{
"title":"Virtual Magician s Video Podcast",
"logo_sm":"http://a5.mzstatic.com/us/r30/Podcasts/v4/cf/53/e1/cf53e162-f4c7-7842-173d-7f7f2a79fd7e/mza_854261567010408552.100x100-75.jpg"
},
{
"title":"shralp! //surfing video podcast//",
"logo_sm":"http://a5.mzstatic.com/us/r30/Podcasts/v4/ea/ff/d0/eaffd0d3-b1f9-e886-2ffd-5ff14bcb5edb/mza_1030973830906343038.100x100-75.jpg"
},
{
"title":"this WEEK in TECH Video (small)",
"logo_sm":"http://a4.mzstatic.com/us/r30/Podcasts2/v4/fb/59/fc/fb59fc2d-b1a2-98cf-e1f8-32bae7217912/mza_5512264877031055372.100x100-75.jpg"
}
]
Also, I was hoping to show the jpg file as an image. Currently, its a text value shown in the html table.
This will add the JSON data as new rows in the table.
var rows = '';
for(var i=0;i<jsonObj.length;i++){
rows += '<tr><td class="title">' + jsonObj[i].title + '</td><td class="logo_sm">' + jsonObj[i].logo_sm + '</td></tr>';
}
document.getElementsByTagName('table')[0].innerHTML += rows;
You are iterating through the JSON object but on each iteration you are replacing the innerHTML of the rows with the ith object.
Therefore it will only show the last item of the JSON object.
Just get the table and insert a row for each item.
var mytable = document.getElementById("tableid");
for(var i=0;i<jsonObj.length;i++){
var myrow = mytable.insertRow(0);
var mytitlecell = myrow.insertCell(0);
var mylogocell = myrow.insertCell(1);
mytitlecell.innerHTML = jsonObj[i].title;
mylogocell.innerHTML = "<img src='"+jsonObj[i].logo_sm+"'/>";
}