How to fix Form action with method get - javascript

I have a small issues with my code.
Basically, I have a form in my index.html file:
The form from page 1 is the following:
<form method="get" name="basicSearch" id = "basicSearch" action="page2.html">
<input name="location" type="text" class="BasicSearch" id="searchInput" placeholder="Location">
<button type= "submit" class="BasicSearch" id="searchBtn" placeholder="Search"></button>
</form>
For this form, I want to use OpenWeatherMap API in order to get some weather data. My problem is the following:
I want to get what the user inputs in the form, which I think I can get by using, for example:
var searchInput = document.getElementById("searchInput");
In this variable I can store the location.
And this variable, I want to append to the link that does fetch the data from the API, in the javascript code.
When the user inputs, for example: New York, and press Search, the form action should redirect him to page2.html, where there I can show the weather data.
How can I show that weather data in the page2, with the location input from page1? I tried many times but no luck.
Some Javascript code down below:
let units = 'metric';
let searchMethod = 'q';
let searchButton = document.getElementById("searchBtn");
let searchInput = document.getElementById("searchInput");
if (searchButton) {
searchButton.addEventListener('click', () => {
let searchTerm = searchInput.value;
if (searchTerm)
searchWeather(searchTerm);
});
}
function searchWeather(searchTerm) {
fetch(`http://api.openweathermap.org/data/2.5/weather?${searchMethod}=${searchTerm}&APPID=${appId}&units=${units}`).then(result => {
return result.json();
}).then(result => {
init(result);
})
}
function init(resultFromServer){
let weatherDescriptionHeader = document.getElementById('weatherDescriptionHeader');
let temperatureElement = document.getElementById('temperature');
let humidityElement = document.getElementById('humidity');
let windSpeedElement = document.getElementById('windSpeed');
let cityHeader = document.getElementById('cityHeader');
let weatherIcon = document.getElementById('documentIconImg');
weatherIcon.src = 'http://openweathermap.org/img/w/' + resultFromServer.weather[0].icon + '.png';
let resultDescription = resultFromServer.weather[0].description;
weatherDescriptionHeader.innerText = resultDescription.charAt(0).toUpperCase() + resultDescription.slice(1);
temperatureElement.innerHTML = Math.floor(resultFromServer.main.temp) + '&#176' + " C";
windSpeedElement.innerHTML = 'Winds at ' + Math.floor(resultFromServer.wind.speed) + ' mph';
cityHeader.innerHTML = resultFromServer.name;
humidityElement.innerHTML = 'Humidity levels at ' + resultFromServer.main.humidity + '%';
}
That is some javascript code which should get the weather data.
Then, in page2, I have the following in HTML:
<div id = "weatherContainer">
<div id = "weatherDescription">
<h1 id = "cityHeader"></h1>
<div id= "weatherMain">
<div id = "temperature"></div>
<div id = "weatherDescriptionHeader"></div>
<div><img id = "documentIconImg"></div>
</div>
<hr>
<div id = "windSpeed" class = "bottom-details"></div>
<div id = "humidity" class = "bottom-details">></div>
</div>
</div>
I expected to have the weather data in page2, where the divs are.
Can somebody give me an advice, please?
Thank you!

Since the form in page1 doesn't exist in page 2, remove
let searchButton = document.getElementById("searchBtn");
let searchInput = document.getElementById("searchInput");
if (searchButton) {
searchButton.addEventListener('click', () => {
let searchTerm = searchInput.value;
if (searchTerm)
searchWeather(searchTerm);
});
}
instead put
ley searchTerm = new URLSearchParams(location.search).get('location');
searchWeather(searchTerm);
Explanation
When the page 1 form is submitted, it will load page2 like
page2.html?location=xxxx
where xxxx is the value of the <input name='location' ...
location.search will be ?location=xxxx
URLSearchParams makes dealing with these (when you have more than one especially) easier than the old method of splitting/decoding/jumping through hoops

We can simply just submit the form and get the current form input from url on page2.html
<form method="get" name="basicSearch" id = "basicSearch" action="page2.html">
<input name="location" type="text" class="BasicSearch" id="searchInput" placeholder="Location">
<button type= "submit" class="BasicSearch" id="searchBtn" placeholder="Search">Search</button>
</form>
And on the load of page2.html (before your ajax call), we can get the 'searchInput' (location) from URL by following:
<script>
let params = (new URL(document.location)).searchParams;
var searchInput= params.get('location');
</script>
Now, we can use 'searchInput' param for your api call and fetch the result.

