Map two objects and join together - javascript

I'm trying to join the data result from ajax to the const res.
So Ideally the list order would be
Attack 402983
Defense 1500
Strength 70
HitPoints 68
As you can see below, i'm having trouble appending the two together in a list fashion. An example of whats coming from ajax data is 402983,1500,70,68
HTML
<form class="form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text" name="search" placeholder="Search"/>
<button id="search-btn" class="btn btn-outline-success my-2 my-sm-0" type="submit">Search </button>
</form>
<ul id="response">
</ul>
JAVASCRIPT
// this is the id of the form
$('#search-btn').on('click', function(e) {
e.preventDefault();
var url = "?player=";
var player = $('input[name="search"]').val();
var urlAddition = url + player
$.ajax({
url: urlAddition,
dataType: "html",
success: function(data) {
const res = 'Attack, Defense, Strength, HitPoints';
const list = res.split(",");
const listdata = data.split(",");
const secondlists = listdata.map(item => + item);
$('ul#response').html(list.map(item => '<li>' + item + secondlists + '</li>').join(''));
}
});
});

You can use the second param from the handler which is the index.
$('ul#response').html(list.map((item, i) => '<li>' + `${item} ${listdata[i]}` + '</li>').join(''));
^ ^
As you can see, this approach uses the array listdata directly.

Related

how to get and render selected values related data from array in jquery?

I have no expertise in javascript but I want to render this data which is showing in my console.log below
How can I make forloop or something like that to render this data in my html input?
create.html
<div class="col-sm-2">
<div class="form-group">
<label>Expected Values</label>
<input type="text" class="form-control" value="{{vital.expected_values}}" readonly>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Price</label>
<input type="text" class="form-control" value="{{vital.price}}" readonly>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#id_vitals").change(function () {
var vitals = $(this).val();
$.ajax({
url: $('#personForm').data('url'),
data: { 'vital_id': vitals },
success: function (response) {
console.log(response[vitals['name']])
}
});
});
})
</script>
I would do it somehow like that:
// Your data
let dataArray = [{data: 1, otherData: 2, elseData: 3}]
// The element, where you want to show it
let targetElement = document.getElementById('your-targer-id');
// The container element for elements
let newContainer = document.createElement('ul');
// Pure JS loop, easy to understand what is happening
// But you can also do it with .map();
for (let i = 0; i < dataArray.length; i++) {
// Add every line
newContainer.innerHTML+='<li>' + dataArray[i].data + '</li>';
// Or other things, depending how you want to show the data
newContainer.innerHTML+='<li> data value is: ' + dataArray[i].data + ' and otherData value is: ' + dataArray[i].otherData + '</li>'; //etc
}
// Append created list in target element
targetElement.appendChild(newContainer);
EDIT - now I see, that you want to display multiple values in text input, rather like so:
let dataArray = [...your-data-array]
let targetElement = document.getElementById('target-input');
for (let i = 0; i < dataArray.lenght; i++) {
// loop throug elements and add it to value attribute of input, separated by coma.
targetElement.value+=dataArray[i].expected_values + ', ';
}

Jquery - On click change append parameter only once

