show next/previous items of an array - javascript

I am using next/previous buttons to show the corresponding items of an array. I am experiencing two issues...
1) when the page loads, I need to click previous or next two times before anything will happen
2) Let's say I'm at record ID 10 for example. If I press 'next' 5 times to get to record ID 15, then press 'previous', instead of taking me to 14, it will take me to ID 16. If I then hit previous again (and subsequent times), the ID will then decrease as normal. Same thing with previous: If I start at ID 15 and hit previous down to 10, clicking 'next' will take me to ID 9 instead of 11. Then, subsequent clicks of 'next' will increase the ID as normal.
Hopefully this will help explain what I mean...
https://jsfiddle.net/mjcs351L/
This uses a super hero API. You will need your own to test the code but it's free and doesn't even ask you to sign up: https://www.superheroapi.com/
Thanks in advance for any guidance.
var apiKey = "YOUR API";
var charID = Math.floor((Math.random() * 731) + 1);
var website = "https://www.superheroapi.com/api.php/" + apiKey + "/" + charID;
var req = new XMLHttpRequest();
req.open('GET', website, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load', function() {
var result = JSON.parse(req.responseText);
getinfo();
function getinfo() {
document.getElementById('fullname').innerHTML = result.biography["full-name"];
document.getElementById('name').innerHTML = result.name;
document.getElementById('egos').innerHTML = result.biography["alter-egos"];
document.getElementById('charID').innerHTML = result.id;
document.getElementById('birth').innerHTML = result.biography["place-of-birth"];
document.getElementById('height').innerHTML = result.appearance.height;
document.getElementById('weight').innerHTML = result.appearance.weight;
document.getElementById('gender').innerHTML = result.appearance.gender;
document.getElementById('race').innerHTML = result.appearance.race;
document.getElementById('eye').innerHTML = result.appearance["eye-color"];
document.getElementById('hair').innerHTML = result.appearance["hair-color"];
document.getElementById('occupation').innerHTML = result.work.occupation;
document.getElementById('connections').innerHTML = result.connections["group-affiliation"];
document.getElementById('relatives').innerHTML = result.connections.relatives;
document.getElementById("pic").src = result.image.url;
document.getElementById("pic").style.height = 300;
document.getElementById("pic").style.width = 300;
}
function nextItem() {
var test = charID + 1;
var website = "https://www.superheroapi.com/api.php/" + apiKey + "/" + test;
req.open('GET', website, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load', function() {
var result = JSON.parse(req.responseText);
charID = test;
getinfo();
});
req.send(null);
}
function prevItem() {
var test = charID - 1;
var website = "https://www.superheroapi.com/api.php/" + apiKey + "/" + test;
req.open('GET', website, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load', function() {
var result = JSON.parse(req.responseText);
charID = test;
getinfo();
});
req.send(null);
}
document.getElementById('prev_button').addEventListener('click', function(e) {
prevItem();
});
document.getElementById('next_button').addEventListener('click', function(e) {
nextItem();
});
event.preventDefault();
});
req.send(null);

