Get id from path in SVG - javascript

So I have this SVG
https://github.com/Cphdat3sem2017f/StartcodeExercises/blob/master/JS/Countries_Europe.svg?short_path=6bcbfa5
I managed to hook up an eventListener and a fetch to get information on the countries when clicked on. This I have done by simply calling ex. document.getElementById("dk"). Is there a way and if so how, where i can get the id's inside the paths so I can loop through them and end up with only one call instead of one for each country?
Code:
import "bootstrap/dist/css/bootstrap.css";
const root = document.getElementById("root");
var svg = document.getElementById("svg");
const country = "https://restcountries.eu/rest/v1/alpha?codes=";
svg.addEventListener("load", function() {
var svgDoc = svg.contentDocument;
var countries = svgDoc.children;
for (let i = 0; i < countries.length; i++) {
//alert(countries[i].id);
countries[i].addEventListener("click", function(event) {
alert(countires[i]);
getCountryInfo(countries[i].id);
});
}
svgDoc.addEventListener("click", function(event) {
getCountryInfo(event.id);
});
var denmark = svgDoc.getElementById("dk");
denmark.addEventListener("click", function() {
getCountryInfo("dk");
});
var sweden = svgDoc.getElementById("se");
sweden.addEventListener("click", function() {
getCountryInfo("se");
});
var germany = svgDoc.getElementById("de");
germany.addEventListener("click", function() {
getCountryInfo("de");
});
var norway = svgDoc.getElementById("no");
norway.addEventListener("click", function() {
getCountryInfo("no");
});
var spain = svgDoc.getElementById("es");
spain.addEventListener("click", function() {
getCountryInfo("es");
});
var iceland = svgDoc.getElementById("is");
iceland.addEventListener("click", function() {
getCountryInfo("is");
});
});
function getCountryInfo(landCode) {
fetch(country + landCode)
.then(res => res.json()) //.then(res=>{ return res.json()})
.then(data => {
var table = "";
table +=
'<table border="1" style="border-spacing: 5px; table-layout: auto; width: 45%;">';
table += "<tr>";
table += "<th>Name</th>";
table += "<th>Capital</th>";
table += "<th>Also known as</th>";
table += "<th>Region</th>";
table += "<th>Population</th>";
table += "<th>Languages</th>";
table += "</tr>";
data.forEach(country => {
table += "<tr>";
table += "<td>" + country.name + "</td>";
table += "<td>" + country.capital + "</td>";
table += "<td>" + country.altSpellings + "</td>";
table += "<td>" + country.region + "</td>";
table += "<td>" + country.population + "</td>";
table += "<td>" + country.languages + "</td>";
table += "</tr>";
});
table += "</table>";
root.innerHTML = table;
});
}
As you can see we tried to get them by getting the children elements but we got stuck and couldn't seem to find answer.

Not sure what children resolves to in that context, but you can get to the paths directly via a query:
[...svgDoc.querySelectorAll('path')].forEach(path => {
path.addEventListener('click', e => {
alert(path.id);
})
})

Related

HTML table not displaying

I wanted to display a javascript object variable as a HTML table when a button with the id "stop" is pressed. I took some of my code for this problem from another question, however for some reason the browser doesn't even render the table.
Html
<table id="tbody"></table>
JavaScript
stop.addEventListener("click", () => {
container.style.display = "none";
stop.style.display = "none";
tbody.style.display = "block";
ratings = JSON.parse(sessionStorage.ratings);
for (let i = 0; i < ratings.length; i++) {
let tr = "<tr>";
tr += "<td>" + ratings[i].key.toString() + "</td>" + "<td>" + ratings[i].value.toString() + "</td></tr>";
tbody.innerHTML += tr;
}
});
I even specifically mention the display in my javascript file, as you can see:
tbody.style.display = "block";
If needed, you can find the full code here
#Ashish Kumar was right, the rating variable was an object. The TypeError (that came later) occurred because I was indexing the object like an array. Fixed that through the following edit in the event listener function :
stop.addEventListener("click", () => {
container.style.display = "none";
stop.style.display = "none";
tbody.style.display = "block";
ratings = JSON.parse(sessionStorage.ratings);
// console.log(ratings);
for (let i = 0; i < Object.keys(ratings).length; i++) {
let tr = "<tr>";
tr += "<td>" + Object.keys(ratings)[i] + "</td>" + "<td>" + Object.values(ratings)[i] + "</td></tr>";
tbody.innerHTML += tr;
}
});
stop.addEventListener("click", () => {
container.style.display = "none";
stop.style.display = "none";
ratings = JSON.parse(sessionStorage.ratings); // RATINGS IS OBJECT HERE
for (let i = 0; i < ratings.length; i++) { // ratings.length will not work as it's not an array
let tr = "<tr>";
/* Verification to add the last decimal 0 */
if (ratings[i].value.toString().substring(ratings[i].value.toString().indexOf('.'), ratings[i].value.toString().length) < 2)
ratings[i].value += "0";
/* Must not forget the $ sign */
tr += "<td>" + ratings[i].key.toString() + "</td>" + "<td>" + ratings[i].value.toString() + "</td></tr>";
/* We add the table row to the table body */
tbody.innerHTML += tr;
}
});
Please see the comments added at line 4 and 5

