Hope Someone can help out. The goal of this small project is to search the moviedatabase OMDB, and display the fetched results below the search bar. I have a feeling that the code breaks when I try to use the forEach loop on the returned results, but I cannot find the bugs. Every help is appreciated! Thanks!
var httpRequest = new XMLHttpRequest();
httpRequest.onload = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText).Search;
var body = document.getElementsByTagName("body");
response.forEach(function (element, index) {
body.appendChild(" <img src="+element[index].Poster+"/>" +
"<p>Title: <a href = 'https://www.imdb.com/title/"+element[index].imdbID+"' >" +element[index].Title+ "</a></p>" +
"<p>Year: "+ element[index].Year+"</p>" +
"<p>Type: "+element[index].Type+"</p>");
});
} else {
console.log(httpRequest.statusText);
}
}
};
httpRequest.onerror = function() {
console.log(httpRequest.statusText);
};
var searchMovie = function () {
var input = document.querySelector('input').value;
if (input) {
httpRequest.open('GET', 'https://www.omdbapi.com/?s=' + input + '&plot=short&apikey=b7da8d63');
httpRequest.send(null);
}
};
Here's a working example which assumes that you're getting back an array of movies.
const response = JSON.parse('{"Search":[{"Title":"The Town","Year":"2010","imdbID":"tt0840361","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTcyNzcxODg3Nl5BMl5BanBnXkFtZTcwMTUyNjQ3Mw##._V1_SX300.jpg"},{"Title":"Ghost Town","Year":"2008","imdbID":"tt0995039","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTQyODQ4MzYxN15BMl5BanBnXkFtZTcwOTQ1MDczMw##._V1_SX300.jpg"},{"Title":"Cougar Town","Year":"2009–2015","imdbID":"tt1441109","Type":"series","Poster":"https://m.media-amazon.com/images/M/MV5BMTQyMDI2MDM5NF5BMl5BanBnXkFtZTgwOTcyNDE5MDE#._V1_SX300.jpg"},{"Title":"New in Town","Year":"2009","imdbID":"tt1095174","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMzAxNzU4MDE1Nl5BMl5BanBnXkFtZTcwOTQ0NDcwMg##._V1_SX300.jpg"},{"Title":"Mr. Deeds Goes to Town","Year":"1936","imdbID":"tt0027996","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BNzdiMDVkNmMtNDI0Ny00MTQ5LWEwNjAtODQxOGNjOTZmMGVmL2ltYWdlXkEyXkFqcGdeQXVyMDI2NDg0NQ##._V1_SX300.jpg"},{"Title":"On the Town","Year":"1949","imdbID":"tt0041716","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BNjk0YmVlNTQtZDg0NC00MGYyLWFhYTMtMTBlMzFkYjczMDMyXkEyXkFqcGdeQXVyMDI2NDg0NQ##._V1_SX300.jpg"},{"Title":"The Town That Dreaded Sundown","Year":"2014","imdbID":"tt2561546","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTUwNzUyNjEwM15BMl5BanBnXkFtZTgwOTk3MTc2MjE#._V1_SX300.jpg"}],"totalResults":"1588","Response":"True"}');
// Get the body, which is the first element in the array
// returned by document.getElementsByTagName()
var body = document.getElementsByTagName("body")[0];
var movie;
response.Search.forEach(function (element) {
// Create a new element to append
movie = document.createElement('div');
// Add HTML contents to new element
movie.innerHTML =
"<img src="+element.Poster+"/>" +
"<p>Title: <a href = 'https://www.imdb.com/title/"+element.imdbID+"' >"+element.Title+ "</a></p>" +
"<p>Year: "+element.Year+"</p>" +
"<p>Type: "+element.Type+"</p>";
// Append new element
body.appendChild(movie);
});
<html>
<head></head>
<body>
</body>
</html>
var httpRequest = new XMLHttpRequest();
httpRequest.onload = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText).Search;
var body =document.getElementById('main')
body.innerHTML = ""
//document.getElementsByTagName("body");
response.forEach(function (element, index) {
var img=document.createElement('img')
img.src=element.Poster
var p1=document.createElement('p')
p1.textContent='Title :'
var a=document.createElement('a')
a.textContent=element.Title
a.href=`https://www.imdb.com/title/${element.imdbID}`
p1.appendChild(a)
var p2=document.createElement('p')
p2.textContent=`Year: ${element.Year}`
var p3=document.createElement('p')
p3.textContent=`Type: ${element.Type}`
var div=document.createElement('div')
div.appendChild(img)
div.appendChild(p1)
div.appendChild(p2)
div.appendChild(p3)
body.appendChild(div);
});
} else {
console.log(httpRequest.statusText);
}
}
};
httpRequest.onerror = function() {
console.log(httpRequest.statusText);
};
var searchMovie = function () {
var input = document.querySelector('input').value;
if (input) {
httpRequest.open('GET', 'https://www.omdbapi.com/?s=' + input + '&plot=short&apikey=b7da8d63');
httpRequest.send(null);
}
};
searchMovie();
var eve = document.getElementById("myInput");
eve.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
searchMovie();
}
});;
.input{
position: fixed;}
<input type="text" class="input" id="myInput" name="country" value="time" ><br><br>
<span id="main"></span>
Related
I wrote this code, which creates divs depending on the amount of text files in local directory.
Then I tried to write additional code, which appends photos to each of these divs. Unfortunately, this code doesn't append any photos...
function liGenerator() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
var n = (xmlhttp.responseText.match(/txt/g) || []).length;
for (var i = 1; i < n; i++) {
$.get("projects/txt/"+i+".txt", function(data) {
var line = data.split('\n');
var num = line[0]-"\n";
var clss = line[1];
var title = line[2];
var price = line[3];
var content = line[4];
$("#list-portfolio").append("<li class='item "+clss+" show' onclick='productSelection('"+num+"')'><img src='projects/src/"+num+"/title.jpg'/><div class='title'><h1>"+title+"</h1><h2>"+price+"</h2></div><article>"+content+"</article></li>");
$("#full-size-articles").append("<li class='product "+num+"'><div><div class='photo_gallery'><div id='fsa_img "+num+"'><div width='100%' class='firstgalleryitem'></div></div></div><article class='content'><h1 class='header_article'>"+title+"</h1><h2 class='price_article'>"+price+"</h2><section class='section_article'>"+content+"</section></article></div></li>");
});
}
}
}
};
xmlhttp.open("GET", "projects/txt/", true);
xmlhttp.send();
}
function pushPhotos() {
var list = document.getElementById("full-size-articles").getElementsByTagName("li");
var amount = list.length;
for(var i=1;i<=amount;i++) {
var divID = "#fsa_img "+i;
var where = "projects/src/"+i+"/";
var fx = ".jpg";
loadPhotos(where, fx, divID);
}
}
function loadPhotos(dir, fileextension, div) {
$.ajax({
url: dir,
success: function (data) {
$(data).find("a:contains(" + fileextension + ")").each(function () {
var filename = this.href.replace(window.location, "").replace("http://", "");
$(div).append("<img src='"+dir+filename+"' class='mini_photo'/>");
});
}
});
}
Any ideas on why this code is not working as intended?
The main issue is the space between "#fsa_img" and "i". When I changed it to '"#fsa_img_"+i', the code started work as intended.
As others before I used yql to get data from a website. The website is in xml format.
I am doing this to build a web data connector in Tableau to connect to xmldata and I got my code from here: https://github.com/tableau/webdataconnector/blob/v1.1.0/Examples/xmlConnector.html
As recommended on here: YQL: html table is no longer supported I tried htmlstring and added the reference to the community environment.
// try to use yql as a proxy
function _yqlProxyAjaxRequest2(url, successCallback){
var yqlQueryBase = "http://query.yahooapis.com/v1/public/yql?q=";
var query = "select * from htmlstring where url='" + url + "'";
var restOfQueryString = "&format=xml" ;
var yqlUrl = yqlQueryBase + encodeURIComponent(query) + restOfQueryString + "&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
_ajaxRequestHelper(url, successCallback, yqlUrl, _giveUpOnUrl9);
}
function _giveUpOnUrl9(url, successCallback) {
tableau.abortWithError("Could not load url: " + url);
}
However, I still got the message: Html table no longer supported.
As I don't know much about yql, I tried to work with xmlHttpRequestinstead, but Tableau ended up processing the request for ages and nothing happened.
Here my attempt to find another solution and avoid the yql thingy:
function _retrieveXmlData(retrieveDataCallback) {
if (!window.cachedTableData) {
var conData = JSON.parse(tableau.connectionData);
var xmlString = conData.xmlString;
if (conData.xmlUrl) {
var successCallback = function(data) {
window.cachedTableData = _xmlToTable(data);
retrieveDataCallback(window.cachedTableData);
};
//INSTEAD OF THIS:
//_basicAjaxRequest1(conData.xmlUrl, successCallback);
//USE NOT YQL BUT XMLHTTPREQUEST:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open('GET', 'https://www.w3schools.com/xml/cd_catalog.xml', true);
xhttp.send();
return;
}
try {
var xmlDoc = $.parseXML(conData.xmlString);
window.cachedTableData = _xmlToTable(xmlDoc);
}
catch (e) {
tableau.abortWithError("unable to parse xml data");
return;
}
}
retrieveDataCallback(window.cachedTableData);
}
Does anyone have an idea how to get YQL work or comment on my approach trying to avoid it?
Thank you very much!
For reference, if there is any Tableau user that wants to test it on Tableau, here is my full code:
<html>
<head>
<title>XML Connector</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script src="https://connectors.tableau.com/libs/tableauwdc-1.1.1.js" type="text/javascript"></script>
<script type="text/javascript">
(function() {
var myConnector = tableau.makeConnector();
myConnector.init = function () {
tableau.connectionName = 'XML data';
tableau.initCallback();
};
myConnector.getColumnHeaders = function() {
_retrieveXmlData(function (tableData) {
var headers = tableData.headers;
var fieldNames = [];
var fieldTypes = [];
for (var fieldName in headers) {
if (headers.hasOwnProperty(fieldName)) {
fieldNames.push(fieldName);
fieldTypes.push(headers[fieldName]);
}
}
tableau.headersCallback(fieldNames, fieldTypes); // tell tableau about the fields and their types
});
}
myConnector.getTableData = function (lastRecordToken) {
_retrieveXmlData(function (tableData) {
var rowData = tableData.rowData;
tableau.dataCallback(rowData, rowData.length.toString(), false);
});
};
tableau.registerConnector(myConnector);
})();
function _retrieveXmlData(retrieveDataCallback) {
if (!window.cachedTableData) {
var conData = JSON.parse(tableau.connectionData);
var xmlString = conData.xmlString;
if (conData.xmlUrl) {
var successCallback = function(data) {
window.cachedTableData = _xmlToTable(data);
retrieveDataCallback(window.cachedTableData);
};
//_basicAjaxRequest1(conData.xmlUrl, successCallback);
//here try another approach not using yql but xmlHttpRequest?
//try xml dom to get url (xml http request)
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open('GET', 'https://www.w3schools.com/xml/cd_catalog.xml', true);
xhttp.send();
return;
}
try {
var xmlDoc = $.parseXML(conData.xmlString);
window.cachedTableData = _xmlToTable(xmlDoc);
}
catch (e) {
tableau.abortWithError("unable to parse xml data");
return;
}
}
retrieveDataCallback(window.cachedTableData);
}
function myFunction(xml) {
var xmlDoc = xml.responseXML;
window.cachedTableData = _xmlToTable(xmlDoc);
}
// There are a lot of ways to handle URLS. Sometimes we'll need workarounds for CORS. These
// methods chain together a series of attempts to get the data at the given url
function _ajaxRequestHelper(url, successCallback, conUrl, nextFunction,
specialSuccessCallback){
specialSuccessCallback = specialSuccessCallback || successCallback;
var xhr = $.ajax({
url: conUrl,
dataType: 'xml',
success: specialSuccessCallback,
error: function()
{
nextFunction(url, successCallback);
}
});
}
// try the straightforward request
function _basicAjaxRequest1(url, successCallback){
_ajaxRequestHelper(url, successCallback, url, _yqlProxyAjaxRequest2);
}
// try to use yql as a proxy
function _yqlProxyAjaxRequest2(url, successCallback){
var yqlQueryBase = "http://query.yahooapis.com/v1/public/yql?q=";
var query = "select * from htmlstring where url='" + url + "'";
var restOfQueryString = "&format=xml" ;
var yqlUrl = yqlQueryBase + encodeURIComponent(query) + restOfQueryString + "&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
_ajaxRequestHelper(url, successCallback, yqlUrl, _giveUpOnUrl9);
}
function _giveUpOnUrl9(url, successCallback) {
tableau.abortWithError("Could not load url: " + url);
}
// Takes a hierarchical xml document and tries to turn it into a table
// Returns an object with headers and the row level data
function _xmlToTable(xmlDocument) {
var rowData = _flattenData(xmlDocument);
var headers = _extractHeaders(rowData);
return {"headers":headers, "rowData":rowData};
}
// Given an object:
// - finds the longest array in the xml
// - flattens each element in that array so it is a single element with many properties
// If there is no array that is a descendent of the original object, this wraps
function _flattenData(xmlDocument) {
// first find the longest array
var longestArray = _findLongestArray(xmlDocument, xmlDocument);
if (!longestArray || longestArray.length == 0) {
// if no array found, just wrap the entire object blob in an array
longestArray = [objectBlob];
}
toRet = [];
for (var ii = 0; ii < longestArray.childNodes.length; ++ii) {
toRet[ii] = _flattenObject(longestArray.childNodes[ii]);
}
return toRet;
}
// Given an element with hierarchical properties, flattens it so all the properties
// sit on the base element.
function _flattenObject(xmlElt) {
var toRet = {};
if (xmlElt.attributes) {
for (var attributeNum = 0; attributeNum < xmlElt.attributes.length; ++attributeNum) {
var attribute = xmlElt.attributes[attributeNum];
toRet[attribute.nodeName] = attribute.nodeValue;
}
}
var children = xmlElt.childNodes;
if (!children || !children.length) {
if (xmlElt.textContent) {
toRet.text = xmlElt.textContent.trim();
}
} else {
for (var childNum = 0; childNum < children.length; ++childNum) {
var child = xmlElt.childNodes[childNum];
var childName = child.nodeName;
var subObj = _flattenObject(child);
for (var k in subObj) {
if (subObj.hasOwnProperty(k)) {
toRet[childName + '_' + k] = subObj[k];
}
}
}
}
return toRet;
}
// Finds the longest array that is a descendent of the given object
function _findLongestArray(xmlElement, bestSoFar) {
var children = xmlElement.childNodes;
if (children && children.length) {
if (children.length > bestSoFar.childNodes.length) {
bestSoFar = xmlElement;
}
for (var childNum in children) {
var subBest = _findLongestArray(children[childNum], bestSoFar);
if (subBest.childNodes.length > bestSoFar.childNodes.length) {
bestSoFar = subBest;
}
}
}
return bestSoFar;
}
// Given an array of js objects, returns a map from data column name to data type
function _extractHeaders(rowData) {
var toRet = {};
for (var row = 0; row < rowData.length; ++row) {
var rowLine = rowData[row];
for (var key in rowLine) {
if (rowLine.hasOwnProperty(key)) {
if (!(key in toRet)) {
toRet[key] = _determineType(rowLine[key]);
}
}
}
}
return toRet;
}
// Given a primitive, tries to make a guess at the data type of the input
function _determineType(primitive) {
// possible types: 'float', 'date', 'datetime', 'bool', 'string', 'int'
if (parseInt(primitive) == primitive) return 'int';
if (parseFloat(primitive) == primitive) return 'float';
if (isFinite(new Date(primitive).getTime())) return 'datetime';
return 'string';
}
function _submitXMLToTableau(xmlString, xmlUrl) {
var conData = {"xmlString" : xmlString, "xmlUrl": xmlUrl};
tableau.connectionData = JSON.stringify(conData);
tableau.submit();
}
function _buildConnectionUrl(url) {
// var yqlQueryBase = "http://query.yahooapis.com/v1/public/yql?q=";
// var query = "select * from html where url='" + url + "'";
// var restOfQueryString = "&format=xml";
// var yqlUrl = yqlQueryBase + encodeURIComponent(query) + restOfQueryString;
// return yqlUrl;
return url;
}
$(document).ready(function(){
var cancel = function (e) {
e.stopPropagation();
e.preventDefault();
}
$("#inputForm").submit(function(e) { // This event fires when a button is clicked
// Since we use a form for input, make sure to stop the default form behavior
cancel(e);
var xmlString = $('textarea[name=xmlText]')[0].value.trim();
var xmlUrl = $('input[name=xmlUrl]')[0].value.trim();
_submitXMLToTableau(xmlString, xmlUrl);
});
var ddHandler = $("#dragandrophandler");
ddHandler.on('dragenter', function (e)
{
cancel(e);
$(this).css('border', '2px solid #0B85A1');
}).on('dragover', cancel)
.on('drop', function (e)
{
$(this).css('border', '2px dashed #0B85A1');
e.preventDefault();
var files = e.originalEvent.dataTransfer.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(e) { _submitXMLToTableau(reader.result); };
reader.readAsText(file);
});
$(document).on('dragenter', cancel)
.on('drop', cancel)
.on('dragover', function (e)
{
cancel(e);
ddHandler.css('border', '2px dashed #0B85A1');
});
});
</script>
<style>
#dragandrophandler {
border:1px dashed #999;
width:300px;
color:#333;
text-align:left;vertical-align:middle;
padding:10px 10px 10 10px;
margin:10px;
font-size:150%;
}
</style>
</head>
<body>
<form id="inputForm" action="">
Enter a URL for XML data:
<input type="text" name="xmlUrl" size="50" />
<br>
<div id="dragandrophandler">Or Drag & Drop Files Here</div>
<br>
Or paste XML data below
<br>
<textarea name="xmlText" rows="10" cols="70"/></textarea>
<input type="submit" value="Submit">
</form>
How to populate the select list with the values that I got with javascript?
I am sending a GET request to a .php site which gives me the respond in JSON format. Now I want to put those lines I got into the select list.
<select id = "list" name=log size=50 style=width:1028px>
<script type="text/javascript">
window.onload = function () {
var bytes=0;
var url = "/test/log.php?q='0'";
function httpGet(url)
{
var xhttp = new XMLHttpRequest();
var realurl = url + bytes;
xhttp.open("GET", url, true);
xhttp.onload = function (e) {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log(xhttp.responseText);
var response=JSON.parse(xhttp.responseText);
var log = response.key;
bytes = log.length;
}
};
xhttp.onerror = function (e) {
console.error(xhttp.statusText);
}
};
xhttp.send();
}
var updateInterval = 2000;
function update() {
httpGet(url);
setTimeout(update, updateInterval);
}
update();
}
</script>
</select>
The response I get from log.php is "{"key":"whole log file"}". Now I want to store that reponse into a list and populate it every 2 seconds.
Loop over the contents of the returned string after JSON.parse-ing it. Create option elements from it, and insert those into the select.
var html = "";
var obj = JSON.parse(xhttp.responseText);
for(var key in obj) {
html += "<option value=" + key + ">" +obj[key] + "</option>";
}
document.getElementById("list").innerHTML = html;
See JSBin
I have an interface that need user to input zip code, then I will query the longitude and latitude from a remote site based on the inputted zip, then query some population information based on previous queried longitude and latitude. I need 3 XMLhttpRequest() to query three different sites. Each query will based on previous queried data. I think there may have some callback issues in my code, I don't know how to fix it.
<input type="submit" value="Get City" onclick="getInfo()">
<script>
function getInfo(getGeoCode) {
var zipCode = document.getElementById("inputtext").value
var xmlReq = new XMLHttpRequest();
xmlReq.open("GET", "http://api.zippopotam.us/us/" + zipCode, true);
xmlReq.onreadystatechange = function () {
if (xmlReq.readyState == 4) {
var temp = JSON.parse(xmlReq.responseText);
var lat = temp.places[[0]].latitude ;
var logt = temp.places[[0]].longitude;
getGeoCode(lat, logt);
};
};
xmlReq.send();
}
function getGeoCode(lat,logt,getpop) {
var nereq = new XMLHttpRequest();
nereq.open("GET", "https://data.fcc.gov/api/block/find?&latitude=" + lat + "&longitude=" + logt + "&showall=false&format=json", true);
nereq.onreadystatechange = function () {
if (nereq.readyState == 4) {
var temp2 = JSON.parse(nereq.responseText);
var stateCode = temp2.State.FIPS;
var contyCode = temp2.County.FIPS;
getpop(stateCode, contyCode);
};
};
nereq.send();
}
function getpop(stateCode, contyCode) {
var nereq2 = new XMLHttpRequest();
nereq2.open("GET", "http://api.census.gov/data/2010/sf1?get=P0010001&for=county:" + contyCode + "&in=state:" + stateCode, true);
nereq2.onreadystatechange = function () {
if (nereq2.readyState == 4) {
var temp3 = JSON.parse(nereq.responseText);
document.getElementById("fs").innerHTML = temp3;
};
};
nereq2.send();
}
</script>
Your functions have arguments which conflict with the function names you call, so they are not accessible anymore.
For example, getGeoCode has an argument called getpop. When getpop is called, it does not call the function of that name, but tries to call the reference that the getpop argument references. Especially as you aren't passing anything in this paarmeter, it is most likely erroring.
The solution is to just remove the getGeoCode parameter from getInfo() and the getpop parameter from getGeoCode():
<input type="submit" value="Get City" onclick="getInfo()">
<script>
function getInfo() {
var zipCode = document.getElementById("inputtext").value
var xmlReq = new XMLHttpRequest();
xmlReq.open("GET", "http://api.zippopotam.us/us/" + zipCode, true);
xmlReq.onreadystatechange = function () {
if (xmlReq.readyState == 4) {
var temp = JSON.parse(xmlReq.responseText);
var lat = temp.places[[0]].latitude ;
var logt = temp.places[[0]].longitude;
getGeoCode(lat, logt);
};
};
xmlReq.send();
}
function getGeoCode(lat,logt) {
var nereq = new XMLHttpRequest();
nereq.open("GET", "https://data.fcc.gov/api/block/find?&latitude=" + lat + "&longitude=" + logt + "&showall=false&format=json", true);
nereq.onreadystatechange = function () {
if (nereq.readyState == 4) {
var temp2 = JSON.parse(nereq.responseText);
var stateCode = temp2.State.FIPS;
var contyCode = temp2.County.FIPS;
getpop(stateCode, contyCode);
};
};
nereq.send();
}
function getpop(stateCode, contyCode) {
var nereq2 = new XMLHttpRequest();
nereq2.open("GET", "http://api.census.gov/data/2010/sf1?get=P0010001&for=county:" + contyCode + "&in=state:" + stateCode, true);
nereq2.onreadystatechange = function () {
if (nereq2.readyState == 4) {
var temp3 = JSON.parse(nereq.responseText);
document.getElementById("fs").innerHTML = temp3;
};
};
nereq2.send();
}
</script>
I have some divs that I replace with new html. So far so good.
(function() {
var obj = function(div) {
var obj = {};
obj.divToReplace = div;
obj.objId = obj.divToReplace.dataset.id;
obj.template = "<div class="newDivs"><p>#Name</p><img src='#ImageUrl'/></div>";
obj.replaceDiv = function() {
var xhr = new XMLHttpRequest();
xhr.open( 'GET', encodeURI('http://.../' + obj.objId) );
xhr.onload = function(e) {
if (xhr.status === 200) {
var x = JSON.parse(xhr.responseText).data.attributes;
var newHtml = obj.template
.replaceAll("#Name", x.name)
.replaceAll("#ImageUrl", x.imageUrl);
obj.divToReplace.outerHTML = newHtml;
}
else {
console.log(xhr.status);
}
};
xhr.send();
};
return {
replaceDiv: obj.replaceDiv
}
};
String.prototype.replaceAll = function(search, replace)
{
return this.replace(new RegExp(search, 'g'), replace);
};
//get the elements I want to replace
var elems = document.getElementsByClassName('divToReplace');
//replace them
for (i = 0; i < elems.length; i++) {
obj(elems[i]).replaceDiv();
}
//call handleStuff ?
})();
Then I want to add addEventListener to the divs, and it's here I get stuck. I want to call handleStuff() after all the divs are replaced. (Because of course, before I replace them the new divs don't exists.) And I can't use jQuery.
var handleStuff = function(){
var classname = document.getElementsByClassName("newDivs");
var myFunction = function() {
};
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', myFunction, false);
}
...............
How can I add a callback that tells me when all the divs are replaced? Or is it overall not a good solution for what I'm trying to do?
Sorry for using jQuery previously, here is solution with native Promise(tested)
(function() {
var f = {
send : function(){
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open( 'GET', encodeURI('http://www.google.com/') );
xhr.onload = function(e) {
if (xhr.status === 200) {
//your code
resolve();
console.log('resolve');
} else {
console.log(xhr.status);
}
};
xhr.send();
});
return promise;
}
}
var promises = [];
for (i = 0; i < 100; i++) {
promises.push(f.send());
}
Promise.all(promises).then(function(){
console.log('success');
});
})();