Related

How to avoid values from an object after inserting from an input form to be inserted repeatedly?

I am inserting the values of an input into an array of objects. Then, I want to get those values e show inside the HTML. Inserting each value inside the object is not the problem, every time I click the button, each value is successfully added. When I console.log() the array, it shows only one of each value added. The problem is when I try to show the content of the object inside the HTML element, it inserts all the data from the object over and over again, but I just want to add the last value added and keep what was previously inserted, not to add everything again.
What am I doing wrong?
This is my HTML
<main>
<div class="add-recipes">
<form id="form">
<h2>Add Recipe</h2>
<div class="input-wrapper">
<div class="text-input-wrapper">
<label for="title"
>Title
<input type="text" name="title" id="recipe-title" />
</label>
</div>
</div>
<button id="send-recipe-btn" type="submit">Send Recipe</button>
</form>
</div>
<div class="recipes-container"></div>
</main>
This is my JS File
let recipes = [];
const addRecipe = e => {
e.preventDefault();
let recipe = {
title: document.getElementById('recipe-title').value
};
recipes.push(recipe);
document.querySelector('form').reset();
recipes.forEach(e => {
const recipeContainer = document.querySelector('.recipes-container');
const recipeTitle = document.createElement('div');
recipeTitle.classList.add('recipe-title');
recipeContainer.append(recipeTitle);
recipeTitle.textContent = e.title;
});
console.log(recipes);
};
document.getElementById('send-recipe-btn').addEventListener('click', addRecipe);
Thanks for any tip or help to solve this.
Have the forEach()loop to start before recipeTitle.textContent = e.title;
let recipes = [];
const addRecipe = e => {
e.preventDefault();
let recipe = {
title: document.getElementById('recipe-title').value
};
recipes.push(recipe);
document.querySelector('form').reset();
const recipeContainer = document.querySelector('.recipes-container');
const recipeTitle = document.createElement('div');
recipeTitle.classList.add('recipe-title');
recipeContainer.append(recipeTitle);
recipes.forEach(e => {
recipeTitle.textContent = e.title;
});
console.log(recipes);
};
document.getElementById('send-recipe-btn').addEventListener('click', addRecipe);
In your event handler, you are looping over the recipes array and creating a new element every single time the button is pressed.
Just remove the loop and it will work properly

click event listener method is not working on a specific div