Append button to a table row dynamically using jquery

I have an array of JavaScript JSON objects which is being parsed from a JSON formatted-string. Now what I'm doing is that I'm looping through the array and append the data to a table within the page.
jQuery Code:
$.each(objArr, function(key, value) {
var tr = $("<tr />");
$.each(value, function(k, v) {
tr.append($("<td />", {
html: v
}));
$("#dataTable").append(tr);
})
})
The code works perfectly and the table is getting populated successfully
But what I'm looking for is that, I want to add a delete button at the end of the row, by which the user will delete the row, and it also important to handle the click event in order to perform the required action
I've done this in another way, but it is not that efficient, I want to use the code above to accomplish that as it is more efficient:
for (var i = 0; i < objArr.length; i++) {
var tr = "<tr>";
var td1 = "<td>" + objArr[i]["empID"] + "</td>";
var td2 = "<td>" + objArr[i]["fname"] + "</td>";
var td3 = "<td>" + objArr[i]["lname"] + "</td>";
var td4 = "<td>" + objArr[i]["phone"] + "</td>";
var td5 = "<td>" + objArr[i]["address"] + "</td>";
var td6 = "<td >" + objArr[i]["deptID"] + "</td>";
var td7 = "<td>" + objArr[i]["email"] + "</td>";
var td8 = "<td>" + '<button id="' + objArr[i]["empID"] + '" value="' + objArr[
i]["empID"] + '" onclick="onClickDelete(' + objArr[i]["empID"] +
')">Delete</button>' + "</td></tr>";
$("#dataTable").append(tr + td1 + td2 + td3 + td4 + td5 + td6 + td7 + td8);
}
Any suggestions please?
Try something like this:
$.each(objArr, function (key, value) {
var tr = $("<tr />");
$.each(value, function (k, v) {
tr.append($("<td />", { html: v }));
tr.append("<button class='remove' />");
$("#dataTable").append(tr);
})
})
This shall append the button at the end of the tr with class remove.
Try this, I've include event handler for the each buttons inside the table.
CHANGES:
Adding Event Listener for each buttons inside the table.
Call method (function) with parameters.
Note:
I am using, fadeOut method for fading purposes only. So you can see the changes. You can change the script as your need.
EXPLAINS :
var cRow = $(this).parents('tr'); on this line we have $(this) which mean we've select the button object that you've clicked, and search the parent with tag-name tr. We need to do this because we need to take control of all data inside the tr object.
var cId = $('td:nth-child(2)', cRow).text(); has mean search second td object wich located on cRow object. And take the text from the selected td.
JQUERY REFFERENCES :
.parents()
:nth-child()
$(this) OR $(this)
$(document).ready(function() {
var jsonData = [
{id: 'A01', name: 'Fadhly'},
{id: 'A02', name: 'Permata'},
{id: 'A03', name: 'Haura'},
{id: 'A04', name: 'Aira'}
];
$.each(jsonData, function(key, val) {
var tr = '<tr>';
tr += '<td>' + (key + 1) + '</td>';
tr += '<td>' + val.id + '</td>';
tr += '<td>' + val.name + '</td>';
tr += '<td><button class="delete" data-key="'+ (key + 1) +'">Delete</button></td>';
tr += '</tr>';
$('tbody').append(tr);
});
$('button.delete').on('click', function() {
var cRow = $(this).parents('tr');
var cId = $('td:nth-child(2)', cRow).text();
var intKey = $(this).data('key');
cRow.fadeOut('slow', function() {
doDelete(cId, intKey);
});
});
function doDelete(param1, param2) {
alert('Data with\n\nID: [' + param1 + ']\nKey: [' + param2 + ']\n\nRemoved.');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1" width="100%">
<thead>
<tr>
<th>#</th>
<th>Id</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

JQuery Drag and Drop from two tables

I need to implement drag and drop feature form one table to another and vise versa.
This is my function where i get transactions to particular IBAN number, I also have the same function which retrieves users transaction which are hidden.
function getAllTransactions(iban) {
var iban = $("#ibanSelection").val();
var username = $("#hiddenusername").val();
var url = 'http://localhost:64300/api/BankAccountApi/GetUserTransaction/?iban=' + iban;
var table = "<table id=\"table1\">";
if ((username != "") && (iban !="")) {
$.getJSON(url, function (data) {
table += "<tr class=\"ibanSelection\">";
table += "<th>My IBAN</th>";
table += "<th>Send to IBAN</th>";
table += "<th>Transfer Date</th>";
table += "<th>Amount</th>";
table += "</tr>";
$.each(data, function (key, val) {
table += "<tr class=\"draggable_tr\">";
table += "<td>" + val.My_Iabn + "</td>";
table += "<td>" + val.Iban_To + "</td>";
table += "<td>" + val.Transfer_Date + "</td>";
table += "<td>" + val.Amount_Transferd + "</td>";
table += "</tr>";
});
table += "</table>";
$("#divResult2").html(table);
});
}
}
Just use the jQueryUI Sortable feature.
Here's the complete example + documentation. Very easy.
Also this example shows your case:
http://jqueryui.com/sortable/#connect-lists

Embed Post not showing with FB.api Call Facebook Javascript Api

I'm using Facebook Javascript SDK and FB.api. I read public pages' posts and wanted to show it on my website. So I made the call with FB.api and got the response. But while I try to show them by Facebook Embed System it just didn't show up.
Here is my code
FB.api("/" + PageId + "/posts",
{
access_token: getCookie("access_token"),
since: From,
until: To,
fields: "id,likes.summary(true).limit(0),comments.summary(true).limit(0),shares,link",
limit: LoadLimit,
date_format: "U",
},
function (res) {
$("#load_post").attr("disabled", false).attr("value", "Load Posts");
if (typeof res.error === 'undefined') {
if (res.data.length > 0) {
for (var i = 1; i <= res.data.length; i++) {
var NewData = res.data[i - 1];
var Id = NewData.id.split("_")[1];
var CreatedTime = NewData.created_time;
var Likes = NewData.likes.summary.total_count;
var Comment = NewData.comments.summary.total_count;
var Share = 0;
var Link = NewData.link;
if (typeof NewData.shares !== 'undefined') {
Share = NewData.shares.count;
}
var Data = "";
Data += "<tr>";
Data += "<td>" + i + "</td>";
Data += "<td><div id='" + Id + "' class='fb-post' data-href='" + Link + "' data-width='350'></div></td>";
Data += "<td>" + CreatedTime + "</td>";
Data += "<td>" + Likes + "</td>";
Data += "<td>" + Comment + "</td>";
Data += "<td>" + Share + "</td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "<td></td>";
Data += "</tr>";
$("#data_area").append(Data);
FB.XFBML.parse(document.getElementById(Id));
}
} else {
alert("No data found.");
}
} else {
alert("Error occured.\n" + res.error.message);
}
});
Even I tried "FB.XFBML.parse" but lately checking the documentation I found that it has no effect on Embed Post.
I checked the console and found no error or something.
Please help me out.

Image does not appear on div even though div class changes

I am trying to show an animation on .gif format, before the page loads JSON data on the div. But It does not show gif.
I check in the console if it does not change the class, but it changes.
Basically code should work like this:
1- Press Button
2- Load image (css class: "loading")
3- Start json call (It takes around 8 secs)
4- Load table (css class: "loaded")
HTML and javascript are in seperate files
gif animation loads when I change the classes into the opposite. But this time it loads on the json table data.
CSS:
div.loading {
width: 600px;
height: 600px;
background: #FFF url('loading.gif') no-repeat 50% 50%;
}
div.loaded {
width: 600px;
height: 600px;
}
Javascript:
function loadOutputs() {
console.log(document.getElementById('loadingElement').className);
document.getElementById("loadingElement").className = "loading";
console.log(document.getElementById('loadingElement').className);
makeProxyCall(
"http://localhost:9090/myService/tool/runTool?tool=myTool",
function(data) {
var globalCounter = 0;
var tbody = document.getElementById('tbody');
var trheader = "<tr><td>Name</td><td>Value</td><td>Type</td><td>UnitOfMeasure</td><td>Mode</td></tr>"
tbody.innerHTML = trheader;
for ( var i = 0; i < 10; i++) {
var tr = "<tr>";
//if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2) obj[i].value += "0";
tr += "<td>" + data[0][i].name + "</td>" + "<td>"
+ data[0][i].value + "</td>" + "<td>"
+ data[0][i].type + "</td>" + "<td>"
+ data[0][i].unitOfMeasure + "</td>" + "<td>"
+ data[0][i].mode + "</td></tr>";
tbody.innerHTML += tr;
}
});
document.getElementById("loadingElement").className = "loaded";
console.log(document.getElementById('loadingElement').className);
}
HTML:
<div id="loadingElement" class="loaded">
<button type="button" class="btn-blue"
style="top: 80px; right: 130px;" onclick="loadOutputs()">Load
Outputs</button>
<table>
<tbody id="tbody"></tbody>
</table>
</div>
The javascript is executed asynchronously. The classname 'loaded' is set before makeproxycall is finished.
Add the classname switch to the end of the callback function in makeproxycall:
makeProxyCall(
"http://localhost:9090/myService/tool/runTool?tool=myTool",
function(data) {
var globalCounter = 0;
var tbody = document.getElementById('tbody');
var trheader = "<tr><td>Name</td><td>Value</td><td>Type</td><td>UnitOfMeasure</td><td>Mode</td></tr>"
tbody.innerHTML = trheader;
for ( var i = 0; i < 10; i++) {
var tr = "<tr>";
//if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2) obj[i].value += "0";
tr += "<td>" + data[0][i].name + "</td>" + "<td>"
+ data[0][i].value + "</td>" + "<td>"
+ data[0][i].type + "</td>" + "<td>"
+ data[0][i].unitOfMeasure + "</td>" + "<td>"
+ data[0][i].mode + "</td></tr>";
tbody.innerHTML += tr;
}
document.getElementById("loadingElement").className = "loaded";
});

Categories