How to draw multiple polylines using Google Maps? - javascript

I have a list of latitude and longitude in database and I want to draw more polyline on google maps.
For example:
var i, j;
var polyline1 = new Array(latt.length);
str = new Array(latt.length);
for (var k = 0; k < latt.length; k++) {
i = latt[k].split(',');
j = longg[k].split(',');
str[k] = 'new GLatLng(' + i[0] + ',' + j[0] + ')' + ',';
for (var count = 1; count < i.length; count++) {
str[k] += 'new GLatLng(' + i[count] + ',' + j[count] + ')' + ',';
}
str[k] = str[k] + 'new GLatLng(' + i[0] + ',' + j[0] + ')';
polyline1[k] = new GPolyline([str[k]], "#ff0000", 6);
map.addOverlay(polyline1[k]);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
}
but I'm getting error

I don't understand the error - I can't see an a anywhere - but you're almost certainly using GPolyline wrong. It wants an array of objects, not a single-element array of a string of JavaScript:
var polyline1 = new Array(latt.length);
str = new Array(latt.length);
for (var k = 0; k < latt.length; k++) {
var i = latt[k].split(',');
var j = longg[k].split(',');
var latlngs = [];
for (var count = 0; count < i.length; count++) {
latlngs.push(new GLatLng(parseFloat(i[count]), parseFloat(j[count])));
}
polyline1[k] = new GPolyline(latlngs, "#ff0000", 6);
map.addOverlay(polyline1[k]);
}
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
I don't know if the parseFloats are actually necessary. You probably want to move the control adds outside the loop too.

Related

How to put JSON object into an array

function initialize(woeid) {
$.ajax({
url: "php/getMapping.php",
type: 'get',
cache: false,
success: function(overallArray) {
console.log(overallArray);
console.log(overallArray.length);
for (var i = 0; i < overallArray.length; i++) {
if (overallArray[i].woeid == woeid) {
var cityArray = overallArray[i];
break;
}
}
var cityHashTags = cityArray.hashTags.split(";");
document.getElementById("cityTitle").innerHTML = cityArray.name;
document.getElementById("rssLink").href = "php/getRssFeed.php?woeid=" + cityArray.woeid;
document.getElementById("cityDescription").innerHTML = cityArray.desc;
document.getElementById("cityPopulation").innerHTML = `Population: ${cityArray.curPop}`;
document.getElementById("cityCountry").innerHTML = `Country: ${cityArray.country}`;
document.getElementById("cityLat").innerHTML = `Lat : ${cityArray.lat}`;
document.getElementById("cityLong").innerHTML = `Long : ${cityArray.lng}`;
for (var j = 0; j < cityHashTags.length; j++) {
document.getElementById("cityTwitter").innerHTML += "<a href='https://twitter.com/search?q=" + cityHashTags[j] + "' target='_blank'>#" + cityHashTags[j] + "</a>&nbsp&nbsp";
}
if (0 < cityArray.images.length) {
for (var i = 0; i < cityArray.images.length; i++) {
document.getElementById("cityPhotos").innerHTML += '<div class="w3-display-container mySlides w3-animate-opacity"><img src="pictures/poi/' + cityArray.images[i].imageFle + '" style="width:100%;height:100%;"><h4>' + cityArray.images[i].name + '</h4><p style="text-align:center;">' + cityArray.images[i].desc + '</p></div>';
}
}
var mapCanvas = document.getElementById('mapCanvas');
var mapOptions = {
center: new google.maps.LatLng(cityArray.lat, cityArray.lng),
zoom: 13,
mapTypeId: google.maps.MapTypeId.TERRAIN,
disableDefaultUI: 1
}
var map = new google.maps.Map(mapCanvas, mapOptions);
setMarkers(map, cityArray.poi);
}
});
}
I have attached the code of my Javascript. The array "overallArray" contains a JSON object. I attached a picture of the array. How can I put this whole data into 2 array? Two array should be based on the two woeid. Rest of the data goes under those two. I can hardcode the data but I am looking for a way to dynamically assign the key and value. I hope it all make sense.
This will work something like , push Json array in existing Empty / jsonArray
cityArray [];
let valuesX = {
mapTypeId: document.getElementsByName('mapTypeId')[i].value,
cityArray.push(valuesX);
}
var cityArray = JSON.stringify(cityArray);

