I created a app using the Google JavaScript Maps API to determine the distance between addresses. I currently have a bug. When the user clicks the row on the table it should highlight the selected row by calling this function: highlight_row().
When testing it does not highlight the row on the first click. It needs to be clicked a second time for it to highlight the row. Why does this function not style the row on the first click? Any help or guidance would be greatly appreciated. Thanks
When I add the highlight_row() function to the global scope, and then call it separately on the onClick I get the same result.
I also have tried adding the onclick inside the span on the table. This only allows the onclick to fire off when the display name cell is clicked. Adding the onClick in the span does style the selected row on the first click. Why does this work when in the tag and not in the tag?
I will add the code below. You will need to add your own google maps api key to test locally.
<!DOCTYPE html>
<html>
<head>
<title>Distance Calculation</title>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&libraries=places"></script>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr.highlighted {
background-color: blue;
color: white; /* For better visibility */
}
</style>
<script>
const destinationAddresses = {
destination1: {
Tour_Location: "Embassy Suites by Hilton Parsippany",
Display_Name: "Hilton Parsippany",
Address1: "909 Parsippany Blvd",
Address2: "",
City: "Parsippany",
State: "NJ",
Zip: "07054",
Tour_Location_Record_Id: "a1F1U000003VKSSUA4",
Phone: "(631) 260-1849",
},
destination2: {
Tour_Location: "Roosevelt Field Mall",
Display_Name: "Roosevelt Field Mall",
Address1: "2nd Floor - Next to Nordstrom",
Address2: "630 Old Country Rd",
City: "Garden City",
State: "NY",
Zip: "11530",
Tour_Location_Record_Id: "a1F1U000003UG8NUAW",
Phone: "(631) 260-1849",
},
destination3: {
Tour_Location: "Club Wyndham Midtown 45",
Display_Name: "Midtown 45",
Address1: "205 E 45th St",
Address2: "",
City: "New York",
State: "NY",
Zip: "10017",
Tour_Location_Record_Id: "a1F1U000003UbX8UAK",
Phone: "(555) 555-5555",
},
// Add more destination objects if needed
};
function getAddress(destination) {
return `${destination.Address1} ${destination.Address2}, ${destination.City}, ${destination.State} ${destination.Zip}`;
}
function SetTourLocationRecordId(recordId) {
console.log(`Tour Location Record Id: ${recordId}`);
const dataArray = recordId.split(",");
const splitData = dataArray.map((data) => data.trim());
const set_Tour_Location_Record_Id = splitData[0]; // Output: a1F1U000003VKSSUA4
const set_Tour_Location = splitData[1]; // Embassy Suites by Hilton Parsippany
const set_Display_Name = splitData[2]; // Output: Hilton Parsippany
const set_Address1 = splitData[3]; // Output: 909 Parsippany Blvd
const set_Address2 = splitData[4]; // Output: Address2
const set_State = splitData[5]; // Output: NJ
const set_City = splitData[6]; // Output: Parsippany
const set_Zip = splitData[7]; // Output: 07054
const set_Phone = splitData[8]; // Output: 07054
alert(`You have selected ${set_Tour_Location}`);
console.log(set_Tour_Location_Record_Id); // Output: a1F1U000003VKSSUA4
console.log(set_Tour_Location); // Output: Embassy Suites by Hilton Parsippany
console.log(set_Display_Name); // Output: Hilton Parsippany
console.log(set_Address1); // Output: 909 Parsippany Blvd
console.log(set_Address2); // Output:
console.log(set_State); // Output: NJ
console.log(set_City); // Output: Parsippany
console.log(set_Zip); // Output: 07054
console.log(set_Phone); // Output: 07054
// set row color
highlight_row();
function highlight_row() {
var table = document.getElementById("display-table");
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
rows[i].addEventListener("click", function () {
// Reset styles for all rows
for (var j = 0; j < rows.length; j++) {
rows[j].style.backgroundColor = "";
rows[j].style.color = "";
}
// Set styles for the clicked row
this.style.backgroundColor = "#1e90ff";
this.style.color = "snow";
});
}
}
}
function calculateDistance() {
const address1 = document.getElementById("address1").value;
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: address1 }, function (results1, status1) {
if (status1 === google.maps.GeocoderStatus.OK) {
const origin = results1[0].geometry.location;
const distanceService = new google.maps.DistanceMatrixService();
distanceService.getDistanceMatrix(
{
origins: [origin],
destinations: Object.values(destinationAddresses).map(
(destination) => getAddress(destination)
),
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.IMPERIAL, // Use miles
},
function (response, status) {
if (status === google.maps.DistanceMatrixStatus.OK) {
let resultHtml = "<table id=display-table>";
resultHtml +=
"<tr><th>Display Name</th><th>City</th><th>State</th><th>Zip</th><th>Distance</th><th>Drive Time</th></tr>";
for (const key in destinationAddresses) {
if (destinationAddresses.hasOwnProperty(key)) {
const destination = destinationAddresses[key];
const address = getAddress(destination);
const distance =
response.rows[0].elements[
parseInt(key.split("destination")[1]) - 1
].distance.text;
const duration =
response.rows[0].elements[
parseInt(key.split("destination")[1]) - 1
].duration.text;
resultHtml += `<tr onclick="SetTourLocationRecordId('${destination.Tour_Location_Record_Id}, ${destination.Tour_Location}, ${destination.Display_Name}, ${destination.Address1}, ${destination.Address2}, ${destination.State}, ${destination.City}, ${destination.Zip}, ${destination.Phone}');"><td> <span >${destination.Display_Name}</td></span><td>${destination.City}</td><td>${destination.State}</td><td>${destination.Zip}</td></td><td>${distance}<td>${duration}</td></tr>`;
}
}
resultHtml += "</table>";
if (resultHtml) {
document.getElementById("result").innerHTML = resultHtml;
} else {
document.getElementById("result").innerHTML =
"Unable to calculate distance for all addresses.";
}
} else {
document.getElementById("result").innerHTML =
"Error calculating distance.";
}
}
);
} else {
document.getElementById("result").innerHTML =
"Invalid origin address.";
}
});
}
</script>
</head>
<body>
<h1>Distance Calculation</h1>
<label for="address1">Origin Address:</label>
<input type="text" id="address1" />
<br />
<button onclick="calculateDistance()">Calculate Distance</button>
<br />
<div id="result"></div>
</body>
</html>
2
Answers
This happens because you are calling
highlight_row()
function before you have defined it. Movinghighlight_row()
function before you call it should solve your problem:The reason because your function worked only after 2nd click, was that on first click program didn’t know anything about
hightlight_row()
function, other than that it just exists somewhere in memory. Because JS run code once, it already know abouthighlight_row()
function, so on 2nd and further clicks your code worked.I would be tempted to modify the original code slightly as below to remove inline function calls and instead use externally registered event handlers. It seems that your
SetTourLocationRecordId
does lots of things but nothing really useful is done with the data passed in so an alternative approach below might be of interest.