Create a reusable function to open and send Ajax - javascript

I have noted that in my program every time when I want to declare a object, for example list, save, add, remove I write the following every time in each function.
ajax.open("Get", "./route/action",true);
ajax.send();
I want to do something like this.
//this.ajax.get('./route/action').update('ajax-content');
./route/action // this is path to my Action class-using servlet
Every time I have to open a connection, give the path to my action class which is a servlet and then send. I do this every time I want to load a list, delete or update.
How can I write a function that I will be just be:
this.ajax.get('./route/action');
// 'ajax.content' is the id of the div where I
// want to show the list,where after updating AJAX show the update list to the user.
update('ajax-content');
For example after adding a user I can see the added user without reloading the whole page. I am working on a maven project using Java EE, Servlet and JavaScript.

Try this:
function ajaxRequest(AJAXurl, callbackElementID){
x = new XMLHttpRequest();
x.open("get", AJAXurl, true);
x.onreadystatechange = function() {
if (x.readyState == 4 && x.status == 200) {
document.getElementById(callbackElementID).innerHTML = x.responseText; //Will send the received data to the element passed in the function
}
};
x.send();
}
Use as following:
ajaxRequest("/somefile.php", "elementID"); //This will send recieved data to the element with "elementID" as id
Note: The way this is built is only for GET requests. Change code if you want POST request.

Related

How to store PHP/MySQL variables in Javascript file?

I need to load some markers into an embedded Google Map based on what a user searches. The markers are determined by lng/lat coordinates in a MySQL table.
The map is created in a Javascript function in a separate Javascript file (so not embedded in the HTML) and it takes an XML file as input. I created a PHP page (called 'xml.php') that can dynamically generate the XML file I need based on whatever the user searchers. Right now I'm manually typing in POST information in my Javascript function, so it calls 'xml.php?query=hello'
I'd like to somehow send the original query to the Javascript file, so that I can append it to the end of 'xml.php'. This way, everything is done automatically from the original search, to generating an xml file, and reading it to create markers.
I've seen solutions that are fairly simple when the Javascript is embedded in tags but I'm trying to avoid that
Here's my function that calls for an XML file:
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
The XML information will change based on what the user originally searched though. So it's actually a php file (xml.php) that performs an SQL search and echos it out in XML format. I can control the SQL search by adding POST info when calling xml.php
downloadURL('xml.php?query=whatever', somefunction())
But that appended POST data needs to be dynamic too.
So the overall flow is:
Search page --> Sends data to results page, which calls on Javascript file to create map --> Javascript file calls on XML information to put map in results page
Could show us some code?
have you tried localstorage?
// Store
localStorage.setItem("lastname", "Smith");
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
You can use this to set some information and then, call the post method using ajax.
but It is only useful if you want to keep some data in session.
references: [1] and [2]

Use URL to jump to a page in AJAX

My website structure is as follows:
public_html/
- index.php
- students.php
The user loads the site (index.php) which contains a button. When this button is clicked AJAX is used to load "students.php" and it is displayed to the user (As if they just went to a different page seamlessly). When doing so the following JavaScript is run:
var state = {'Page' : 'Students'};
history.pushState(state, null, "students");
This adds a state to the browsers history and causes the browsers URL to display "example.com/students" instead of "example.com". However if a user was to refresh at this point, nothing would load (404 Not Found) due to the folder "students" not actually existing.
My question is, how can I get the users browser to actually display "index.php" and automatically take them to the students page. In other words, the user refreshes "example.com/students" and what actually happens is the user is taken to the index.php file and the AJAX automatically takes them to the students page (As though they actually refreshed the page)
Note: I am aware I can pass null to the url parameter in "pushState()" however this URL behaviour is desired as it would allow users to quickly jump to a page (If I can get it working)
The full code to show the students page via AJAX is as follows:
/**
* Display students screen.
*/
function displayStudents(createState) {
if(typeof(createState)==='undefined') {
createState = true;
}
$("#container").css("width", $( window ).width());
$("#container").css("position", "fixed");
$("#container").animate({marginLeft: "-100%"}, ANIMATION_SPEED);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
$("#container").css("margin-left", "100%");
$("#container").html(xmlhttp.responseText);
$("#container").animate({marginLeft: "0"}, ANIMATION_SPEED, null, function reset() {
$("#container").css("width", "100%");
$("#container").css("position", "relative");
});
if(createState) {
var state = {'Page' : 'Students'};
history.pushState(state, null, "students");
}
}
};
xmlhttp.open("GET", "students.php", true);
setTimeout(function() { xmlhttp.send(); }, ANIMATION_SPEED);
}
Most of the code here is for animation.
In other words, the user refreshes "example.com/students" and what actually happens is the user is taken to the index.php file and the AJAX automatically takes them to the students page (As though they actually refreshed the page)
The point of pushState is that when you use JavaScript to transform the state of the page, you provide a URL which the server can use to deliver some HTML that will provide the page in that state.
If you are always going to serve up the homepage and then transform it with JavaScript, then just use hashbangs. pushState is entirely the wrong tool for the job.
If you were to use pushState, then a pseudocode implementation of a possible approach would be along the lines of:
GET data needed for the page
IF `Accept` header prefers `application/json`
Output `Content-Type: application/json` header
Output data in JSON format
ELSE
Output `Content-Type: text/html` header
Pass data through the template for the page
Output template as HTML
And you would use students.php in the URL instead of students (or you would make students resolve to the PHP code you wanted to run instead).
Since you are using raw XMLHttpRequest, you will need to use setRequestHeader to set the Accept header. You are using jQuery though, so you could just use $.ajax and pass it dataType: "json".