How to zoom all markers in Leaflet

This is the code I have to show the markers on the map:
var coordinates = data;
for (var i = 0; i < coordinates.length; i++) {
if (coordinates[i].x && coordinates[i].y) {
var marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: " + coordinates[i].device_type + '<br>' + "Time: " + coordinates[i].datetime)
.addTo(map);
}
}
It's working, but I can't zoom to view all markers in the window when I refresh the page.
I tried:
map.fitBounds(coordinates.getBounds());
But it's not working.
Update your code to:
var fg = L.featureGroup();
fg.addTo(map)
var coordinates = data;
for (var i = 0; i < coordinates.length; i++) {
if (coordinates[i].x && coordinates[i].y) {
var marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: " + coordinates[i].device_type + '<br>' + "Time: " + coordinates[i].datetime)
.addTo(fg);
}
}
map.fitBounds(fg.getBounds());

null is not an object - jQuery + leaflet

I'm trying to get some data using a query build like this:
function buildQuery(startDate, endDate)
{
/*http://data.cityofnewyork.us/resource/erm2-nwe9.json?$where=(latitude%20IS%20NOT%20NULL)%
20AND%20(complaint_type%20like%20%27\%Noise\%%27)%20AND%20(created_date%3E=%272013-08-01%27)%
20AND%20(created_date%3C=%272013-08-08%27)&$group=complaint_type,descriptor,latitude,longitude&$
select=descriptor,latitude,longitude,complaint_type*/
var start_date = formattedDate(startDate); //YYYY-MM-DD
var end_date = formattedDate(endDate); //YYYY-MM-DD
var c_type = 'Noise'; // Complaint Type
// Build the data URL
URL = "http://data.cityofnewyork.us/resource/erm2-nwe9.json"; // API Access Endpoint
URL += "?"; // A query parameter name is preceded by the question mark
URL += "$where="; // Filters to be applied
URL += "(latitude IS NOT NULL)"; // Only return records with coordinates
URL += " AND ";
URL += "(complaint_type like '\\%" + c_type + "\\%')";
URL += " AND ";
URL += "(created_date>='" + start_date + "') AND (created_date<='" + end_date + "')"; // Date range
URL += "&$group=complaint_type,descriptor,latitude,longitude"; // Fields to group by
URL += "&$select=descriptor,latitude,longitude,complaint_type"; // Fields to return
URL = encodeURI(URL); // Encode special characters such as spaces and quotes
URL = URL.replace("'%5C%25", "%27\\%"); // Only way that seems to work in Safari
URL = URL.replace("%5C%25'", "\\%%27");
}
Then, I plot the latitude / longitude of the response as follows:
function load311ComplaintsIntoMap(map)
{
cleanMap();
$.getJSON(URL, function(data)
{
if ( data.length == 0 )
{
return;
}
var markers = []
for (var i = 0; i < noise_description.length; i++)
{
markers[i] = [];
}
var all_markers = [];
$.each(data, function(index, rec)
{
var marker;
for (var i = 0; i < noise_description.length; i++)
{
if (rec.descriptor.indexOf(noise_description[i]) > -1)
{
marker = L.circleMarker([rec.latitude, rec.longitude], marker_style(i));
markers[i].push(marker);
all_markers.push(marker);
break;
}
if (i == noise_description.length-1)
{
marker = L.circleMarker([rec.latitude, rec.longitude], marker_style(i));
markers[i].push(marker);
all_markers.push(marker);
}
}
});
// Create layer of all markers but do not add to map
var all_layers = L.featureGroup(all_markers);
// Create specific layers of markers and add to map
for (var i = 0; i < markers.length; i++)
{
layers[i] = L.featureGroup(markers[i]).addTo(map);
layers[i].bringToFront();
} // 311complaints.js:152
map.fitBounds(all_layers.getBounds());
for (var i = 0; i < noise_description.length; i++)
{
overlays['<i style="background:' + getColor(i) + '"></i> ' +noise_description[i]] = layers[i];
}
// Add layer control using above object
layer = L.control.layers(null,overlays).addTo(map);
});
}
However, I'm receiving this error:
TypeError: null is not an object (evaluating 't.lat')
projectleaflet.js:5:17200
latLngToPointleaflet.js:5:17604
projectleaflet.js:5:24291
latLngToLayerPointleaflet.js:5:24556
projectLatlngsleaflet.js:7:15193
redrawleaflet.js:6:28501
setRadiusleaflet.js:7:15524
_updateStyleleaflet.js:7:15290
_initStyleleaflet.js:6:30051
_initElementsleaflet.js:6:29400
onAddleaflet.js:6:27822
_layerAddleaflet.js:5:29679
addLayerleaflet.js:5:21183
eachLayerleaflet.js:6:25647
onAddleaflet.js:6:25458
_layerAddleaflet.js:5:29679
addLayerleaflet.js:5:21183
addToleaflet.js:6:25578
(anonymous function)311complaints.js:152
jjquery-2.1.0.min.js:1:26681
fireWithjquery-2.1.0.min.js:1:27490
xjquery-2.1.0.min.js:3:10523
(anonymous function)jquery-2.1.0.min.js:3:14160
And I don't know why, since I request fields that have a valid latitude.
Some of the objects that you get back from the API does not have a latitude.
Check that they do before adding it to the map:
rec.hasOwnProperty("latitude") && rec.hasOwnProperty("longitude")

