The code below is commented throughout. It is my understanding that I'm retrieving the JSON data and passing it to the 'results' div in my HTML view. This actually returns nothing, and it's difficult to debug because I can't output anything to the console.
// Here is how the final url should look:
// api.openweathermap.org/data/2.5/weather?q=Chicago&APPID=2e76bb25aa22d34ca062d764f4f3114b
var weatherSearch = '';
// weather-search is my html form id. On submit, send the input
// (which is city name) to the function getWeather.
$('#weather-search').submit(function(event) {
weatherSearch = $('#weatherQuery').val();
event.preventDefault();
getWeather(weatherSearch);
});
// getWeather has params q (city name), and APPID (API key).
function getWeather(weatherSearch) {
var params = {
q: weatherSearch,
APPID: '2e76bb25aa22d34ca062d764f4f3114b'
};
// This is the url that goes before the params.
url = 'http://api.openweathermap.org/data/2.5/weather/';
// Request data using url and params above.
// Does $.getJSON format the url properly?
$.getJSON(url, params, function(data) {
// Pass JSON data to showWeather function.
showWeather(data.items);
});
}
function showWeather(weather) {
// Show JSON data (weather) in html div id="weatherResults"
$('#weatherResults').html(weather);
}
Here is the associated HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>weather</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="openweather.js"></script>
</head>
<body>
<form id="weather-search">
<input type="text" value="" id="weatherQuery" />
<input type="submit" />
</form>
<div id="weatherResults">
</div>
</body>
</html>
Here's a codepen for the program
This answer demonstrates multiple ways to request and view data.
The code snippet below queries the web service using either jQuery or plain javascript. The returned data is displayed on the screen using JSON.stringify() and Google Prettify. The data is also sent to the console. Interestingly, the OpenWeatherMap service makes a good guess when the city name is misspelled.
The problem with OP's code appears to be this line: showWeather(data.items); which tries to display an object as html.
Run the snippet to try
var url = 'http://api.openweathermap.org/data/2.5/weather?APPID=2e76bb25aa22d34ca062d764f4f3114b';
// plain javascript version
function getWeather(city) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url + '&q=' + city, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
showData( data );
}
}
xhr.send();
}
// jQuery version
function getWeather2( city ) {
$.getJSON(url + '&q=' + city, showData );
}
// display json weather data
function showData( data ) {
window.city.value = data.name;
window.stdout.innerHTML = JSON.stringify(data, false, ' ');
window.stdout.className = 'prettyprint';
PR.prettyPrint();
if (window.console) window.console.log( data );
}
// sample data
getWeather('Berlin');
input {border: 1px solid black;}
button {width: 8em; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/run_prettify.js?autoload=false&skin=sunburst&lang=js"></script>
Enter City: <input id="city" >
<button onclick="getWeather(window.city.value)">Use JS</button>
<button onclick="getWeather2(window.city.value)">Use jQuery</button>
<pre id="stdout" class="prettyprint"></pre>
You can use console.log or the dom to print messages for debugging. You can run a callback like this to find out if a request fails, this will tell you more infomation:
$.getJSON(url, params, function(data) {
// Pass JSON data to showWeather function.
showWeather(data.items);
}).fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
});
Using the complete URL (http://api.openweathermap.org/data/2.5/weather/?q=Chicago&APPID=2e76bb25aa22d34ca062d764f4f3114b) directly in a browser returns some JSON with data about chicago -- but that JSON does NOT contain an item property. Thus, your data.items is null and nothing is shown.
Just check what you actually get from the browser and adopt your code accordingly (e.g. data.name would give you "Chicago", or simply use showWeather(data); to show all JSON you got).
Related
I have multiple input tags, my task is to collect the values entered by the user and send it back to the server. I am using Django as my framework. I am successful in sending the data to the client side (javascript).
To return back the data from javascript function to my python function, I used XMLHttpRequest.
I have added my code below:
<html>
<head>
<style>label{ text-align:center; width:250px; color:blue; display:inline-block}</style>
<script type="text/javascript" src="'+url_read+'"></script>
<script>
function submit_this()
{
var i,j;var arr=[];
for(i=0; i<Hello.length; i++)
{
arr[i]=[];
for(j=0;j<Hello[i].length; j++)
{
arr[i].push(document.getElementById(Hello[i][j]).value);
}
}
alert(document.getElementById(Hello[1][0]).value);
xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.open('POST', '/button_click',true);
xmlHttpReq.send('w=' + encodeURI(arr));
}
</script>
</head>
<body>
<center>
<button id="submit_button" onclick="submit_this();" value="Submit">Submit</button>
</center>
</body>
</html>
The above code is stored in a string called html_string.
Hello is a json object read from the file denoted by the varible url_read. It was dumped using Python.
The plan was to use HttpResponse to send the html_string and render the html page in return.
I understand that I need to make one POST function in one of the classes in views.py. But unable to understand how to approach this problem.
I have to somehow send the javascript data structure named arr back to the server side. The main doubt is where can I put my code where I can read the value posted by the javascript function.
I want to navigate to a new page once submit button has been pressed and in Django each url has a new function (in views.py) associated with it. Should I place it in that ?
Here is an example where in I am sending values to (Django)python server using JS, and receiving html rendered template.
I am using ul tag with id #Nearby to load html inside an html.
Ajax success is returning html from django view rendered through url endpoint '/getGopoints/'
template.html
<div class="row">
<div>
<ul id="Nearby">
</ul>
</div>
</div>
<script>
$(document).ready(function(){
$('#dataTables-example1').DataTable({
responsive: true
});
getLocation();
});
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
}
function showPosition(position) {
$.ajax({
url : '/getGopoints/', // the endpoint
type : 'GET', // http method
data : { 'lat' : position.coords.latitude,
'lon' : position.coords.longitude,
'csrfmiddlewaretoken': '{{csrf_token}}'
}, // data sent with the post request
// handle a successful response
success : function(data) {
$('#Nearby').html(data);
},
dataType: 'html'
});
}
</script>
urls.py
url(r'^getGopoints/$',views.getGopoints, name='getGopoints'),
views.py
def getGopoints(request):
lat = str(request.GET['lat'])
lon = str(request.GET['lon'])
pnt=fromstr('POINT(%s %s)' %(lon,lat))
with_in_distance = 20
go_points = GoPoint.objects.filter(point__distance_lte=(pnt, D(km=with_in_distance)))
context = RequestContext(request,
{'go_points':go_points,
'with_in_distance':with_in_distance,
})
return render_to_response('nearby.html',
context_instance=context)
I'm trying to get two values (x and y) from a javascript (Virtualjoystick.js) and pass them to a (prototype.js) Ajax script. I've been reading through similar questions and answers both here and on other websites but I'm not really 'getting it'! Any help would be greatly appreciated.
Here is a simplified version of what I have so far.
<html>
<head>
<script src="JavaScripts/prototype.js"></script>
<script src="JavaScripts/virtualjoystick.js"></script>
</head>
<body>
<div id="info">
<span id="result"><b>Joystick:</b> X:0 Y:0</span>
</div>
<div id="container">
<canvas height="300" width="300"></canvas>
<canvas height="300" width="300"></canvas>
<script>
console.log("touchscreen is", VirtualJoystick.touchScreenAvailable() ? "available" : "not available");
var joystick = new VirtualJoystick({
container : document.getElementById('container'),
mouseSupport : true,
stationaryBase: true,
baseX: 150,
baseY: 150,
limitStickTravel: true,
stickRadius: 100
});
joystick.addEventListener('touchStart', function(){
console.log('down')
})
joystick.addEventListener('touchEnd', function(){
console.log('up')
})
setInterval(function(){
var outputEl = document.getElementById('result');
outputEl.innerHTML = '<b>Result:</b> '
+ ' X:'+parseInt(joystick.deltaX())
+ ' Y:'+parseInt(joystick.deltaY())
}, 1/30 * 1000);
</script>
</div>
<div>
<form>
<input type="button" value="On" onClick="go('60.30')" style="font-size:200%;"><br />
<input type="button" value="Off" onClick="go('0.0')" style="font-size:200%;">
</form>
<script type="text/javascript">
function go(qry) {
new Ajax.Request('motor_control.py?q='+ qry,
{method: 'GET'}
);
}
</script>
</div>
</body>
</html>
What I need is parseInt(joystick.deltaX()) and +parseInt(joystick.deltaY()) from the virtualjoystick.js script to be written to the end of the Ajax.Request. Something like:
new Ajax.Request('motor_control.py?q='+parseInt(joystick.deltaX())
+ '.'+parseInt(joystick.deltaY()),
I tried that but it didn't seem to work!
As you can probably tell JavaScript is a foreign language to me, so any help at all would be appreciated.
If you are wanting to use plain JavaScript you can use something like the example below. You will have to remember that when using AJAX type function that you will only be able to perform operations on the data retrieved by the function from inside a call back or promise function. Click on the following link to see the Ajax function in action.
Live Example
JavaScript:
//path to the file you are sending and retrieving data
//this will differ from the Plunker link code because
//I do not have access to the url in your example.
var url = "motor_control.py?q='+ qry";
//call get Ajax function
get(url,function(data){//begin call back function
//do something with data variable here
//change the innerHTML of the example id element.
document.getElementById("example").innerHTML = "I was rendered by an AJAX function!"
});//end call back function
function get(url,fn){//begin ajax function
var contentType;
//variable to hold the xmlhttp object
var xmlhttp = null;
//if the browser contains the object
if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
//create a new XMLHttpRequest object
xmlhttp=new XMLHttpRequest();
}
//add the event listenter
xmlhttp.onreadystatechange = function(){
//if the status of the request is good
if (xmlhttp.readyState===4 && xmlhttp.status===200){//begin if then
//get the response text and store it in the data variable
var data = xmlhttp.responseText;
//call the callback function
fn(data,fn);
}//end if then
};//end function
//open a the http request
xmlhttp.open("GET",url,true);
//set the request header
xmlhttp.setRequestHeader("Content-type",contentType);
//send the the request
xmlhttp.send();
}//end get function
I currently have a servlet setup to send over a list of our active servers. The method grabs the servlet data, processes it, then injects the html into the datalist tag. HTML injection process works, but when I'm splitting the array by the concat separator (which I've done before), I get no values. Below I'll explain with code examples:
HTML:
<label for="server_id_text">Server ID: </label>
<input id="server_id_text" list="server_names" name="server_id" required>
<datalist id="server_names">
<!--This gets injected with the active servers grabbed through a get request-->
</datalist>
Javascript connecting to server to get data:
Note: serverList is a global variable.
var serverList = "";
function setupAutoComplete() {
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
console.debug("server list auto comp at post mailing: " + serverList);
});
}
This method is called in the function that is called when the onload event is called in the body tag
Here are the two methods that inject the html:
function setupServerName() {
document.getElementById("server_names").innerHTML = getServerListHTML();
}
function getServerListHTML(){
console.debug("Autocomplete process running...");
var servArr = String(serverList).split('*');
var html = '';
var temp = '<option value="{serverName}">';
console.debug("Array:" + servArr.toString());
if (serverList == 'undefined' || servArr.length == 0){
console.debug("serverList is empty...");
return '';
}
for (var i =0; i < servArr.length; ++i){
html += temp.replace("{serverName}", servArr[i]);
}
console.debug("html: " + html);
console.debug("ServList size " + servArr.length);
return html;
}
When the page loads, setupAutoCompelte() is called first. Then, setupServerName() is called.
My issue is that after I load the page, I get the correct response from the server. For instance, I'll get server1*server2 as a response to the jQuery $.get(...) call. Then I go to split the string into an array, and I get back an empty html tag (<option value="">);
Also, the debug console info are as follows:
Autocomplete process running...
Array:
html: <option value="">
ServList size 1
Status with auto comp id: success
server list auto comp at post mailing: server1*server2
Thanks for the help!
I believe that your setupServerName() function is being called before the AJAX request in setupAutoComplete() returns, so your serverList is an empty string at that point. What you need to do is populate your <datalist> from inside your AJAX callback in setupAutoComplete().
// setup autocomplete datalist
function setupAutoComplete() {
var $datalist = $('#server_names');
$.get(baseURL + '/SupportPortal').then(function (data) {
// update datalist
if (!data || !data.length) {
// no servers, empty list
$datalist.html('');
} else {
// create options html:
// reduce array of server names
// to HTML string, and set as
// innerHTML of the dataset
$datalist.html(data.split('*').reduce(function (html, server) {
return html + '<option value="' + server + '">\n';
},''));
}
});
}
// on page load, setup autocomplete
$(function () {
setupAutoComplete();
});
As you can see from "debug console info":
the get function is asyncrhonous so you need to change your setupAutoComplete get part to:
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
setupServerName();
console.debug("server list auto comp at post mailing: " + serverList);
});
On page load try to call directly the setupServerName function within the success event of get function. A different approach is to divide the setupServerName function so that the part related to the serverList variable becomes part of another function.
The serverList variable is global but its content is filled after the setupServerName is executed.
I use a js to display some content on my app (I use Dreamweaver and PhoneGap). When i preview the html separately works, but when i load the html from other page dont.
I receive this msg on the Firefox Security: ReferenceError: requestCrossDomain is not defined
This is my HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Mobile Web App</title>
<script src="js/jquery-1.11.0.min.js"></script>
<script src="js/cross-domain-request.js"></script>
</head>
<body>
<div id="container">
<p id="sitename"> http://catedralaltapatagonia.com/invierno/partediario.php? default_tab=0
</p>
function codeAddress(){
var elem = document.getElementById("sitename");
elem.value = "http://catedralaltapatagonia.com/invierno/partediario.php? default_tab=0";
var path =$('#sitename').val();
requestCrossDomain(path, function(results){
$('#container').html(results);
});
return false;
};
</script>
</body>
</html>
And my cross-domain-request.js:
/ JavaScript Document
// Accepts a url and a callback function to run.
function requestCrossDomain( site, callback ) {
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + 'http://catedralaltapatagonia.com/invierno/partediario.php?default_tab=0' + '"'+' AND xpath="//*[#id=\'meteo_recuadro\']"') + '&format=xml&callback=?';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON( yql, function(data){
// If we have something to work with...
if ( data.results[0] ) {
// Strip out all script tags, for security reasons.
// BE VERY CAREFUL. This helps, but we should do more.
data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
// If the user passed a callback, and it
// is a function, call it, and send through the data var.
if ( typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
});
}
Some clue to resolve it?
You appear to have an error in your external JS file, and it's not running. The final else statement is not correct. Try this:
/ JavaScript Document
// Accepts a url and a callback function to run.
function requestCrossDomain( site, callback ) {
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + 'http://catedralaltapatagonia.com/invierno/partediario.php?default_tab=0' + '"'+' AND xpath="//*[#id=\'meteo_recuadro\']"') + '&format=xml&callback=?';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON( yql, function(data){
// If we have something to work with...
if ( data.results[0] ) {
// Strip out all script tags, for security reasons.
// BE VERY CAREFUL. This helps, but we should do more.
data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
// If the user passed a callback, and it
// is a function, call it, and send through the data var.
if ( typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else {
throw new Error('Nothing returned from getJSON.');
}
});
}
I add the line
<script src="js/cross-domain-request.js"></script>
and the js is loaded
I did a cross-domain JSON request with YQL and it returns me the JSON code in a table <div> in the html file.
Now my problem is that I don't know to get this data and put it in a table.
This is the code (in JS file):
// JavaScript Document
$(document).ready(function(){
var container = $('#target');
$('.ajaxtrigger').click(function(){
doAjax($(this).attr('href'));
return false;
});
function doAjax(url){
// if it is an external URI
if(url.match('^http')){
// call YQL
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=xml'&callback=?",
// this function gets the data from the successful
// JSON-P call
function(data){
// if there is data, filter it and render it out
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
// otherwise tell the world that something went wrong
} else {
var errormsg = "<p>Error: can't load the page.</p>";
container.html(errormsg);
}
}
);
// if it is not an external URI, use Ajax load()
} else {
$('#target').load(url);
}
}
// filter out some nasties
function filterData(data){
data = data.replace(/<?\/body[^>]*>/g,'');
data = data.replace(/[\r|\n]+/g,'');
data = data.replace(/<--[\S\s]*?-->/g,'');
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,'');
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,'');
data = data.replace(/<script.*\/>/,'');
return data;
}
});
and here is the html code:
<body>
<div id="doc" class="yui-t7">
<div id="hd" role="banner">
<h1>
Ajax with jQuery - using YQL
</h1>
</div>
<div id="bd" role="main">
<h2>
Demo
</h2>
<ul>
<li>
<a class="ajaxtrigger" href="ajaxcontent.html">
Load Ajax Content
</a>
</li>
<li>
<a class="ajaxtrigger" href="linkpage">
Get cspro.json
</a>
</li>
</ul>
<div id="target">
<!-- <script>window.alert(container)</script> -->
</div>
<h2>
Formatted List
</h2>
</div>
<div id="placeholder"></div>
<!-- <script> document.getElementById("placeholder").innerHTML = container.html(data);
</script> -->
<h2>
TEST
</h2>
</div>
<script src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script src="code.js"></script>
<script src="using-yql3.js"></script>
</body>
I've try with:
// $.getJSON(data, function(json){
// figure out the format of the answer here...
//
document.getElementById("placeholder").innerHTML=prova.buy.currency+" "+prova.sell.currency+" "+prova.offer[0].amount+" "+prova.offer[0].rate+" "+prova.offer[0].seller.name;
but it didn't work.
(UPDATE) after your indications, I've tested this:
// TEST
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=json'&callback=?", // QUESTO è URL cui segue la "," e poi function(data)
// this function gets the data from the successful
// JSON-P call
function(data){
document.getElementById('placeholder').value = JSON.stringify(data,null,' '); //MIO
// if there is data, filter it and render it out
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
alert(data); //MIO TEST
// otherwise tell the world that something went wrong
} else {
var errormsg = "<p>Error: can't load the page.</p>";
container.html(errormsg);
}
}
);
but it works up to alert(data) simply "jumping" the part of the code related to document.getElementById.
I've also changed the "xml" request into "json" request...
SECOND UPDATE
I've solved the problem with the "div id=placeholder" in the html table. Seems it has some problems with this div, considering that changing the "div id" with a "texture id=placeholder" it works.
So, now I have the whole json string in my text area.
I've tried the getJson command to recover a parte of the data and get it in a table, but again I've having some problems.
I can't understand with the code you suggested to me, I have a json code, why I can't extract it and show the part i need?
FINAL PARTIAL UPDATE
The problem was that the "data" filter wasn't eliminating "" tag from data, so that the parse.Json(data) was unable to read the format!
Right know I retrieve the information I need.
Here's the final .js code:
// JavaScript Document
$(document).ready(function(){
var container = $('#target');
$('.ajaxtrigger').click(function(){
doAjax($(this).attr('href'));
return false;
});
function doAjax(url){
// if it is an external URI
if(url.match('^http')){
// call YQL
// TEST
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=json'&callback=?",
// this function gets the data from the successful
// JSON-P call
function(data){
// if there is data, filter it and render it out
if(data.results[0]){
**var data = filterData(data.results[0]);**
container.html(data);
alert(data); // TEST VERIFY (after FILTER before data extraction)
document.getElementById("prova1").value = data; // TEST full data return in a textarea
var obj = $.parseJSON(data); // JSON elements retrieve
alert(obj.sell.currency); // TEST for element retrieve
// TEST END
// otherwise tell the world that something went wrong
} else {
var errormsg = "<p>Error: can't load the page.</p>";
container.html(errormsg);
}
}
);
// if it is not an external URI, use Ajax load()
} else {
$('#target').load(url);
}
}
// filter out some nasties
function filterData(data){
**data = data.replace(/<body>/,'');** // INTERTED THIS ONE TO REMOVE body tag
data = data.replace(/<?\/body[^>]*>/g,'');
data = data.replace(/[\r|\n]+/g,'');
data = data.replace(/<--[\S\s]*?-->/g,'');
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,'');
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,'');
data = data.replace(/<script.*\/>/,'');
return data;
}
});
Your main problem is that you are requesting data in XML format. Suggest changing your query string to format=json. That will return a javascript object that you can work with more easily.
Since you are already using jQuery I highly recommend the DataTables plug-in.
Here's a code snippet that illustrates the data formats returned from Yahoo. And the Yahoo Console is also very helpful when testing.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<button onclick="json()">GET JSON</button><button onclick="xml()">GET XML</button>
<textarea id="stdout" style="width:100%;height:40em;"></textarea>
<script type="text/javascript">
function json() {
var url = 'https://query.yahooapis.com/v1/public/yql?q=show%20tables&format=json&diagnostics=true&callback=?';
$.getJSON( url, function(data) {
document.getElementById('stdout').value = JSON.stringify(data,null,' ');
});
}
function xml() {
var url = 'https://query.yahooapis.com/v1/public/yql?q=show%20tables&format=xml&diagnostics=true&callback=?';
$.getJSON( url, function(data) {
document.getElementById('stdout').value = JSON.stringify(data,null,' ');
});
}
</script>
</body>
</html>
You may want to look at this library: https://github.com/IonicaBizau/jQuery-cross-domain-requests