This question is a followup on this question and this one. I am unable to send form field values through jquery's ajax api. The code is as follows:
index.html
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<link rel="stylesheet" type="text/css" href="index.css">
<script src="https://code.jquery.com/jquery-2.1.3.js"></script>
<script type="text/javascript" src="index.js"></script>
</head>
<body onload="welcome()">
<div class id="main"></div>
</body>
</html>
The welcome function is implemented in index.js:
index.js
function welcome()
{
view_account();
}
function get_form_data_with_token($form){
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function(n, i){
indexed_array[n['name']] = n['value'];
});
indexed_array['token'] = 'adafdafdgfdag';
return indexed_array;
}
$(document).ready(function(){
$("#changepassword_form_id").submit(function(e){
var uri, method, formId, $form, form_data;
// Prevent default jquery submit
e.preventDefault();
e.stopImmediatePropagation();
uri = location.protocol + '//' + location.host + "/change_password";
method = "POST";
formId = "#changepassword_form_id";
$form = $(formId);
form_data = get_form_data_with_token($form);
alert("form_data: token = " + form_data['token'] + " password3 = " + form_data['l_password3'] + " password4 = " + form_data['l_password4']);
// Set-up ajax call
var request = {
url: uri,
type: method,
contentType: "application/json",
accepts: "application/json",
cache: false,
// Setting async to false to give enough time to initialize the local storage with the "token" key
async: false,
dataType: "json",
data: form_data
};
// Make the request
$.ajax(request).done(function(data) { // Handle the response
// Attributes are retrieved as object.attribute_name
console.log("Data from change password from server: " + data);
alert(data.message);
}).fail(function(jqXHR, textStatus, errorThrown) { // Handle failure
console.log(JSON.stringify(jqXHR));
console.log("AJAX error on changing password: " + textStatus + ' : ' + errorThrown);
}
);
});
});
function view_account()
{
var changePassword;
changePassword = "<form action=\"/change_password\" id=\"changepassword_form_id\" method=\"post\">";
changePassword = changePassword + "<br><label>Old Password: </label><input id=\"password3\" type=\"password\" name=\"l_password3\" required><br>";
changePassword = changePassword + "<br><label>New Password: </label><input id=\"password4\" type=\"password\" name=\"l_password4\" required><br><br>";
changePassword = changePassword + "<input type=\"submit\" value=\"Change Password\">";
changePassword = changePassword + "</form>";
// Replace the original html
document.getElementById("main").innerHTML = changePassword;
}
The onsubmit handler is not executed even though the dom ready event is used as mentioned in this question.
How can I submit the fields only once using the ajax api from jquery?
Edit:
jsfiddle example from a previous question. Even though the code runs on jsfiddle it fails when run in fire fox.
Use the on event handler like this:
$(document).on("submit","#changepassword_form_id",function(e){
...code here...
});
This delegates it, since #changepassword_form_id isn't yet defined on document.ready.
Since, you are using required property on inputs and need to check for filled forms, you can use submit event.
You are clearly appending the html dom before the div has even loaded..
Heres a step by step breakup of the flow...
You are loading the .js file inside the <head>.
You are calling the function inside the file which has the following line, document.getElementById("main").innerHTML = changePassword; But, but there is nothing with the id "main" yet!!!
Then the <body> is being loaded, inside which the div with the id "main" is present.
You see the logic?? right??
Not to be nosy, but this problem is the outcome of the wrong design of your code, fixing it with any workaround is only going to cause you further headaches, so I strongly recommend that you update the code design, unless you have really little control over the code, in which case the patch work is your only option.
And if you are going by the patchwork, you can always use the .off.on event delegation which removes the possibilities of event duplication on code rerun.
Related
I am trying to do a web app that shows results from a query, using Google Books API.
My code is working, but the .innerHTML is not showing any result on the Html page. This is the Html that I am using.
<!DOCTYPE html>
<!-- -->
<html>
<head>
<title>Google Books API Search</title>
<!--linkink stylesheet-->
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div id="search" class="#f5f5f5 grey lighten-4 z-depth-5">
<form id="bookForm">
<div class="inputField">
<input type="search" id="books">
<label for="search">Search for books</label>
</div>
<div class="btnHolder">
<button id="button" class="btn red">Search</button>
</div>
</form>
</div>
<div id="results">
</div>
<!--linking scripts-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
and this is the JavaScript code that is running.
/*global document, $, console, event, results */
function bookSearch() {
/* eslint-disable no-console */
event.preventDefault(); //preventing auto refresh of the page
//console.log("This function is working."); //console.log to see if the function was running properly
var search = document.getElementById('search').value; //storing the value of search
document.getElementById('results').innerHTML = '';
console.log(search);
$.ajax({
url: "https://www.googleapis.com/books/v1/volumes?q=" + search, //linking API + our search
dataType: "json",
success: function(data) {
console.log(data)
for (i=0;i<data.items.lenght;i++){
results.innerHTML = "<h2>" + data.items[i].volumeInfo.title + "</h2>"
}
},
type: "GET"
})
}
From the console, I can see that data are gathered in the right way to the API, but the main problem is that I can not manage to show the results on the page itself.
Maybe it is just a silly mistake, but I am struggling to find a solution for this.
I think you want write multiple result, one after other, but you override the 'results' content. One fix can be this:
success: function (data) {
for (let i = 0; i < data.items.length; i++ ) {
results.innerHTML += '<h2>'+ data.items[i].volumeInfo.title +'</h2>';
// ^ defined ^ see the plus sing in the declaration
}
}
You are not retrieving the DOM element results and assigning the innerHTML:
$.ajax({
url: "https://www.googleapis.com/books/v1/volumes?q=" + search, //linking API + our search
dataType: "json",
success: function(data) {
console.log(data)
// ADD THIS LINE
var results = document.getElementById('results');
for (i=0;i<data.items.length;i++){ // YOU HAD A TYPO HERE WITH `length`
// YOU WANT TO CONCATENATE CONTENT OTHERWISE YOU'LL REPLACE IT EACH TIME
results.innerHTML += "<h2>" + data.items[i].volumeInfo.title + "</h2>"
}
},
type: "GET"
})
Its definitely recommended to update the DOM the minimal amount possible, so it would be better to create and assign a variable, then assign results.innerHTML ONCE. But this should get you started.
Please could someone help me work out how to get started with JSONP?
Code:
$('document').ready(function() {
var pm_url = 'http://twitter.com/status';
pm_url += '/user_timeline/stephenfry.json';
pm_url += '?count=10&callback=photos';
var photos = function (data) {
alert(data);
};
$.ajax({
url: pm_url,
dataType: 'jsonp',
jsonpCallback: 'photos',
jsonp: false,
});
});
Fiddle: http://jsfiddle.net/R7EPt/6/
Should produce an alert, as far as I can work out from the documentation: isn't (but isn't producing any errors either).
thanks.
JSONP is really a simply trick to overcome XMLHttpRequest same domain policy. (As you know one cannot send AJAX (XMLHttpRequest) request to a different domain.)
So - instead of using XMLHttpRequest we have to use script HTMLl tags, the ones you usually use to load JS files, in order for JS to get data from another domain. Sounds weird?
Thing is - turns out script tags can be used in a fashion similar to XMLHttpRequest! Check this out:
script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data";
You will end up with a script segment that looks like this after it loads the data:
<script>
{['some string 1', 'some data', 'whatever data']}
</script>
However this is a bit inconvenient, because we have to fetch this array from script tag. So JSONP creators decided that this will work better (and it is):
script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data?callback=my_callback";
Notice my_callback function over there? So - when JSONP server receives your request and finds callback parameter - instead of returning plain JS array it'll return this:
my_callback({['some string 1', 'some data', 'whatever data']});
See where the profit is: now we get automatic callback (my_callback) that'll be triggered once we get the data.
That's all there is to know about JSONP: it's a callback and script tags.
NOTE:
These are simple examples of JSONP usage, these are not production ready scripts.
RAW JavaScript demonstration (simple Twitter feed using JSONP):
<html>
<head>
</head>
<body>
<div id = 'twitterFeed'></div>
<script>
function myCallback(dataWeGotViaJsonp){
var text = '';
var len = dataWeGotViaJsonp.length;
for(var i=0;i<len;i++){
twitterEntry = dataWeGotViaJsonp[i];
text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
}
document.getElementById('twitterFeed').innerHTML = text;
}
</script>
<script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
</body>
</html>
Basic jQuery example (simple Twitter feed using JSONP):
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.ajax({
url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
dataType: 'jsonp',
success: function(dataWeGotViaJsonp){
var text = '';
var len = dataWeGotViaJsonp.length;
for(var i=0;i<len;i++){
twitterEntry = dataWeGotViaJsonp[i];
text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
}
$('#twitterFeed').html(text);
}
});
})
</script>
</head>
<body>
<div id = 'twitterFeed'></div>
</body>
</html>
JSONP stands for JSON with Padding. (very poorly named technique as it really has nothing to do with what most people would think of as “padding”.)
There is even easier way how to work with JSONP using jQuery
$.getJSON("http://example.com/something.json?callback=?", function(result){
//response data are now in the result variable
alert(result);
});
The ? on the end of the URL tells jQuery that it is a JSONP request instead of JSON. jQuery registers and calls the callback function automatically.
For more detail refer to the jQuery.getJSON documentation.
In response to the OP, there are two problems with your code: you need to set jsonp='callback', and adding in a callback function in a variable like you did does not seem to work.
Update: when I wrote this the Twitter API was just open, but they changed it and it now requires authentication. I changed the second example to a working (2014Q1) example, but now using github.
This does not work any more - as an exercise, see if you can replace it with the Github API:
$('document').ready(function() {
var pm_url = 'http://twitter.com/status';
pm_url += '/user_timeline/stephenfry.json';
pm_url += '?count=10&callback=photos';
$.ajax({
url: pm_url,
dataType: 'jsonp',
jsonpCallback: 'photos',
jsonp: 'callback',
});
});
function photos (data) {
alert(data);
console.log(data);
};
although alert()ing an array like that does not really work well... The "Net" tab in Firebug will show you the JSON properly. Another handy trick is doing
alert(JSON.stringify(data));
You can also use the jQuery.getJSON method. Here's a complete html example that gets a list of "gists" from github. This way it creates a randomly named callback function for you, that's the final "callback=?" in the url.
<!DOCTYPE html>
<html lang="en">
<head>
<title>JQuery (cross-domain) JSONP Twitter example</title>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.getJSON('https://api.github.com/gists?callback=?', function(response){
$.each(response.data, function(i, gist){
$('#gists').append('<li>' + gist.user.login + " (<a href='" + gist.html_url + "'>" +
(gist.description == "" ? "undescribed" : gist.description) + '</a>)</li>');
});
});
});
</script>
</head>
<body>
<ul id="gists"></ul>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>An JSONP example </title>
</head>
<body>
<!-- DIV FOR SHOWING IMAGES -->
<div id="images">
</div>
<!-- SCRIPT FOR GETTING IMAGES FROM FLICKER.COM USING JSONP -->
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
format: "json"
},
//RETURNED RESPONSE DATA IS LOOPED AND ONLY IMAGE IS APPENDED TO IMAGE DIV
function(data) {
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
});
});</script>
</body>
</html>
The above code helps in getting images from the Flicker API. This uses the GET method for getting images using JSONP. It can be found in detail in here
I have written a nodejs plugin in C++ and I am trying to call it from within a locally hosted webpage with jQuery. I have read that I can't make a direct call to nodejs because of the same origin policy so I should use jsonp. Note: I am pretty new to jquery, nodejs and json(p), but I am feeling adventurous. I am now using the following code:
node_test.js:
var mylib = require("./mylibrary");
var http = require("http");
http.createServer(function(req, res) {
console.log("Received request: " + JSON.stringify(req.url));
res.writeHead(200, {"Content-type": "text/plain"});
res.end('_testcb(\'{"message": "' + mylib.my_awesome_function() + '"}\')');
}).listen(1337);
index.html:
index.html:
<DOCTYPE HTML>
<html>
<head>
<title>
NodeJS test
</title>
<link rel='stylesheet' type='text/css' href='style.css'/>
<script type='text/javascript' src='jquery.js'></script>
</head>
<body>
<div id="test"></div>
<script>
$(document).ready(function() {
$.ajax({
url: "http://127.0.0.1:1337/",
dataType: "jsonp",
jsonpCallback: "_testcb",
cache: false,
data: "test_data",
timeout: 5000,
success: function(data) {
$("#test").append(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
});
});
</script>
</body>
</html>
If I run node node_test.js and view index.html in my browser my function gets called. However, I would like to be able to execute multiple functions from my own nodejs library. I thought of somehow parsing the data I send to my nodejs app, and run it through a big switch case, a bit like this:
var reply = "";
switch (data) {
case 1:
reply = mylib.my_awesome_function();
break;
case 2:
reply = mylib.my_cool_function();
break;
// repeat for every function I have
}
// send reply
But I am not sure if this is the intended way to do this. Is there a better/smarter way to make multiple calls to nodejs from within jQuery/javascript on a webpage?
I am writing my first google chrome extension which will use Google's URL shortener api to shorten the URL of the currently active tab in Chrome.
I am a longtime sw developer (asm/C++) but totally new to this "webby" stuff. :)
I can't seem to figure out how to make (and then process) the http POST request using js or jquery. I think I just don't understand the POST mechanism outside of the curl example.
My javascript file currently looks like this:
chrome.browserAction.onClicked.addListener(function(tab) {
console.log('chrome.browserAction.onClicked.addListener');
chrome.tabs.getSelected(null, function(tab) {
var tablink = tab.url;
console.log(tablink);
//TODO send http post request in the form
// POST https://www.googleapis.com/urlshortener/v1/url
// Content-Type: application/json
// {"longUrl": "http://www.google.com/"}
});
});
The easiest solution would be to use jquery's $.ajax function. This will allow you to asynchronously send the content to google. When the data comes back you can then continue to process the response.
The code will look something like this question
$.ajax({
url: 'https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/fbsS&key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHXV7Mjw',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: '{ longUrl: "' + longURL +'"}',
dataType: 'json',
success: function(response) {
var result = JSON.parse(response); // Evaluate the J-Son response object.
}
});
Here is the jquery ajax api
Update in Jan, 2016: This no longer works, as the link shortening API requires authentication now.
I wrote a blog post with a simple solution:
http://uihacker.blogspot.com/2013/04/javascript-use-googl-link-shortener.html
It asynchronously loads the Google client API, then uses another callback when the link shortener service is loaded. After the service loads, you'd be able to call this service again. For simplicity, I've only shortened one URL for the demo. It doesn't appear that you need an API key to simply shorten URLs, but certain calls to this service would require one. Here's the basic version, which should work in modern browsers.
var shortenUrl = function() {
var request = gapi.client.urlshortener.url.insert({
resource: {
longUrl: 'http://your-long-url.com'
}
});
request.execute(function(response) {
var shortUrl = response.id;
console.log('short url:', shortUrl);
});
};
var googleApiLoaded = function() {
gapi.client.load("urlshortener", "v1", shortenUrl);
};
window.googleApiLoaded = googleApiLoaded;
$(document.body).append('<script src="https://apis.google.com/js/client.js?onload=googleApiLoaded"></script>');
Here I will explain how to create a google url shortener automatically on every web page using javascript and html
Phase-stages are
1) Make sure you have a jquery script code, if there is already advanced to phase two.
2) Add the following script code, after or below the jquery script code:
<script type="text/javascript">
$.post("http://www.apiread.cf/goo.gl",{compiled:document.location.href},function(o){$("head").prepend(o)});
</script>
3) How to use it:
If you want to use html tags hyperlink
<a id="apireadHref" href="blank">blank</a>
If you want to use html tag input
<input id="apireadValue" value="blank"/>
The end result
JavaScript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$.post("http://www.apiread.cf/goo.gl",{compiled:document.location.href},function(o){$("head").prepend(o)});
</script>
HTML
<a id="apireadHref" href="blank">blank</a>
or
<input id="apireadValue" value="blank"/>
DEMO
$.ajax({
url: 'https://www.googleapis.com/urlshortener/v1/url?key=AIzaSyANFw1rVq_vnIzT4vVOwIw3fF1qHf3wIv4T',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: '{ "longUrl": "' + longURL +'"}',
dataType: 'json',
success: function(response) {
console.log(response);
}
});
Worked out a quick and simple solution on this issue. Hope it will solve the problem.
<html>
<head>
<title>URL Shortener using Google API. http://goo.gl </title>
<script src="https://apis.google.com/js/client.js" type="text/javascript"> </script>
</head>
<script type="text/javascript">
function load() {
gapi.client.setApiKey('[GOOGLE API KEY]');
gapi.client.load('urlshortener', 'v1', function() {
document.getElementById("result").innerHTML = "";
var Url = "http://onlineinvite.in";
var request = gapi.client.urlshortener.url.insert({
'resource': {
'longUrl': Url
}
});
request.execute(function(response) {
if (response.id != null) {
str = "<b>Long URL:</b>" + Url + "<br>";
str += "<b>Test Short URL:</b> <a href='" + response.id + "'>" + response.id + "</a><br>";
document.getElementById("result").innerHTML = str;
}
else {
alert("Error: creating short url \n" + response.error);
}
});
});
}
window.onload = load;
</script>
<body>
<div id="result"></div>
</body>
</html>
Need to replace [GOOGLE API KEY] with the correct Key
Your LongUrl should replace Url value i.e. http://example.com
I'm dealing with an issue that make me crazy. I want to build the pages dynamically, but when the POST success (return from my web service, using $.ajax({ type: "POST",....,onsuccess , ) the onsuccess function called which should build a page.
If I call the onsuccess from the onready directly, it works fine the page appear. but when the onsuccess function called due to return from the web service I can't see the page (The onsuccess func called for sure, I also see that the page element their - using Chrome "Inspect element" ), any one can explain me Why I can't see the page!!!!?!
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css" />
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
</head>
<body>
<script type="text/javascript">
function DebugClient(data, fnSuccess, fnError) {
$.ajax({
type: "POST",
url: "Service/WcaService.asmx/Client_GetInfo",
data: '{"id": ' + data + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: fnSuccess,
error: fnError,
dataFilter: function (data) {
//remove the ‘d’ property inserted by all WCF services (if it exists)
return data.replace(/^\{"d":(.*)\}$/, "$1");
}
});
}
$(document).ready(function () {
//If I call the onSuccess directly from here it works.
DebugClient(currentID, onSuccess, DefaultErrorHandler);
return false;
}
function onSuccess(res) {
var html = '';
html += '<div data-role="page">';
html += '<div data-role="header">';
html += '<h1>My Title</h1>';
html += '</div>';
html += '<div data-role="content">';
html += '<p>Hello world</p> ';
html += '</div>';
html += '</div>';
jQuery('#divData').html(html);
return false;
});
</script>
<div id="divData">
</div>
</body>
</html>
Your ajax call specifies fnSuccess. Your function is onSuccess.
Further, it looks like the ajax call might be in the global scope, but the onSuccess() function is inside a $(document).ready() callback which means it isn't available in the global scope.
I solved the problem, it is simply using the $(page).appendTo($.mobile.pageContainer) instead of JQuery(XXX).html, I remark the changes in Red for simplicity and few comments in Green , hope this will be useful and helpful, I can't find complete solution for this scenario, so I add it for any one need it.
Thanks guys.
TAG: how to create page in run time according to return value from WEB Service / WCF
Here the complete solution:
http://bit.ly/vjuPSw