Function call doesn't work [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I'm trying to execute a function that alerts an array but it doesn't work. When I press the Add button, I'm supposed to have an alert containing Lat/lng, but no alert appears.
You can see my working code here: jsfiddle. Press the Add button to see the phenomenon. I call the function f() in line 195 but I don't get anything.
My HTML code:
<div id="info"></div>
<div id="dvMap"></div>
<div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
<div id="wrapper">Paste coordinate data here:
<form onSubmit="javascript:return false;">
<textarea id="Coords" cols="50" rows="25"></textarea>
<div>
<input type="button" id="btnAdd" class="Button" value="Add Markers" onClick="ProcessData()">
<input type="button" id="btnClear" class="Button" value="Clear Map" onClick="Clear()">
</div>
<br>
</form>
</div>
My Javascript code:
var directionsDisplay = [];
var directionsService = [];
var map = null;
var g = [];
var path = new Array();
var routeSegment = 0;
var k = 0;
function inizialise() {
var mapOptions = {
center: new google.maps.LatLng(33.730166863, 130.7446296584),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
document.getElementById("Coords").value = '33.29702, 130.54948000000002' + '\n' + '33.29764, 130.54986000000002' + '\n' + '33.29793, 130.55010000000001' + '\n' + '33.298730000000006, 130.55066000000002' + '\n' + '33.299620000000004, 130.55129000000002'
// calcRoute() ;
}
var MyArray = [];
function Clear() {
//alert(directionsDisplay.length);
MyArray = [];
for (var i = 0; i < directionsDisplay.length; i++) {
directionsDisplay[i].setMap(null);
}
// directionsDisplay = [];
document.getElementById("Coords").value = "";
document.getElementById("Coords").disabled = false;
document.getElementById("btnAdd").disabled = false;
}
function ProcessData() {
var Points = document.getElementById("Coords").value
if (document.getElementById("Coords").value != '') {
var Points = document.getElementById("Coords").value
calcRoute(Points);
}
}
/*
function ProcessData() {
alert('ok');
if (document.getElementById("Coords").value != '') {
var Points = document.getElementById("Coords").value
AddMarkers(Points);
}
}*/
function AddMarkers(data) {
var MyData = data.substr(0, data.length);
MyArray = MyData.split("\n");
//alert(MyArray[2]);
// calcRoute();
t();
}
function calcRoute(data) {
var MyData = data.substr(0, data.length);
MyArray = MyData.split("\n");
var input_msg = MyArray;
var locations = new Array();
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < input_msg.length; i++) {
var tmp_lat_lng = input_msg[i].split(",");
//var s = new google.maps.LatLng(tmp_lat_lng[0], tmp_lat_lng[1]);
locations.push(new google.maps.LatLng(tmp_lat_lng[0], tmp_lat_lng[1]));
bounds.extend(locations[locations.length - 1]);
}
/* var mapOptions = {
// center: locations[0],
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('dvMap'), mapOptions);
*/
map.fitBounds(bounds);
var summaryPanel = document.getElementById("directions_panel");
summaryPanel.innerHTML = "";
var i = locations.length;
var index = 0;
while (i != 0) {
if (i < 3) {
var tmp_locations = new Array();
for (var j = index; j < locations.length; j++) {
tmp_locations.push(locations[j]);
}
drawRouteMap(tmp_locations);
i = 0;
index = locations.length;
}
if (i >= 3 && i <= 10) {
console.log("before :fun < 10: i value " + i + " index value" + index);
var tmp_locations = new Array();
for (var j = index; j < locations.length; j++) {
tmp_locations.push(locations[j]);
}
drawRouteMap(tmp_locations);
i = 0;
index = locations.length;
console.log("after fun < 10: i value " + i + " index value" + index);
}
if (i >= 10) {
console.log("before :fun > 10: i value " + i + " index value" + index);
var tmp_locations = new Array();
for (var j = index; j < index + 10; j++) {
tmp_locations.push(locations[j]);
}
drawRouteMap(tmp_locations);
i = i - 9;
index = index + 9;
console.log("after fun > 10: i value " + i + " index value" + index);
}
}
}
var coord = new Array();
function drawRouteMap(locations) {
var start, end;
var waypts = [];
for (var k = 0; k < locations.length; k++) {
if (k >= 1 && k <= locations.length - 2) {
waypts.push({
location: locations[k],
stopover: true
});
}
if (k == 0) start = locations[k];
if (k == locations.length - 1) end = locations[k];
}
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: false,
travelMode: google.maps.TravelMode.DRIVING
};
console.log(request);
directionsService.push(new google.maps.DirectionsService());
var instance = directionsService.length - 1;
directionsDisplay.push(new google.maps.DirectionsRenderer({
preserveViewport: true
}));
directionsDisplay[instance].setMap(map);
directionsService[instance].route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
console.log(status);
directionsDisplay[instance].setDirections(response);
var f = response.routes[0];
// var summaryPanel = document.getElementById("directions_panel");
var route = directionsDisplay[instance].getDirections().routes[0];
// var routes = response.routes;
var points = route.overview_path;
//alert(points);
var ul = document.getElementById("directions_panel");
var legs = response.routes[0].legs;
for (i = 0; i < legs.length; i++) {
var steps = legs[i].steps;
for (j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
for (k = 0; k < nextSegment.length; k++) {
// alert(nextSegment[k]);
var li = document.createElement('P');
li.innerHTML = getLatLng(nextSegment[k]);
ul.appendChild(li);
// polyline.getPath().push(nextSegment[k]);
//bounds.extend(nextSegment[k]);
coord.push( getLatLng(nextSegment[k]));
f(coord);
}
}
}
} else {
alert("directions response " + status);
}
});
}
function f( r) {
alert(r);
}
function getLatLng(point) {
//alert(MyArray.length);
var lat = point.lat(),
lng = point.lng();
var tmp = MyArray[k].split(",");
// alert( Math.abs(parseFloat(tmp[0]- lat)) )
if (Math.abs(parseFloat(tmp[0] - lat)) < 0.00009 && Math.abs(parseFloat(tmp[1] - lng)) < 0.00009) {
k++;
// alert(k);
//if(k==MyArray.length) { f('animation'); }
return " { \"lat\": " + lat + " ,\"lng\" : " + lng + " ,\"waypoint\" : 1},";
} else {
return " { \"lat\": " + lat + " ,\"lng\" : " + lng + " ,\"waypoint\" : 0},";
}
}
google.maps.event.addDomListener(window, 'load', inizialise);
The problematic code is in line 195: I call f(coord), but the alert doesn't appear. I have defined the f function as such:
function f(r) {
alert(r);
}
You're overwriting f with an object in line 173:
var f = response.routes[0];
So when you try to call f, it's not a function, but an object (try logging typeof f before the call: you will get 'object').
I managed to fix the problem. I edite my function 'getLatLng()' such as :
function getLatLng(point, array) {
//alert(k);
var lat = point.lat(),
lng = point.lng();
var tmp = MyArray[k].split(",");
// alert( Math.abs(parseFloat(tmp[0]- lat)) )
if (Math.abs(parseFloat(tmp[0] - lat)) < 0.00009 && Math.abs(parseFloat(tmp[1] - lng)) < 0.00009) {
k++;
array.push({
"lat": lat ,
"lng": lng,
"stop":1
});
return " { \"lat\": " + lat + " ,\"lng\" : " + lng + " ,\"waypoint\" : 1},";
} else {
array.push({
"lat": lat ,
"lng": lng,
"stop":1
});
return " { \"lat\": " + lat + " ,\"lng\" : " + lng + " ,\"waypoint\" : 0},";
}
}
Now I can acess to the element of my array. Here my code