I am trying to add an event listener to my "degree section div" but it is not working nor am I getting any errors. I have tried multiple ways of traversing the DOM to reach the "degree-section" div but to no avail.
Any kind of help is welcome and appreciated
Code:
let city = document.querySelector('#city');
let searchbtn = document.querySelector('.search-btn');
let city_name = document.querySelector('.city-name');
let temp = document.querySelector('.temp');
let feels_like = document.querySelector('.feels-like');
let humidity = document.querySelector('.humidity');
let locationIcon = document.querySelector('.weather-icon');
let checkbox = document.getElementById('celcius');
let weather_sec = document.querySelector('.weather-info');
let degree_section = weather_sec.firstElementChild;
let degree_section_span = degree_section.getElementsByTagName('span')[0];
//let wind = document.querySelector('.wind');
async function getUrl(city) {
try {
let theUrl = url + city + '&appid=' + apiKey;
let response = await fetch(theUrl, {
mode: 'cors'
})
let data = await response.json();
//Get data from api and change html content based on the recieved data
let temp_data = data.main.temp
temp.textContent = temp_data;
let feels_like_data = data.main.feels_like;
feels_like.textContent = feels_like_data + "K";
let humidity_data = data.main.humidity;
humidity.textContent = humidity_data;
let {
icon
} = data.weather[0];
locationIcon.innerHTML = `<img src="icons/${icon}.png">`;
//change K to C
degree_section.addEventListener('click', () => {
//logging a message just to check if it is working
console.log("c")
})
} catch (err) {
let error = document.createElement('span')
error.className = "error";
error.textContent = "Location does not exist"
let top_center_div = document.querySelector('.top-center')
top_center_div.appendChild(error)
city_name.textContent = "No city found"
}
}
searchbtn.addEventListener('click', (e) => {
let cityName = city.value;
city_name.textContent = cityName
console.log(cityName)
getUrl(cityName)
})
<body>
<div class="loc-container">
<div class="location">
<h1 class="city-name">City</h1>
<div class="weather-icon"><img src="icons/unknown.png" /></div>
</div>
</div>
<div class="weather-info">
<div class="degree-section">
<h2 class="temp">0.0</h2>
<span>K</span>
</div>
<div class="info-section">
<div class="info-flex">
<h3 class="feels-like">0K</h3>
<h4>Feels Like</h4>
</div>
<div class="info-flex">
<h3 class="humidity">0</h3>
<h4>Humidity</h4>
</div>
<div class="info-flex">
<h3 class="wind">0</h3>
<h4>Wind</h4>
</div>
</div>
</div>
<div class="top-center">
<div class="form">
<input type="text" name="city" id="city" required>
<label for="city" class="label-name"><span class="search-name">Search City...</span></label>
</div>
<!-- <i class="fas fa-search search-btn"></i> -->
<i class="material-icons search-btn" style="font-size: 35px;">search</i>
</div>
<script src="weather.js"></script>
</body>
This is what "data" looks like
{"coord":{"lon":72.8479,"lat":19.0144},"weather":[{"id":711,"main":"Smoke","description":"smoke","icon":"50d"}],"base":"stations","main":{"temp":303.14,"feels_like":303.45,"temp_min":301.09,"temp_max":303.14,"pressure":1014,"humidity":45},"visibility":2500,"wind":{"speed":3.09,"deg":120},"clouds":{"all":20},"dt":1638773692,"sys":{"type":1,"id":9052,"country":"IN","sunrise":1638754125,"sunset":1638793848},"timezone":19800,"id":1275339,"name":"Mumbai","cod":200}
Thank you in advance!
I believe the problem is with
let degree_section_span = degree_section.getElementsByTagName('span')[0];
since it selects the wrong element. Try changing it to
let degree_section_span = weather_sec.querySelector('.check');
and see if it works. You can also change the variable name to something more appropriate, while you're at it.
EDIT:
I think this is what you're trying to do. For the sake of siplicity , I removed everything not related to temp:
let target = weather_sec.querySelector("div.check"),
temp_data = data.main.temp;
temp.textContent = temp_data;
target.addEventListener('click', () => {
cel = parseInt(temp_data) - 273.15;
temp.textContent = cel.toFixed(2);
temp.nextElementSibling.textContent = "C";
});
So after 48hrs of debugging I finally figured out what is wrong. If you see in my HTML I have a div.top-center at the bottom. And due to some dimension issues in my css file the height of div.top-center spanned the entire page so essentially all of my divs were being wrapped inside div.top-center so even if I assigned a click event to my div.degree-section the target was always div.top-center and that is why the click event was not showing the proper output.

javascript issue calling function after adding event listener

I am working on a wikipedia viewer (https://codepen.io/rwiens/pen/YLMwBa) which is almost done but I have 2 problems:
I cannot submit my search results when I press enter. I have added an event listener and can console.log "hello: but I cannot call the searchWiki function.
When I do a new search the results are appended to the bottom pf my old results.
I've searched the web for the last half day and am stuck. Any help would be appreciated.
<div class="container">
<div class="banner text-center align-items">
<h1>Wiki Search</h1>
<p>Search for articles on Wikipedia</p>
</div>
<form action="" class="text-center">
<input type="search" id="search-box" placeholder="Search Here">
<div class="buttons">
<input type="button" onclick="searchWiki()" id="search-
button" value="Search">
<input type="submit" value="Feel Lucky?">
</div>
</form>
<div class="articles">
<ul id="results">
</ul>
</div>
</div>
<script type="test/javascript">
const searchBox = document.getElementById('search-box');
const sButton = document.getElementById('search-button');
const results = document.getElementById('results');
window.onload = function() {
searchBox.focus();
};
const searchWiki = () => {
const keyword = searchBox.value;
fetch("https://en.wikipedia.org/w/api.php?
&origin=*&action=opensearch&search=" + keyword + "&limit=5", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ query: event.currentTarget.value })
})
.then(response => response.json())
.then((data) => {
console.log(data);
build(data);
});
}
const build = (data) => {
let title = data[1];
let description = data[2];
let url = data[3];
for(let x = 0; x < 5; x++){
console.log(title);
const item = `<a href="${url[x]}" target="#">
<li>
<h5>${title[x]}</h5>
<p>${description[x]}.</p>
</li>
</a>`;
results.insertAdjacentHTML("beforeend", item);
}
}
searchBox.addEventListener("keyup", function(event) {
if (event.key === "Enter") {
searchWiki;
}
});
</script>
You are not calling searchWiki as function. Call it like this searchWiki();
Also you need to remove the form tag. Because you have button type elements in it , it is by default submitting your form on enter press.
Also clear results div before appending new data like this
results.innerHTML = ""
for(let x = 0; x < 5; x++){
console.log(title);
const item = `<a href="${url[x]}" target="#">
<li>
<h5>${title[x]}</h5>
<p>${description[x]}.</p>
</li>
</a>`;
results.insertAdjacentHTML("beforeend", item);
}
Check updated codepen
when I put searchWiki I am still not calling the search unfortunately. also, when i add results.innerHTML = "" my search only comes back with one result.
You need to add an event listener for the form submit. In that you need to cancel the event ( event.preventDefault() ).
Empty your results as #NanditaAroraSharma pointed out (best before calling build function)
Solved it. Removed the form as it was trying to send me to another page.
<div class="text-center">
<input type="search" id="search-box" placeholder="Search Here">
<div class="buttons">
<input type="button" onclick="searchWiki()" id="search-
button" value="Search">
<input type="button"
onclick="location.href='https://en.wikipedia.org/wiki/Special:Random';"
value="Feel Lucky?">
</div>
for building the html i took part of it out of the for loop.
const build = (data) => {
let title = data[1];
let description = data[2];
let url = data[3];
results.innerHTML = "";
for(let x = 0; x < 5; x++){
console.log(title);
const item = `<a href="${url[x]}" target="#">
<li>
<h5>${title[x]}</h5>
<p>${description[x]}.</p>
</li>
</a>`;
results.innerHTML += item;
}
}

