I'm trying to create a site where you can search up any country and it'll show you detailed information on it using REST Countries API. I want to have a first HTML page with just a search box in the middle where you type your country. You then press search and it'll redirect you to another HTML page where I've set up a template for the countries flag, capital, population, currency, region, and subregion.
I have no clue how to connect them and I've tried messing with the input box id value, looking at search bar & REST Countries API tutorials, but I've figured out nothing. I added a search box to the page where I want ONLY the information to be displayed for testing and it works if I type in the exact country name and it is case sensitive.
How could I even connect these pages & search bar? And if it is possible, how could I make it suggest me countries after I type in one letter?
Main HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Dosis:wght#500&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/ae3cf15842.js" crossorigin="anonymous"></script>
<title>CountryProjectA</title>
</head>
<body>
<div>
<div class="search-box" >
<input class= "search-txt" type="text" id="search" placeholder="Search for a country" />
<a class="search-btn" href="">
<i class="fas fa-search-location fa-lg"></i>
</a>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
Country info display HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/info-style.css">
<title>Info</title>
</head>
<body>
<h1>Countries</h1>
<div id="main-container">
<div id="flag-container">
<img src="" alt="">
</div>
<div id="info-container">
<input name="" id="countries"></select>
<p>Capital: <span id="capital"></span></p>
<p>Population: <span id="population"></span></p>
<p>Currencies: <span id="currencies"></span></p>
<p>Region: <span id="region"></span></p>
<p>Subregion: <span id="subregion"></span></p>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
Main JS
const countriesList = document.getElementById("countries");
let countries;
countriesList.addEventListener("change", newCountrySelection);
function newCountrySelection(event) {
displayCountryInfo(event.target.value);
}
fetch("https://restcountries.eu/rest/v2/all")
.then(res => res.json())
.then(data => initialize(data))
.catch(err => console.log("Error:", err));
function initialize(countriesData) {
countries = countriesData;
let options = "";
countries.forEach(country => options+=`<option value="${country.alpha3Code}">${country.name}</option>`);
countriesList.innerHTML = options;
countriesList.selectedIndex = Math.floor(Math.random()*countriesList.length);
displayCountryInfo(countriesList[countriesList.selectedIndex].value);
}
function displayCountryInfo(countryByName) {
const countryData = countries.find(country => country.name === countryByName);
document.querySelector("#flag-container img").src = countryData.flag;
document.querySelector("#flag-container img").alt = `Flag of ${countryData.name}`;
document.getElementById("capital").innerHTML = countryData.capital;
document.getElementById("population").innerHTML = countryData.population.toLocaleString("en-US");
document.getElementById("currencies").innerHTML = countryData.currencies.filter(c => c.name).map(c => `${c.name} (${c.code})`).join(", ");
document.getElementById("region").innerHTML = countryData.region;
document.getElementById("subregion").innerHTML = countryData.subregion;
}
Thank you!
You should use this to get the input value in your Javascript code when someone clicks the search button.
document.getElementsByClassName("search-btn")[0].onclick = function() {
var searchInput = document.getElementById("search").value;
// call the search function here and redirect to the other page where you display results.
}
As for suggesting names, you can use the Google Places Autocomplete API for that: https://developers.google.com/places/web-service/autocomplete. Just call the API in the oninput event handler for #search.
Hope this helps!
Related
Trying to make a basic webpage where you can type a message for it to be displayed on the website. However, the script section of my website does not seem to work.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script>
document.addEventListener('DOMContentLoaded', function()
{
let submit = document.querySelector('#submit');
submit.addEventListener('click',function()
{
let questions = document.querySelectorAll('.question');
let input = document.querySelector('input');
for (let i =0; i< questions.length; i++)
{
if questions[i].innerHTML == ""
{
questions[i].innerHTML = 'a';
}
else
{
continue;
}
}
});
function myfunction()
{
alert('test');
}
});
</script>
<title>Write A Message!</title>
</head>
<body class="p-3 mb-2 bg-secondary text-white">
<h1>How to write a message</h1>
<hr>
<p>Type a Message into the textbox below to display a public letter!</p>
<div>
<input type = 'text'>
<button id = 'submit'>Type a message!</button>
</div>
<div>
<h1>Message 1!</h1>
<hr>
<p class = 'question'></p>
<h2>Message 2!</h2>
<hr>
<p class = 'question'></p>
<h3>Message 3!</h3>
<hr>
<p class = 'question'></p>
<button onclick = 'myfunction()'>test</button>
</div>
</body>
</html>
I tried adding a button that would display an alert as well but it does not run as well when clicked.
First, javscript that contains listener/reference to DOM elements is better to include in the end on body, avoid putting in head.
Second, myfunction() is not accessible bebcause you included it under DOMContentLoaded. It should be outside of the listener (global scope).
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Write A Message!</title>
</head>
<body class="p-3 mb-2 bg-secondary text-white">
<h1>How to write a message</h1>
<hr>
<p>Type a Message into the textbox below to display a public letter!</p>
<div>
<input type='text'>
<button id='submit'>Type a message!</button>
</div>
<div>
<h1>Message 1!</h1>
<hr>
<p class='question'></p>
<h2>Message 2!</h2>
<hr>
<p class='question'></p>
<h3>Message 3!</h3>
<hr>
<p class='question'></p>
<button onclick='myfunction()'>test</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', function(){
let submit = document.querySelector('#submit');
submit.addEventListener('click',function(){
let questions = document.querySelectorAll('.question');
let input = document.querySelector('input');
for (let i =0; i< questions.length; i++){
if (questions[i].innerHTML == ""){
questions[i].innerHTML = 'a';
} else {
continue;
}
}
});
});
function myfunction() {
alert('test');
}
</script>
</body>
</html>
This project is using the cocktail api to search for a specific ingredient (think gin or vodka) and then return all the drinks that contain the ingredient. I was able to get the results to display, but I wanted the thumbnail pic of the drink (included in the api as strDrinkThumb). When I try to get the pictures to display I get the follow error:
GET http://local/undefined 404 (Not Found)
window.addEventListener('DOMContentLoaded', (event) => {
console.log('DOM fully loaded and parsed');
});
let ingredients = document.getElementById('ingredients');
let searchTerm= document.getElementById('search-Bar');
let searchBtn = document.getElementById('searchBtn');
let drinkInfo = document.getElementById('drinkInfo');
let ingredientList = []
searchBtn.addEventListener("click", async (e) => {
const searchString = searchTerm.value.toLowerCase();
fetch(`https://www.thecocktaildb.com/api/json/v1/1/filter.php?i=${searchString}`)
.then((response) => response.json())
.then((filteredIngredients) => {
displayIngredient(filteredIngredients.drinks);
})
.catch((error) => {
});
});
function displayIngredient(drinkData){
const ingredients = [];
//maps over array and makes new array
drinkInfo.innerHTML = drinkData.map( ({strDrink}) => { //destructuring
//use backticks and html
return` <div> //use backticks and html
<div class="card" style="width: 14rem;">
<div class="card-body">
<h5 class="card-title">${strDrink} </h5>
<img src="${drinkData.strDrinkThumb}"/>
</div></div>
`; //use backticks and html
}).join('');
drinkInfo.appendChild(drinkInfo);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cocktail App</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<input type="text" id="search-Bar" placeholder="Enter main ingredient..."/>
<button id="searchBtn">search</button>
</header>
<div class="drinkInfo" id="drinkInfo">
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<script type="text/javascript" src="./extrafile.js"></script>
</body>
</html>
In drinkData.map function you are only pulling strDrink value from the object, you need also get strDrinkThumb
Then you are trying get strDrinkThumb from drinkData which is an array, not an object.
Try this:
drinkInfo.innerHTML = drinkData.map( ({strDrink, strDrinkThumb}) => { //destructuring
//use backticks and html
return` <div> //use backticks and html
<div class="card" style="width: 14rem;">
<div class="card-body">
<h5 class="card-title">${strDrink} </h5>
<img src="${strDrinkThumb}"/>
</div></div>
`; //use backticks and html
}).join('');
I'm working on a project where you ask the National Parks API for info of parks based on the state abbreviation you enter, as in OR(Oregon) or WA (Washington), etc. I understand how to write it for one value, using template literals, but if I search for more than one state at a time, that when writing the code gets tricky. Im looking to get it to send a call to the api like this:
https://developer.nps.gov/api/v1/parks?stateCode=or%2Cwa
I would be putting "or,wa" into my search box
(Documentation for National Parks API endpoint I'm using:
https://www.nps.gov/subjects/developer/api-documentation.htm#/parks/getPark)
JS:
'use strict'
$(watchForm());
function watchForm(){
$('form').submit(event => {
event.preventDefault();
getParkInfo();
})
}
function getParkInfo(){
var searchBox = $('.inputBox').val();
var numResults = $('.numPerPage').val();
const url = *** How do I write this???***
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response)
displayResults(response);
})
}
function displayResults(response){
$('#results-list').empty();
for(let i = 0; i < response.data.length; i++){
$('#results-list').append(
`<li>
<h3>${response.data[i].fullName}</h3>
<p>${response.data[i].description}</p>
<p>${response.data[i].addresses[i]}</p>
<a href="${response.data[i].directionsUrl}"<p>Address</p></a>
</li>`
)
}
$('#results').removeClass('hidden');
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Search Your Favorite National Parks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>NPS Search Up</h1>
<form>
<input class="inputBox" type="text" required> Search for Park
<br><br>
<input class="numPerPage" type="text" value="10" required> Results per page
<br><br>
<input class="submitBox" type="submit">
</form>
<section id="results" class="hidden">
<h2>Search Results</h2>
<ul id="results-list">
</ul>
</section>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<script src="script.js" async defer></script>
</body>
</html>
Create a new URL instance with your base url.
var url = new URL("https://developer.nps.gov/api/v1/parks");
and then add your query parameters to this URL instance like this
url.searchParams.append('stateCode', searchBox)
url.searchParams.append('limit', numResults);
var joinedSearchEntry = searchBox.split(',').join('%2C')
var url = `https://developer.nps.gov/api/v1/parks?stateCode=${joinedSearchEntry}`
or save a line
var url = `https://developer.nps.gov/api/v1/parks?stateCode=${searchBox.split(',').join('%2C')}`
Let me know if I'm missing something but this should be fine.
I'm working on a project where you ask the National Parks API for info of parks based on the state abbreviation you enter, as in OR(Oregon) or WA (Washington), etc. I understand how to write it for one value, using template literals, but if I search for more than one state at a time, that when writing the code gets tricky. Im looking to get it to send a call to the api like this:
https://developer.nps.gov/api/v1/parks?stateCode=or%2Cwa
I would be putting "or,wa" into my search box
(Documentation for National Parks API endpoint I'm using:
https://www.nps.gov/subjects/developer/api-documentation.htm#/parks/getPark)
JS:
'use strict'
$(watchForm());
function watchForm(){
$('form').submit(event => {
event.preventDefault();
getParkInfo();
})
}
function getParkInfo(){
var searchBox = $('.inputBox').val();
var numResults = $('.numPerPage').val();
const url = *** How do I write this???***
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response)
displayResults(response);
})
}
function displayResults(response){
$('#results-list').empty();
for(let i = 0; i < response.data.length; i++){
$('#results-list').append(
`<li>
<h3>${response.data[i].fullName}</h3>
<p>${response.data[i].description}</p>
<p>${response.data[i].addresses[i]}</p>
<a href="${response.data[i].directionsUrl}"<p>Address</p></a>
</li>`
)
}
$('#results').removeClass('hidden');
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Search Your Favorite National Parks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>NPS Search Up</h1>
<form>
<input class="inputBox" type="text" required> Search for Park
<br><br>
<input class="numPerPage" type="text" value="10" required> Results per page
<br><br>
<input class="submitBox" type="submit">
</form>
<section id="results" class="hidden">
<h2>Search Results</h2>
<ul id="results-list">
</ul>
</section>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<script src="script.js" async defer></script>
</body>
</html>
You can split the value by ",", then trim and join back together with "%2C":
document.getElementById("b").onclick = () => {
let sCodes = document.getElementById("p").value
console.log(sCodes.split(",").map(code => code.trim()).join("%2C"))
}
<input id="p" />
<button id="b">Create State Code Val</button>
No matter what I try I get NAN when I try to parse an input value into a variable. I am trying to make a calculator to determine fuel economy.
<!DOCTYPE html>
<html>
<head>
<title>Fuel Calculator</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="Demo project">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<style type="text/css"></style>
</head>
<body>
<div class="wrapper">
<h1>Fuel Usage</h1>
<div class="row">
<div class="col-md-12">
<form>
<div class="form-group">
<label>Miles Driven Per Year</label>
<input type="text" class="form-control" id="mpy">
</div>
<div class="form-group">
<label>MPG</label>
<input type="text" class="form-control" id="mpg">
</div>
<p>Gallons Used: <span id="used"></span</p>
<div class="form-group">
</div>
<button id="submit" type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="main.js" type="text/javascript"></script>
</body>
</html>
js file
var mpy = parseInt($('#mpy').val(), 10);
var mpg = parseInt($('#mpg').val(), 10);
var gallonsUsed = mpy/mpg;
$('#submit').click(function(){
$('#used').text(gallonsUsed);
});
Since you have the input fields declared globally, the initial value in the text value is empty. So the result of parseInt would give you a NAN value.
You need to calculate the parsed values once you invoke the click event.
$('#submit').click(function(e){
var mpy = parseInt($('#mpy').val(), 10);
var mpg = parseInt($('#mpg').val(), 10);
var gallonsUsed = mpy/mpg;
$('#used').text(gallonsUsed);
});
Working example : https://jsfiddle.net/DinoMyte/b9bhs4s3/
The way you have your code, mpy/mpg/gallonsUsed are all calculated when the page is loaded (before any user input can even take place)
Your code would make more sense like this
$('#submit').click(function(){
var mpy = parseInt($('#mpy').val(), 10);
var mpg = parseInt($('#mpg').val(), 10);
var gallonsUsed = mpy/mpg;
$('#used').text(gallonsUsed);
});
So that the calculation is done once user has entered data and hit submit