You should try and follow DRY (don't repeat yourself), it makes it easier to debug code. I've tweaked the code a bit to re-use components.
var apiKey = "YOUR API";
var charID = Math.floor((Math.random() * 731) + 1);
function fetchData(id) {
id = id || charID;
var website = "https://www.superheroapi.com/api.php/" + apiKey + "/" + id;
var req = new XMLHttpRequest();
req.open('GET', website, true);
req.setRequestHeader('Content-Type', 'application/json');
req.addEventListener('load', function() {
var result = JSON.parse(req.responseText);
getinfo(result);
});
req.send(null);
}
fetchData()
function getinfo(result) {
document.getElementById('fullname').innerHTML = result.biography["full-name"];
document.getElementById('name').innerHTML = result.name;
document.getElementById('egos').innerHTML = result.biography["alter-egos"];
document.getElementById('charID').innerHTML = result.id;
document.getElementById('birth').innerHTML = result.biography["place-of-birth"];
document.getElementById('height').innerHTML = result.appearance.height;
document.getElementById('weight').innerHTML = result.appearance.weight;
document.getElementById('gender').innerHTML = result.appearance.gender;
document.getElementById('race').innerHTML = result.appearance.race;
document.getElementById('eye').innerHTML = result.appearance["eye-color"];
document.getElementById('hair').innerHTML = result.appearance["hair-color"];
document.getElementById('occupation').innerHTML = result.work.occupation;
document.getElementById('connections').innerHTML = result.connections["group-affiliation"];
document.getElementById('relatives').innerHTML = result.connections.relatives;
document.getElementById("pic").src = result.image.url;
document.getElementById("pic").style.height = 300;
document.getElementById("pic").style.width = 300;
}
function nextItem(ev) {
ev.preventDefault();
fetchData(++charID)
}
function prevItem(ev) {
ev.preventDefault();
fetchData(--charID)
}
document.getElementById('prev_button').addEventListener('click', prevItem);
document.getElementById('next_button').addEventListener('click', nextItem);

Related

how to fix javascript refresh error on google chrome

I have an error which is giving me a hard time to fix. I have written a program in JavaScript but when I refresh it doesn't affect the page. I even closed and opened the browser more than once but it didn't work, please does anyone have a solution to it?
This is some part of the code
var person = document.getElementById('formant');
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var email = document.getElementById('email').value;
var num = document.getElementById('num').value;
var pass = document.getElementById('pass').value;
var conpass = document.getElementById('conpass').value;
var gen ='';
function setgen(f)
{
gen = document.getElementById(f).value;
}
person.addEventListener('submit', red);
function red(m)
{
m.preventDefault();
var xhr = new XMLHttpRequest();
// var response = document.getElementById().innerHTML;
xhr.open('POST','php/signupajax.php',true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = function()
{
if(this.status == 200)
{
if(document.getElementById('pass').value.lenght < 0)
{
alert('less man');
}
console.log(this.responseText);
}
}
xhr.send('fname=' + document.getElementById('fname').value + '&lname=' + document.getElementById('lname').value + '&email=' + document.getElementById('email').value + '&num=' +document.getElementById('num').value+ '&pass=' + document.getElementById('pass').value + '&conpass=' +document.getElementById('conpass').value + '&gen=' + gen);
}
if(document.getElementById('pass').value <6)
{
alert('password not strong');
}
else{
alert('password good');
}

ajax listener for file uploading progress

I cant find a way to get around my code. I have seen some tutorials out there, but because of the way I design my code I guess I need something different.
(function(){
var dropzone = document.getElementById('dropzone');
var uploadFile = function (files) {
var formData = new FormData();
var request = new XMLHttpRequest();
var i;
var file_size = 0;
for(i = 0; i<files.length; i = i+1){
formData.append('file[]', files[i]);
file_size = file_size + files[i].size;
}
request.onload = function(){
var data = this.responseText;
// window.location.reload();
};
request.open('post', 'dragNdrop.php?isNotSet=set');
request.send(formData);
};
dropzone.ondragover = function(){
this.className = 'dropzone dragover';
return false;
};
dropzone.ondragleave = function(){
this.className = 'dropzone';
return false;
};
dropzone.ondrop = function (event) {
event.preventDefault();
this.className = 'dropzone';
uploadFile(event.dataTransfer.files);
return false;
}
}());
This is the code I use to upload a file, but i cant find a way to add a eventlistener that keeps checking if the file has been uploaded. I have tried.
request.upload = function(){console.log("me")} //Returns nothing
I tried something like this:
request.upload.addEventListener("progress", progressBar, false);
function progressBar(event){
var percent = (event.loaded / event.total) * 100;
console.log(percent + " " + event.loaded + " " + event.total);
}
It only returns the value once, I would imagine it needs to return several times as it needs to loop in order to get the progress bar moving?
All this function below was inside the main function.
How else could I do this?

How can I Make Use of Only One Function with My Weather App

In my weather app, I need to get the user location, which I'm getting from ipinfo.io, so that's one http request, and then I make another http request to another api on openweathermap.org. My question is how can I improve my code. Is it possible to make only one http request function and use it for calling both api by passing different parameters. Notice that I do set a number of variables inside each function which are particular to that function. I don't think it is possible to use these variables outside the scope of the function.
Here's my index.js
/*
Weather App Javascript code
author: George Louis
date: 3/11/2018
purpose: get local weather
*/
window.onload = function() {
//variables
var ipUrl = "https://ipinfo.io/json";
var appid = "appid=8e1880f460a20463565be25bc573bdc6";
var location = document.getElementById("location");
var currentDate = new Date();
var dayNight = "day";
//setting the date
var dateElem = document.getElementById("date");
var strDate = currentDate.toString();
dateElem.innerHTML = strDate.substring(0, strDate.length-18)
//calling ipinfo.io/json function
httpReqIpAsync(ipUrl);
//request to ipinfo.io/json
function httpReqIpAsync(url, callback) {
var httpReqIp = new XMLHttpRequest();
httpReqIp.open("GET", url, true)
httpReqIp.onreadystatechange = function() {
if(httpReqIp.readyState == 4 && httpReqIp.status == 200) {
var jsonIp = JSON.parse(httpReqIp.responseText)
var ip = jsonIp.ip;
var city = jsonIp.city;
var country = jsonIp.country;
location.innerHTML = `${city}, ${country}`;
var lat = jsonIp.loc.split(",")[0];
var lon = jsonIp.loc.split(",")[1];
console.log(lat+" "+lon)
var weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&${appid}`;
//calling openweathermap api function
httpReqWeatherAsync(weatherApi);
}
}
httpReqIp.send();
}
//request to openweathermap.com json
function httpReqWeatherAsync(url, callback) {
var httpReqWeather = new XMLHttpRequest();
httpReqWeather.open("GET", url, true);
httpReqWeather.onreadystatechange = function() {
if(httpReqWeather.readyState == 4 && httpReqWeather.status == 200) {
var jsonWeather = JSON.parse(httpReqWeather.responseText);
console.log(jsonWeather)
var weatherDesc = jsonWeather.weather[0].description;
var id = jsonWeather.weather[0].id;
var icon = `<i class="wi wi-owm-${id}"></i>`
var temperature = jsonWeather.main.temp;
var tempFaren = Math.round(1.8 * (temperature - 273) + 32)
// console.log(tempFaren)
var humidity = jsonWeather.main.humidity;
var windSpeed = jsonWeather.wind.speed;
//converting visibility to miles
var visibility = Math.round(jsonWeather.visibility / 1000);
// console.log(visibility)
//find whether is day or night
var sunSet = jsonWeather.sys.sunset;
//sunset is 10 digits and currentDate 13 so div by 1000
var timeNow = Math.round(currentDate / 1000);
console.log(timeNow + "<" + sunSet +" = "+(timeNow < sunSet))
dayNight = (timeNow < sunSet) ? "day" : "night";
//insert into html page
var description = document.getElementById("description");
description.innerHTML = `<i id="icon-desc" class="wi wi-owm-${dayNight}-${id}"></i><p>${weatherDesc}</p>`;
var tempElement = document.getElementById("temperature");
tempElement.innerHTML = `${tempFaren}<i id="icon-thermometer" class="wi wi-thermometer"></i>` ;
var humidityElem = document.getElementById("humidity");
humidityElem.innerHTML = `${humidity}%`;
var windElem = document.getElementById("wind");
windElem.innerHTML = `${windSpeed}m/h`;
var visibilityElem = document.getElementById("visibility");
visibilityElem.innerHTML = `${visibility} miles`;
}
}
httpReqWeather.send();
}
}
You can use the modern way to request with fetch instead, if you like. You can also take advantage of destructuring. This is what I would do:
function httpReqIpAsync(url, callback) {
fetch(url)
.then(response => response.json())
.then(jsonIp => {
const { ip, city, country } = jsonIp;
location.textContent = `${city}, ${country}`;
const [lat, lon] = jsonIp.loc.split(",");
const weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&${appid}`;
return [weatherApi, callback];
})
.then(httpReqWeatherAsync)
}
//request to openweathermap.com json
function httpReqWeatherAsync([url, callback]) {
// ...
Since each request is separate, I think it makes much more sense for them to be in separate functions, rather than consolidating them together.

XMLHttpRequest with multiple queries

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>

Javascript - progress bar with muliple images

I want to preload a bunch of images and show the progress bar in the same time.
At the moment the code works only with 1 image, here is it:
$progress = document.querySelector('#progress');
var url = 'https://placekitten.com/g/2000/2000';
var request = new XMLHttpRequest();
request.onprogress = onProgress;
request.onload = onComplete;
request.onerror = onError;
function onProgress(event) {
if (!event.lengthComputable) {
return;
}
var loaded = event.loaded;
var total = event.total;
var progress = (loaded / total).toFixed(2);
$progress.textContent = 'Loading... ' + parseInt(progress * 100) + ' %';
console.log(progress);
}
function onComplete(event) {
var $img = document.createElement('img');
$img.setAttribute('src', url);
$progress.appendChild($img);
console.log('complete', url);
}
function onError(event) {
console.log('error');
}
$progress.addEventListener('click', function() {
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send(null);
});
<div id="progress">Click me to load</div>
And here is the jsfiddle to test the code out: https://jsfiddle.net/q5d0osLr/
How can I make it work with more than one image?
Use an array to store each progress and create a function to load image and record the necessary information for you.
var $progress = document.querySelector('#progress');
var url = 'https://placekitten.com/g/';
var urls =
['https://i.imgur.com/7raUYR2.jpg', 'https://i.imgur.com/i8GSA1b.jpg', 'https://i.imgur.com/jGkaxEZ.jpg',
'http://i.imgur.com/cuS5DDv.jpg', 'https://i.imgur.com/bl5DOR0.jpg', 'http://i.imgur.com/TuFu2lK.jpg',
'https://i.imgur.com/qbwarWi.jpg', 'https://i.imgur.com/hJ9Ylph.gif', 'https://i.imgur.com/8KLbDxe.jpg',
'https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Pleiades_large.jpg/1024px-Pleiades_large.jpg',
];
// Store all progress.
var allProgress = [];
var loadImage = function(url) {
// Get current index.
var idx = allProgress.length;
// Push a progress in array.
allProgress.push(0.0);
var onProgress = function(evt) {
if (!evt.lengthComputable) {
return;
}
var loaded = evt.loaded;
var total = evt.total;
var progress = (loaded / total);
allProgress[idx] = progress;
// Calculate the progress by sum then divide.
var sum = allProgress.reduce(function(sum, val) {
return sum + val;
});
sum /= allProgress.length;
sum = sum.toFixed(2);
$progress.textContent = 'Loading... ' + parseInt(sum * 100) + ' %';
console.log(progress, idx);
};
var onComplete = function(evt) {
var $img = document.createElement('img');
$img.setAttribute('src', url);
document.body.appendChild($img);
console.log('complete', url);
};
var onError = function(evt) {
// You may have to do something with progress.
console.log('error');
};
// Move the request in function. So each of them is independent.
var request = new XMLHttpRequest();
request.onprogress = onProgress;
request.onload = onComplete;
request.onerror = onError;
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send(null);
};
$progress.addEventListener('click', function() {
urls.forEach(function(url) {
loadImage(url);
});
});
img {
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="progress">Click me to load</div>

Categories

Resources