Append localstorage data to the body element on All session (Works also with reload)

I have some code from input, and I wanna to save it to some body element.
I can add it to the body, but it disappear when page is reloaded
function store(){
var nameOfbook = document.getElementById("nameOfbook");
var value = localStorage.setItem("nameOfbook", nameOfbook.value);
var storedValueBockName = localStorage.getItem("nameOfbook");
var par = document.createElement('P');
par.innerText = storedValueBockName;
document.body.appendChild(par);
}
<form action="\" class="form-login" method="post" />
<input name="text" type="text" id="nameOfbook" required="" placeholder="Book name" />
<button onclick="store()" type="button">StoreText</button>
</form>
This question is basically asking how to retrieve a stored value from localStorage.
So you're setting the value in localStorage, but when you reload the page, you need to have a script that checks to see if there's a value in localStorage and add that data to your page if it is found there.
I would suggest something like:
<script>
var setText = function(text) {
var par = document.createElement('P');
par.innerText = text;
document.body.appendChild(par);
}
var checkLocalStorage = function() {
var value = localStorage.getItem("nameOfbook")
if (value) {
setText(value)
}
}
checkLocalStorage()
function store(){
var nameOfbook = document.getElementById("nameOfbook");
var value = localStorage.setItem("nameOfbook", nameOfbook.value);
var storedValueBockName = localStorage.getItem("nameOfbook");
setText(storedValueBockName)
}
</script>
So I moved the code that appends the title to the page into its own function so that it can be used by both store() and checkLocalStorage(). checkLocalStorage looks to see if there's a value set for nameOfbook and, if there is, passes that value to setText.
Should do the trick.

Trigger a html button inside a web browser control

