i'm trying to make auto complete with pure javascript.
Scenario is when type to input some letters it will search movies from omdbapi.
I make it like that:
i have input which users can search movies, i have get data from input value:
<input type="text" class="form-control" id="searchMovie" value="">
and here i get movies and make html markup with javascript for show these results in html:
var searchInput = document.getElementById("searchMovie");
// get movie
searchInput.onkeydown = function() {
var searchData = document.getElementById("searchMovie").value;
if (searchData.length >= 3 ) {
var request = new XMLHttpRequest();
request.open('GET', 'http://www.omdbapi.com/?s=' + searchData + '&apikey=000000', true);
request.onload = function () {
// Begin accessing JSON data here
var data = JSON.parse(this.response);
const wrapper = document.createElement('div');
app.appendChild(wrapper);
var results = data;
if (request.status >= 200 && request.status < 400) {
console.log(data);
Object.keys(data.Search).map(function(key, index) {
console.log(data.Search[index].Title);
const searchResultsContainer = document.createElement('div');
searchResultsContainer.setAttribute('class', 'row');
const h1 = document.createElement('h1');
h1.textContent = data.Search[index].Title;
wrapper.appendChild(searchResultsContainer);
searchResultsContainer.appendChild(h1);
console.log(searchResultsContainer);
});
} else {
console.log('error');
}
};
request.send();
}
};
everything work well but problem is:
when i try to delete keyword which i wrote and write new one results not disappear from html, i want change
You need to capture the change in the text input. Adding your code to a function and binding the input to oninput function. When there is a change in the value of the input it will rerun the api call. Furthermore, you need to clear out the old result.
<input type="text" class="form-control" id="searchMovie" value="" oninput"apiCall()">
<script>
function apiCall(){
var searchInput = document.getElementById("searchMovie");
// get movie
searchInput.onkeydown = function() {
var searchData = document.getElementById("searchMovie").value;
if (searchData.length >= 3 ) {
while (document.getElementsByClassName('autoComplete')[0]) {
document.getElementsByClassName('autoComplete')[0].remove();
}
var request = new XMLHttpRequest();
request.open('GET', 'http://www.omdbapi.com/?s=' + searchData + '&apikey=000000', true);
request.onload = function () {
// Begin accessing JSON data here
var data = JSON.parse(this.response);
var wrapper = document.createElement('div');
wrapper.className = "autoComplete";
app.appendChild(wrapper);
var results = data;
if (request.status >= 200 && request.status < 400) {
console.log(data);
Object.keys(data.Search).map(function(key, index) {
console.log(data.Search[index].Title);
const searchResultsContainer = document.createElement('div');
searchResultsContainer.setAttribute('class', 'row');
const h1 = document.createElement('h1');
h1.textContent = data.Search[index].Title;
wrapper.appendChild(searchResultsContainer);
searchResultsContainer.appendChild(h1);
console.log(searchResultsContainer);
});
} else {
console.log('error');
}
};
request.send();
}
}
</script>
That should remove the wrapper element you added and its children and populate a new one with new data. I can't really test this to make sure it works as I can not see the rest of your code. But it should work. if not I can help you to figure out any errors.
Also, I would consider making wrapper just a hidden div that you can easily clear and unhide when needed. It would be much easier and you wouldn't need to add and remove so many elements. just wrapper.innerHTML = ""; then wrapper.innerHTML = newRowSet; and done
Instead of setting h1.textContent = data.Search[index].Title; update this to h1.innerHTML = data.Search[key].Title;
Related
I'm trying to get data from a xml file and show inside inputs, but I need to get a parameter from a input.
This code is working when just click on the button, but it return the xml file with the parameter 'sbbr'
this is my code:
<script>
var icaocode = 'sbbr'
var client;
if (window.XMLHttpRequest) {
client = new XMLHttpRequest();
} else {
client = new ActiveXObject("Microsoft.XMLHTTP");
}
client.open('GET', 'https://mywebsite.com/api/?icaoCode=' + icaocode, true);
function buscarFunction() {
var xmlDoc = client.responseXML;
var heliponto = xmlDoc.getElementsByTagName("aisweb");
for (i = 0; i < heliponto.length; i++) {
data = heliponto[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
city = heliponto[i].getElementsByTagName("city")[0].childNodes[0].nodeValue;
org = heliponto[i].getElementsByTagName("rmkText")[0].childNodes[0].nodeValue;
}
document.getElementById('nome').value = data;
document.getElementById('cidade').value = city;
document.getElementById('org').value = org;
}
client.send();
</script>
<input id="icao"><button type="button" onclick="buscarFunction()">Buscar</button><Br>
<input id="nome"><br>
<input id="cidade"><br>
<input id="org">
I need to get this paramenter from here:
<input id="icao"><button type="button" onclick="buscarFunction()">Buscar</button>
but is not populating the variable icaocode, I have tryed this:
var icaocode = document.getElementById('icao').value;
client.open('GET', 'https://mywebsite.com/api/?icaoCode=' + icaocode, true);
Try putting your <script> below the <body> tag after all elements have finished rendering. I think what's happening is that document.getElementById('icao') is returning null because there is no element with ID icao yet.
I fixed, found a solution.
just needed to add the function onload and put all the code inside the main function like this:
<input id="icao"><button type="button" onclick="buscarFunction()">Buscar</button><Br>
<input id="nome"><br>
<input id="cidade"><br>
<input id="org">
<script>
function buscarFunction() {
var icaocode = document.getElementById('icao').value;
var client;
if (window.XMLHttpRequest) {
client = new XMLHttpRequest();
} else {
client = new ActiveXObject("Microsoft.XMLHTTP");
}
client.open('GET', 'https://mywebsite.com/api/?icaoCode=' + icaocode, true);
client.send();
client.onload = function () {
var xmlDoc = client.responseXML;
var heliponto = xmlDoc.getElementsByTagName("aisweb");
for (i = 0; i < heliponto.length; i++) {
data = heliponto[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
city = heliponto[i].getElementsByTagName("city")[0].childNodes[0].nodeValue;
org = heliponto[i].getElementsByTagName("rmkText")[0].childNodes[0].nodeValue;
}
document.getElementById('nome').value = data;
document.getElementById('cidade').value = city;
document.getElementById('org').value = org;
};
}
</script>
and after that storage the variable from the input:
var icaocode = document.getElementById('icao').value;
I am very new to JS and I have a problem to create a searchable movie reviewer html page, it is very basic, I just want to know how to have the input box search the NYT API for the movie I am looking for, I wont have a problem putting the elements onto the page, I just want to know how to search properly. I expect I need a function that when the search button is clicked it requests from the site all movies with the words provided.
<div id="search">
<input type="text" id = "search">
<button onclick="search()">Search</button>
</div>
<textarea id="APIoutput" cols="90" rows="50"></textarea>
const ISFINISHED = 4;
const ISOK = 200;
var searchedMovie = document.getElementById("search").value;
function getJSONSync(url){
var response = "";
var xmlHttp = new XMLHttpRequest();
if(xmlHttp !== null){
xmlHttp.open("GET", url, false);
xmlHttp.send(null);
response = xmlHttp.responseText;
}
return response;
}
function getJSONAsync(url, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === ISFINISHED && request.status === ISOK) {
callback(this);
}
};
request.open("GET", url);
request.send();
}
function search(searchedMovie){
var my_api_url = "https://api.nytimes.com/svc/movies/v2/reviews/search.json?query=" + searchedMovie + "&api-key=" + API;
return my_api_url;
}
function handleAPIresponse(response) {
var textArea = document.getElementById("APIoutput");
textArea.value = response.responseText;
}
getJSONAsync(my_api_url, handleAPIresponse);
ERRORS: Uncaught ReferenceError: my_api_url is not defined
Expected Results: (UNFORMATTED JSON THAT LOOKS LIKE THIS:)
{"status":"OK","copyright":"Copyright (c) 2021 The New York Times
Company. All Rights
Reserved.","has_more":false,"num_results":10,"results":[{"display_title":"The
Black Godfather","mpaa_rating":"TV-MA","critics_pick":0,"byline":"BEN
KENIGSBERG","headline":"‘The Black Godfather’ Review: The Music
Executive Who Made It All Happen"
I am working on a small project for University using JavaScript, JSON and AJAX to pull information from 3 seperate restaurant menus (stored in JSON files) and displaying them in a list once the relevant button has been clicked.
This worked using one menu, having a button with an event listener that ran the loadAjax function and displayed the relevant menu information.
I've tried to expand this using 3 buttons, with an event listener on each that passes the name of the JSON file through the function parameter. This no longer works, and only the last JSON file is displayed, on window load, without clicking a button.
I'm pretty stuck at this stage and want to avoid having three separate functions (for obvious reasons). The code is below, any help would be much appreciated! I may have made a minor error so apologies if this is a silly question.
var weekdayBtn = document.getElementById("weekdayBtn"),
saturdayBtn = document.getElementById("saturdayBtn"),
sundayBtn = document.getElementById("sundayBtn");
weekdayBtn.addEventListener("click", loadAjax("weekday.json"), false);
saturdayBtn.addEventListener("click", loadAjax("saturday.json"), false);
sundayBtn.addEventListener("click", loadAjax("sunday.json"), false);
function loadAjax(menuData) {
var request = new XMLHttpRequest();
request.open('GET', menuData);
request.onreadystatechange = function() {
if ((request.readyState === 4) && (request.status === 200)) {
var menu = JSON.parse(request.responseText);
var output = "";
for (var key in menu) {
output += "<li>" + menu[key]["Title"] + ", " + menu[key]["Description"] + ". " + menu[key]["Price"] + " </li>";
}
var menu = document.getElementById('menu');
menu.innerHTML = output;
}
}
request.send();
}
The addEventListener methods requires a function as second argument so your loadAjax method must return a function:
function loadAjax(menuData) {
return function () {
var request = new XMLHttpRequest();
request.open('GET', menuData);
request.onreadystatechange = function() {
if ((request.readyState === 4) && (request.status === 200)) {
var menu = JSON.parse(request.responseText);
var output = "";
for (var key in menu) {
output += "<li>" + menu[key]["Title"] + ", " + menu[key]["Description"] + ". " + menu[key]["Price"] + " </li>";
}
var menu = document.getElementById('menu');
menu.innerHTML = output;
}
}
request.send();
}
}
in this way the inner function will be used as event listener with the menuData variable in its scope.
i have some problrm creating the radio buttons dynamically. in my problem i am requesting data from server in json formate than i check if it contains options i have to create the radio buttons otherwise simply creates the txt area of field to submit the answer. than again i parse it in json formate and send to the server and if my question is write i get new url for next question and so on...
my question is how can i create the radio buttons and read the data from it and than parse that data like {"answer": "something"}.my code is bellow:
enter code herefunction loadDoc(url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
var data = JSON.parse(this.responseText);
document.getElementById("my_test").innerHTML = data.question;
// Send the answer to next URL
if(data.alternatives !== null){
createRadioElement(div,);
}
var answerJSON = JSON.stringify({"answer":"2"});
sendAnswer(data.nextURL, answerJSON)
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function sendAnswer(url, data) {
xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(this.responseText);
console.log(this.responseText);
loadDoc(data.nextURL);
}
}
// var data = JSON.stringify({"email":"hey#mail.com","password":"101010"});
xhr.send(data);
}
function createRadioElement(name, checked) {
var radioHtml = '<input type = "radio" name="' + name + '"';
if ( checked ) {
radioHtml += ' checked="checked"';
}
radioHtml += '/>';
var radioFragment = document.createElement('div');
radioFragment.innerHTML = radioHtml;
return radioFragment.firstChild;
}
I'm only guessing since you have some things in your posted code that won't even run, but createRadioElement returns a detached node which you never actually inject into your document.
E.g.,
document.body.appendChild(createRadioElement());
I have a form with 2 inputs, where the 1st input has a datalist attribute.
<div class="col-xs-4">
<input name="description" type="text" id="ajax" list="json-datalist">
<datalist id="json-datalist"></datalist>
</div>
<div class="col-xs-2">
<input type="text" name="product" />
</div>
the JSON file has this format
[ {
"product":"1235",
"description":"description 1"
},
{
"product":"1325",
"description":"description 2"
},
...
]
What I want is when the user selects one of the description, then the product to be added in the 2nd input..
here is the code for the javascript where loads the JSON file to the form
var dataList = document.getElementById('json-datalist');
var input = document.getElementById('ajax');
var request = new XMLHttpRequest();
request.onreadystatechange = function(response) {
if (request.readyState === 4) {
if (request.status === 200) {
// Parse the JSON
var jsonOptions = JSON.parse(request.responseText);
// Loop over the JSON array.
jsonOptions.forEach(function(item) {
// Create a new <option> element.
var option = document.createElement('option');
// Set the value using the item in the JSON array.
option.value = item.description;
//<--
// Add the <option> element to the <datalist>.
dataList.appendChild(option);
});
// Update the placeholder text.
input.placeholder = "e.g. datalist";
} else {
// An error occured :(
input.placeholder = "Couldn't load datalist options :(";
}
}
};
// Update the placeholder text.
input.placeholder = "Loading options...";
// Set up and make the request.
request.open('GET', 'myfile.json', true);
request.send();
How can I add the item.product as a value to the second input, when the item.description is selected?
Set product in the data attribute of datalist like following.
option.value = item.description; //after this line
option.setAttribute('data-product', item.product);
And in description change event set product to second input like following using jquery.
$('#ajax').change(function() {
var description = $(this).val();
var product = $('#json-datalist > option[value="' + description + '"]').data('product');
$('input[name=product]').val(product);
});
Full JS code given below. Hope this helps.
var dataList = document.getElementById('json-datalist');
var input = document.getElementById('ajax');
var request = new XMLHttpRequest();
request.onreadystatechange = function (response) {
if (request.readyState === 4) {
if (request.status === 200) {
// Parse the JSON
var jsonOptions = JSON.parse(request.responseText);
// Loop over the JSON array.
jsonOptions.forEach(function (item) {
// Create a new <option> element.
var option = document.createElement('option');
// Set the value using the item in the JSON array.
option.value = item.description;
option.setAttribute('data-product', item.product);
//<--
// Add the <option> element to the <datalist>.
dataList.appendChild(option);
});
// Update the placeholder text.
input.placeholder = "e.g. datalist";
} else {
// An error occured :(
input.placeholder = "Couldn't load datalist options :(";
}
}
};
// Update the placeholder text.
input.placeholder = "Loading options...";
// Set up and make the request.
request.open('GET', 'myfile.json', true);
request.send();
$(function() {
$('#ajax').change(function() {
var description = $(this).val();
var product = $('#json-datalist > option[value="' + description + '"]').data('product');
$('input[name=product]').val(product);
});
});
You can create your <option> element with some other attribute that indicates the product, and then use that attribut to copy it into the second input.
request.onreadystatechange = function(response) {
if (request.readyState === 4) {
if (request.status === 200) {
// Parse the JSON
var jsonOptions = JSON.parse(request.responseText);
// Loop over the JSON array.
jsonOptions.forEach(function(item) {
// Create a new <option> element.
var option = document.createElement('option');
// Set the value using the item in the JSON array.
option.value = item.description;
$(option).attr('data-product',item.product);//THIS IS THE NEW LINE
//<--
// Add the <option> element to the <datalist>.
dataList.appendChild(option);
});
// Update the placeholder text.
input.placeholder = "e.g. datalist";
} else {
// An error occured :(
input.placeholder = "Couldn't load datalist options :(";
}
}
};
And then, for copying it, if you are using JQuery:
$('input#ajax').change(function(){
$('input[name="product"]').val($('#json-dataList').find('option:selected').attr('data-product'));
});