With present code, data-endpoint path changing as
data.15435.json?parameter=test
data.13588.json?parameter=test?parameter=test
data.15435.json?parameter=test?parameter=test?parameter=test
On each change, parameter is appending. But, need to include this parameter only once.
$('a.dropdown-item').on('click', function(){
let getDataKey = $(this).attr('data-key');
let getEndPoint = $('.detail.component').attr('data-endpoint');
var getEndPointVal = getEndPoint.replace(/[.0-9]*\.json/, '.' + getDataKey + '.json');
var getEndPointValParam = getEndPointVal + '?parameter=test';
var getJsonUrl = $('.detail.component').attr('data-endpoint', getEndPointValParam);
let getNewDataKey = getJsonUrl;
console.log(getJsonUrl)
}
<div class="detail component" data-endpoint="detail.json">
..
</div>
<div class="dropdown start-date">
<button id="startdate" type="button" class="btn btn-outline-dark">List 1</button>
<div class="dropdown-menu">
<a type="button" data-key="15435" class="dropdown-item">List 1</a>
<a type="button" data-key="13588" class="dropdown-item">List 2</a>
</div>
</div>
The only way how i can see, is to set the data-endpoint to be a permanent or constant. Try this:
let getEndPoint = $('.detail.component').attr('data-endpoint');
$('a.dropdown-item').on('click', function(e){
e.preventDefault();
let getDataKey = $(this).data('key');
var array = getEndPoint.split('.'); //now it is an array
var getEndPointVal = array[0] + '.' + getDataKey + '.' + array[1];
var getEndPointValParam = getEndPointVal + '?parameter=test';
$('.detail.component').data('endpoint', getEndPointValParam);
var getJsonUrl = $('.detail.component').data('endpoint');
console.log(getJsonUrl);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="detail component" data-endpoint="detail.json">
</div>
List 1
List 2

onclick with two function calls takes two clicks to run both functions js

This is probably going to be marked as a duplicate because there are so many SO questions about this already, but I'm just unable to apply those questions answers onto my code.
I am using Razor, html, css, and javascript in my Blob storage page code.
On the left side in the image below there are three containers. When clicking on one of them they are to open up and show all their children (blobs). The first time I click one of the containers only one of the function calls run (listContainerBlobs()) and it is not the one opening the container up (showHide()).
Below is the html p-tag calling the functions onclick.
<p class="blob-container" onclick="showHide('#containerId', '#arrowId');listContainerBlobs('#jsonBlob', '#container.Name');"><i class="fa fa-caret-right" id="#arrowId"></i> #container.Name</p>
The full div with C# and razor:
<aside class="aside">
<div class="aside-header">
<i class="fa fa-plus add-container-button aside-header-icons" onclick="addContainer()"></i><i class="fa fa-search search-button aside-header-icons"></i>
<input id="searchBox" type="text" onkeyup="search()" name="search" placeholder="Search blobs..." />
</div>
<div class="aside-containers">
#foreach (var container in containers)
{
caretArrowNumber++;
string arrowId = "arrowId-" + caretArrowNumber;
containerNumber++;
string containerId = "containerId-" + containerNumber;
var blobs = await Model.ListContainerBlobs(container.Name);
//var jsonBlob = Json.Serialize(blobs);
List<object> blobObject = new List<object>();
blobObject.Add(new
{
blobCount = blobs.Count,
blobs = blobs.Select(x => new
{
Name = x.Name,
Container = container.Name,
Blobtype = x.BlobType,
Uri = x.Uri
})
});
var jsonBlob = JsonConvert.SerializeObject(blobObject);
<div class="arrow-blob-container">
<p class="blob-container" onclick="showHide('#containerId', '#arrowId');listContainerBlobs('#jsonBlob', '#container.Name');"><i class="fa fa-caret-right" id="#arrowId"></i> #container.Name</p>
</div>
<div class="showBlob" id="#containerId">
<div class="ml-4">
#foreach (var blob in blobs)
{
blobNumber++;
string blobId = "blobId-" + blobNumber;
<div>
<input class="blobs" id="#blobId" type="button" value="#blob.Name" onclick="downloadBlob('#blobId', '#blob.Name', '#blob.Container.Name')" />
</div>
}
</div>
</div>
}
</div>
</aside>
The following code is the two functions being called on onclick:
<script>
function listContainerBlobs(json, container) {
console.log("beginning");
console.log(json);
var arr = JSON.parse(json);
console.log(arr);
var blobs = document.getElementById('container-blob-display').innerHTML = "<h4>" + container + "</h4>";
var otherDiv = document.getElementById('section-1');
var thisDiv = document.getElementById('section-2');
otherDiv.style.display = 'none';
thisDiv.style.display = 'inline';
var blobNumber = 0;
for (i = 0; i < arr.length; i++){
blobNumber++;
var blobId = "blobId" + blobNumber;
blobs += "<p class='search-result' id='" + blobId + "' onclick='downloadBlob('" + blobId + "', '" + arr[i].Name + "', '" + container + "')'>" + arr[i].Name + "</p>";
}
console.log(blobs);
}
function showHide(containerId, arrowId) {
var c = document.getElementById(containerId);
var a = document.getElementById(arrowId);
if (c.style.display === "none") {
c.style.display = "inline";
a.className = "fa fa-caret-down";
} else {
c.style.display = "none";
a.className = "fa fa-caret-right";
}
}
</script>
I have tried
commenting out the ListContainerBlobs()-function
commenting out all the css
changed from style.display = "block" to "inline" (seen in the example code)
moved the whole script section to the top of the html
commented out almost all code in the html except the most necessary
But showHide() still wouldn't run on the first click.
So currently, on the first click the listContainerBlobs() run and on the second click the showHide() runs, but I would prefer if both of them ran on the first onclick.
I appreciate all the help I can get! Thanks in advance!
P.S I'd love to do a jsfiddle but it doesn't seem to understand C# and List<> (thinking <> is a tag)
Edit from Mr. Smiths solution
It still takes two clicks for me to run both functions with this solution from Mr. Smith:
HTML:
<div class="arrow-blob-container">
<p class="blob-container aside-content" id="#newContId" data-containerId="#containerId" data-arrowId="#arrowId" data-jsonBlob="#jsonBlob" data-containerName="#container.Name"><i class="fa fa-caret-right" id="#arrowId"></i> #container.Name</p>
</div>
Js:
document.querySelectorAll('.aside-content').forEach(element => {
element.addEventListener('click', function (e) {
let ds = this.dataset;
showHide(ds.containerid, ds.arrowid);
listContainerBlobs(ds.jsonblob, ds.containername);
})
});
This works all the way with the right ids and other values, but like I said, I still need to click two timesto get both functions to be called. First click runs listContainerBlobs(), second click showHide().
Any ideas of why that might be?
You can create an event listener which calls your functions:
<div class="arrow-blob-container">
<p class="blob-container" data-container-id="#containerId" data-arrow-id="#arrowId" data-json-blob="#jsonBlob" data-container-name="#container.Name" ><i class="fa fa-caret-right" id="#arrowId"></i> #container.Name</p>
</div>
Script:
<script>
document.querySelectorAll('.blob-container').forEach(element => {
element.addEventListener('click', function(e) {
let dataset = e.currentTarget.dataset;
showHide(dataset.containerId, dataset.arrowId);
listContainerBlobs(dataset.jsonBlob, dataset.containerName);
});
});
</script>
Check this snippet:
document.querySelectorAll('.blob-container').forEach(element => {
element.addEventListener('click', function(e) {
let dataset = e.currentTarget.dataset;
console.log("containerId: " + dataset.containerId);
console.log("arrowId: " + dataset.arrowId);
console.log("jsonBlob: " + dataset.jsonBlob);
console.log("containerName: " + dataset.containerName);
});
});
<div class="arrow-blob-container">
<button class="blob-container" data-container-id="container1" data-arrow-id="arrow1" data-json-blob="{...}" data-container-name="Button1">Display dataset</button>
<button class="blob-container" data-container-id="container2" data-arrow-id="arrow2" data-json-blob="{...}" data-container-name="Button2">Display dataset</button>
<button class="blob-container" data-container-id="container3" data-arrow-id="arrow3" data-json-blob="{...}" data-container-name="Button3">Display dataset</button>
<button class="blob-container" data-container-id="container4" data-arrow-id="arrow4" data-json-blob="{...}" data-container-name="Button4">Display dataset</button>
</div>
This also works without querySelector which might be clearer:
function onButtonClick(e) {
let dataset = e.dataset;
console.log("containerId: " + dataset.containerId);
console.log("arrowId: " + dataset.arrowId);
console.log("jsonBlob: " + dataset.jsonBlob);
console.log("containerName: " + dataset.containerName);
}
<div class="arrow-blob-container">
<button class="blob-container" onClick="onButtonClick(this)" data-container-id="container1" data-arrow-id="arrow1" data-json-blob="{...}" data-container-name="Button1">Display dataset</button>
<button class="blob-container" onClick="onButtonClick(this)" data-container-id="container2" data-arrow-id="arrow2" data-json-blob="{...}" data-container-name="Button2">Display dataset</button>
<button class="blob-container" onClick="onButtonClick(this)" data-container-id="container3" data-arrow-id="arrow3" data-json-blob="{...}" data-container-name="Button3">Display dataset</button>
<button class="blob-container" onClick="onButtonClick(this)" data-container-id="container4" data-arrow-id="arrow4" data-json-blob="{...}" data-container-name="Button4">Display dataset</button>
</div>

How to fix Form action with method get

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.

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;
}
}

Categories

Resources