Javascript Hanging UI on IE6/7

Could anyone suggest performance improvements for the function I've written (below, javascript with bits of jquery)? Or point out any glaring, basic flaws? Essentially I have a javascript Google map and a set of list based results too, and the function is fired by a checkbox click, which looks at the selection of checkboxes (each identifying a 'filter') and whittles the array data down accordingly, altering the DOM and updating the Google map markers according to that. There's a 'fake' loader image in there too at the mo that's just on a delay so that it animates before the UI hangs!
function updateFilters(currentCheck) {
if (currentCheck == undefined || (currentCheck != undefined && currentCheck.disabled == false)) {
var delay = 0;
if(document.getElementById('loader').style.display == 'none') {
$('#loader').css('display', 'block');
delay = 750;
}
$('#loader').delay(delay).hide(0, function(){
if (markers.length > 0) {
clearMarkers();
}
var filters = document.aspnetForm.filters;
var markerDataArray = [];
var filterCount = 0;
var currentfilters = '';
var infoWindow = new google.maps.InfoWindow({});
for (i = 0; i < filters.length; i++) {
var currentFilter = filters[i];
if (currentFilter.checked == true) {
var filtername;
if (currentFilter.parentNode.getElementsByTagName('a')[0].textContent != undefined) {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].textContent;
} else {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].innerText;
}
currentfilters += '<li>' + $.trim(filtername) +
$.trim(document.getElementById('remhide').innerHTML).replace('#"','#" onclick="toggleCheck(\'' + currentFilter.id + '\');return false;"');
var nextFilterArray = [];
filterCount++;
for (k = 0; k < filterinfo.length; k++) {
var filtertype = filterinfo[k][0];
if (filterinfo[k][0] == currentFilter.id) {
var sitearray = filterinfo[k][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
if (filterCount > 1) {
nextFilterArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
} else {
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
if (filterCount > 1) {
var itemsToRemove = [];
for (j = 0; j < markerDataArray.length; j++) {
var exists = false;
for (k = 0; k < nextFilterArray.length; k++) {
if (markerDataArray[j] == nextFilterArray[k]) {
exists = true;
}
}
if (exists == false) {
itemsToRemove.push(j);
}
}
var itemsRemoved = 0;
for (j = 0; j < itemsToRemove.length; j++) {
markerDataArray.splice(itemsToRemove[j]-itemsRemoved,1);
itemsRemoved++;
}
}
}
}
if (currentfilters != '') {
document.getElementById('appliedfilters').innerHTML = currentfilters;
document.getElementById('currentfilters').style.display = 'block';
} else {
document.getElementById('currentfilters').style.display = 'none';
}
if (filterCount < 1) {
for (j = 0; j < filterinfo.length; j++) {
var filtertype = filterinfo[j][0];
if (filterinfo[j][0] == 'allvalidsites') {
var sitearray = filterinfo[j][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
var infoWindow = new google.maps.InfoWindow({});
var resultHTML = '<div id="page1" class="page"><ul>';
var count = 0;
var page = 1;
var paging = '<li class="selected">1</li>';
for (i = 0; i < markerDataArray.length; i++) {
var markerInfArray = markerDataArray[i].split('|');
var url = '';
var name = '';
var placename = '';
var region = '';
var summaryimage = 'images/controls/placeholder.gif';
var summary = '';
var flag = 'images/controls/placeholderf.gif';
for (j = 0; j < tsiteinfo.length; j++) {
var thissite = tsiteinfo[j].split('|');
if (thissite[0] == markerInfArray[2]) {
name = thissite[1];
placename = thissite[2];
region = thissite[3];
if (thissite[4] != '') {
summaryimage = thissite[4];
}
summary = thissite[5];
if (thissite[6] != '') {
flag = thissite[6];
}
}
}
for (k = 0; k < sitemapperinfo.length; k++) {
var thissite = sitemapperinfo[k].split('|');
if (thissite[0] == markerInfArray[2]) {
url = thissite[1];
}
}
var markerLatLng = new google.maps.LatLng(markerInfArray[1].toString(), markerInfArray[0].toString());
var infoWindowContent = '<div class="infowindow">' + markerInfArray[2] + ': ';
var siteurl = approot + '/sites/' + url;
infoWindowContent += '<strong>' + name + '</strong>';
infoWindowContent += '<br /><br/><em>' + placename + ', ' + region + '</em></div>';
marker = new google.maps.Marker({
position: markerLatLng,
title: $("<div/>").html(name).text(),
shadow: shadow,
icon: image
});
addInfo(infoWindow, marker, infoWindowContent);
markers.push(marker);
count++;
if ((count > 20) && ((count % 20) == 1)) { // 20 per page
page++;
resultHTML += '</ul></div><div id="page' + page + '" class="page"><ul>';
paging += '<li>' + page + '</li>';
}
resultHTML += '<li><div class="namehead"><h2>' + name + ' <span>' + placename + ', ' + region + '</span></h2></div>' +
'<div class="codehead"><h2><img alt="' + region + '" src="' + approot +
'/' + flag + '" /> ' + markerInfArray[2] + '</h2></div>' +
'<div class="resultcontent"><img alt="' + name + '" src="' + approot +
'/' + summaryimage +'" />' + '<p>' + summary + '</p>' + document.getElementById('buttonhide').innerHTML.replace('#',siteurl) + '</div></li>';
}
$('#filteredmap .paging').each(function(){
$(this).html(paging);
});
document.getElementById('resultslist').innerHTML = resultHTML + '</ul></div>';
document.getElementById('count').innerHTML = count + ' ';
document.getElementById('page1').style.display = 'block';
for (t = 0; t < markers.length; t++) {
markers[t].setMap(filteredMap);
}
});
}
}
function clearMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setMap(null);
markers[i] = null;
}
markers.length = 0;
}
However, I'm suffering from performance issues (UI hanging) specifically in IE6 and 7 when the number of results is high, but not in any other modern browsers, i.e. FF, Chrome, Safari etc. It is much worse when the Google map markers are being created and added (if I remove this portion it is still slugglish, but not to the same degree). Can you suggest where I'm going wrong with this?
Thanks in advance :) Please be gentle if you can, I don't do much javascript work and I'm pretty new to it and jquery!
This looks like a lot of work to do at the client no matter what.
Why don't you do this at the server instead, constructing all the HTML there, and just refresh the relevant sections with the results of an ajax query?

Categories

Resources