Javascript for Submitting HTML Form When Offline

I need a script that will store html form data locally on the device until the user is online and then submit the form via the html action. Is this possible? I'm a javascript novice so I'd love any help available.
I think this is doable. Here's how I would do it, though it may not be ideal.
Set your form up so that the submit action is handled by javascript. It should attempt to submit the form with something like an XMLHttpRequest or jQuery's ajax() function.
Set up callbacks for the submission request. On success, indicate this to the user or navigate to some new page, however you want to show the request was successful. On failure (any failure or use the result's status code to confirm that the user is unable to connect) you have two options.
One option is to do a setTimeout of some reasonable length and attempt your submit action again. If the user closes the page or navigates away, though, this will never complete.
Another option is to put the form data into an array of some sort and put it into the localStorage object. Then if they reload the page, you can see if that data exists. If it does, it can repopulate the form and prompt the user to attempt a new submission. If the submission is successful, empty the local storage.
The way I'd do it would be a combination of both. Here's some psuedocode.
//run this once document is ready
//our submitForm action
var submitForm = function() {
var url = "my_form_action.php";
var params = "foo=bar"; //set params to your form values here
localStorage.myFormData = params;
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
//Call a function when the state changes.
http.onreadystatechange = function() {
if(http.readyState == 4) {
if(http.status == 200) {
//call was completed successfully
//clear out our local storage
localStorage.myFormData = null;
//do whatever here! (tell the user it was successful, change pages, whatever)
//doStuff();
} else {
//call was unsuccessful (user is offline)
//attempt again in 10 seconds
window.setTimeout(submitForm, 10000);
}
}
}
http.send(params)
}
//on document ready, check if we have pending form data to send
//if we do, fill in our form and attempt to submit it
if(localStorage.myFormData) {
//my data exists
//fill the form back out using stuff like
//document.getElementById('FirstName').value = localStorage.myFormData.match(/(.+?)=(.+?)(?:&|$)/g)[1][1];
//you'll need to figure out how best to repopulate your form when the page loads, but do it here
//once form is repopulated, either submit it using the form.submit function or call our submitForm() function directly
submitForm();
}
I hope this makes sense. There's a lot of work involved in getting the above setup working, but it should work!

Is it possible sending one variable multiple time via POST using javascript?

Let me explain why I need to do this!
I need to send a request to another server that its format is something like this:
http://www.test.ccom/process?item=1AAA&item=2BBB&item=3CCC
This URL will add 3 different items (one of each) to the result page, like this:
Item = 1AAA Count=1
Item = 2BBB Count=1
Item = 3CCC Count=1
If I want to add just 3 of just one item, I should use this:
http://www.test.ccom/process?item=1AAA&item=1AAA&item=1AAA
And result page will be like this:
Item = 1AAA Count=3
My problem is that I can't send my request using GET method (because we want to add more than 100 per item and it will cause "Request-URI Too Large" error)
I used two different methods to send this request by POST, but without success.
First I used this function:
function post_by_form(path, params) {
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", path);
form.setAttribute("style", "display: none")
for(var key in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", "item");
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
document.body.appendChild(form);
form.submit();
}
It works when I test it with different variable names (name="item"+key), but it doesn't work when I use one variable name for all the inputs.
Then I used this function to send the POST request by ajax:
function post_by_ajax(path, params_arr){
var http = new XMLHttpRequest();
var url = path;
var params = "";
for(var key in params_arr) {
if (params != "")
params += "&item="+params_arr[key];
else
params += "item="+params_arr[key];
}
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
}
The same result, both of this methods will return just one quantity for just one item (last one)... While we can submit a form with many input fields all with the same name, why I can not do it using these methods?! Do I have any problem in the logic?! can somebody please help me?!
Using Firefox with the TamperData plugin, and a form that simply has four fields all specified as <input type="text" name="item"> I can see that the POST data does indeed send four variables all named "item" but with different values for each.
It is then up to the receiving server to do something sensible with that. Most systems will just use one of the four values sent (maybe the first one, or the last one) but if there's already a server that correctly handles http://www.test.ccom/process?item=1AAA&item=1AAA&item=1AAA then your adding multiple fields all named "item" should work.
If that's not the case, then you need to write something to handle that on the server end of things - no amount of javascript coding will do it. That would involve getting the whole POST body and processing it yourself, as most server-side frameworks (like I said) will generally just use one of the values.
You can use TamperData or something similar to capture the HTTP data stream and see what is actually transmitted from the javascript you have now.
So ultimately, the answer to your question "Is it possible sending one variable multiple time via POST using javascript?" is yes, it is possible.
If you're passing all variables with the same name i.e.: 'item' then the request handler has no way to differentiate between them. That is why you're getting only 1 element. Try renaming the elements to item1=value&item2=value&item3=value.
If you're passing 100 elements then you should definitely be using the post method. The name problem will exist for both post and get so make sure that all the items are named differently.

Periodically autosave form

How to implement a periodical save of a form in the background? Same kinda thing that gmail does.
setInterval(function(){
var form = $('#my-form-id');
var method = form.attr('method').toLowerCase(); // "get" or "post"
var action = form.attr('action'); // url to submit to
$[method](action, form.serialize(), function(data){
// Do something with the server response data
// Or at least let the user know it saved
});
},10000); // do it every 10 seconds
If you don't want to use the method of the form, but always want to use 'post', then use:
$.post(action, form.serialize(), ... );
And, if you want to supply your own action for the autosave that is different from the action for the actual save:
$.post("/autosave/comments", form.serialize(), ... );
You would need a timed loop on the client side that would save the form every x seconds/minutes. A crude way of doing this would be to have a setTimeout javascript function that collects the form's field values and updates the model via an update (PUT in Rails' case) AJAX request.
Example
Here's a crude way of doing it (i.e. there might be a better way):
// repeat every 10 seconds
var repeatTime = 10 * 1000;
function updateModel(){
// get field values (using jQuery, etc.)
// make ajax request using these field values
//(make sure put parameters match model attribute names)
console.log('updated');
setTimeout(updateModel, repeatTime); // start call over again
}
setTimeout(updateModel, repeatTime);
I included the console.log so that you can test this out in Firebug right now and see that the updateModel executes every 10 seconds. I would recommend using jQuery to generate the PUT AJAX requests.
Why not do this purely on the client, using a local database (or whatever)? That should reduce complexity, server load and bandwidth usage.
Permanent or per-session storage -- whatever's appropriate -- and you can save after every keystroke: no need for setTimeout().
Sisyphus.js: Gmail-like client-side drafts and bit more. Plugin developed to save html forms data to LocalStorage to restore them after browser crashes, tabs closings and other disasters.
http://sisyphus-js.herokuapp.com
Smashing Magazine article: http://coding.smashingmagazine.com/2011/12/05/sisyphus-js-client-side-drafts-and-more/
Version that works without jquery:
function urlencodeFormData(fd) {
var s = '';
function encode(s) { return encodeURIComponent(s).replace(/%20/g,'+'); }
for (var pair of fd.entries()) {
if(typeof pair[1]=='string') {
s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
}
}
return s;
}
setInterval(function() {
var form = document.getElementById('my-form-id');
var request = new XMLHttpRequest();
request.open(form.method, form.action);
request.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
request.send(urlencodeFormData(new FormData(form)));
}, 10000);
If you need to do something with the server response see this post: https://blog.garstasio.com/you-dont-need-jquery/ajax/#posting

Categories