in my web browser control i am accessing a form:
<form role="form">
<div class="form-group">
<input type="text" class="form-control" id="InputEmail1" placeholder="name...">
</div>
<div class="form-group">
<input type="email" class="form-control" id="InputPassword1" placeholder="email...">
</div>
<div class="form-group">
<textarea class="form-control" rows="8" placeholder="message..."></textarea>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
How can i trigger this button automatically from vb.net application? how can i set text to the text area? am accessing the text box as follows:
WebBrowser1.Document.GetElementById("InputEmail1").SetAttribute("value", "Sample")
WebBrowser1.Document.GetElementById("InputPassword1").SetAttribute("value", "Sample")
i cannot access button and text area since it does not have an id or name? is their any possibility to do like this?
Your elements need to have IDs and if you doesn't have access to the html code you can enumerate elements like this but you must know which element is the right one:
foreach (HtmlElement element in WebBrowser1.Document.Forms[0].All)
{
if (element.TagName.ToLower() == "textarea".ToLower())
{
element.InnerText = "text";
}
}
for clicking a button try this:
element.InvokeMember("click");
In a lot of web automation, unless you can get the original devs to add ids, you have to navigate the DOM in order to find what you need.
Here is an example of doing that kind of filtering and web automation
var actionPanel = topPanel.insert_Above(40);
var ie = topPanel.add_IE_with_NavigationBar().silent(true);
var server = "http://127.0.0.1.:8080";
Action<string,string> login =
(username, password) => {
ie.open(server + "/jpetstore/shop/signonForm.do");
ie.field("username",username);
ie.field("password",password);
ie.buttons()[1].click();
};
Action loginPlaceAnOrderAndGoToCheckout =
()=>{
ie.open("http://127.0.0.1:8080/jpetstore");
ie.link("Enter the Store").click();
//login if needed
var signOffLink = ie.links().where((link)=> link.url().contains("signonForm.do")).first();
if(signOffLink.notNull())
{
signOffLink.click();
login("j2ee", "pwd1");
}
ie.links().where((link)=> link.url().contains("FISH"))[0].click();
ie.link("FI-FW-01 ").flash().click();
ie.links().where((link)=> link.url().contains("addItemToCart"))[0].flash().click();
ie.links().where((link)=> link.url().contains("checkout.do"))[0].flash().click();
ie.links().where((link)=> link.url().contains("newOrder.do"))[0].flash().click();
};
Action scrollToTotal =
()=>{
var tdElement = ie.elements().elements("TD").toList().Where((element)=> element.innerHtml().notNull() && element.innerHtml().contains("Total:")).first();
tdElement.scrollIntoView();
tdElement.injectHtml_beforeEnd("<h2><p align=right>Look at the Total value from the table above (it should be 18.50)</p><h2>");
};
Action<string> exploit_Variation_1 =
(payload) => {
loginPlaceAnOrderAndGoToCheckout();
ie.buttons()[1].flash().click();
ie.open(server + "/jpetstore/shop/newOrder.do?_finish=true&" + payload);
scrollToTotal();
};
Action<string> exploit_Variation_1_SetTotalPrice =
(totalPrice) => {
var payload = "&order.totalPrice={0}".format(totalPrice);
exploit_Variation_1(payload);
};
Another option (which I also use quite a lot) is to actually use Javascript to do those actions (which is much easier if jQuery is available (or injected) in the target page).
[Test] public void Issue_681__Navigating_libraries_views_folders__Clicking_the_icon_doesnt_work()
{
var tmWebServices = new TM_WebServices();
Func<string, string> clickOnNodeUsingJQuerySelector =
(jQuerySelector)=>
{
ie.invokeEval("TM.Gui.selectedGuidanceTitle=undefined");
ie.invokeEval("$('#{0}').click()".format(jQuerySelector));
ie.waitForJsVariable("TM.Gui.selectedGuidanceTitle");
return ie.getJsObject<string>("TM.Gui.selectedGuidanceTitle");
};
if (tmProxy.libraries().notEmpty())
{
"Ensuring the the only library that is there is the TM Documentation".info();
foreach(var library in tmProxy.libraries())
if(library.Caption != "TM Documentation")
{
"deleting library: {0}".debug(library.Caption);
tmProxy.library_Delete(library.Caption);
}
}
UserRole.Admin.assert();
tmProxy.library_Install_Lib_Docs();
tmProxy.cache_Reload__Data();
tmProxy.show_ContentToAnonymousUsers(true);
ieTeamMentor.page_Home();
//tmWebServices.script_Me_WaitForClose();;
//ieTeamMentor.script_IE_WaitForComplete();
ie.waitForJsVariable("TM.Gui.selectedGuidanceTitle");
var _jsTree = tmWebServices.JsTreeWithFolders();
var viewNodes = _jsTree.data[0].children; // hard coding to the first library
var view1_Id = viewNodes[0].attr.id;
var view5_Id = viewNodes[4].attr.id;
var click_View_1_Using_A = clickOnNodeUsingJQuerySelector(view1_Id + " a" );
var click_View_5_Using_A = clickOnNodeUsingJQuerySelector(view5_Id + " a" );
var click_View_1_Using_Icon = clickOnNodeUsingJQuerySelector(view1_Id + " ins" );
var click_View_5_Using_Icon = clickOnNodeUsingJQuerySelector(view5_Id + " ins" );
(click_View_1_Using_A != click_View_5_Using_A ).assert_True();
(click_View_5_Using_A == click_View_1_Using_Icon).assert_False(); // (Issue 681) this was true since the view was not updating
(click_View_5_Using_A == click_View_5_Using_Icon).assert_True();
}

Categories

Resources