Periodically autosave form - javascript

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

Related

How to refresh a specific part of the HTML Document with Vanilla JavaScript

I am working on an AJAX cart system where the sub total will automatically update when the quantity changes. My solution is every time the input changes, post it to the current page (cart page) then reload the div that displays the sub total. However, I don't know how to do this with pure JavaScript, and I haven't found any reference yet.
This is my function for the above algorithm:
var _rangeInput = document.querySelectorAll('.ranum'), _upAload = document.getElementsByClassName('upAload');
var _frmData = {};
for (var i = 0; i < _rangeInput.length; i ++) {
_rangeInput[i].addEventListener('change', function(){
_frmData[this.name] = this.value;
ajaxFormValidate({
type: 'POST',
url: location.href,
method: true,
sendItem: _frmData,
success: function(response) {
//reload here
}
});
}, false);
}
Code explaination:
First, get the inputs and divs that need to be processed.
Loop through all of the inputs and get their values and names.
I have written an AJAX function for my self, you can look above.
Is there anyway to do this with pure JavaScript?
I can't use JavaScript methods or functions to change the content since I am sending the request to the same page, as a result, response here will have the value of the whole document.
Also, this is how the system works:
First, the user changes the quantity they want
AJAX sends request to the same page
The page changes the information based on the request
AJAX receives the request, and refreshes/reloads the specific div
Simply set the innerHTML of your sub total div with the response data.
document.getElementById("sub-total").innerHTML = response.value; //Whatever value you get in response
It sounds like you're actually asking how to get a single element out of an AJAX response.
You can do that by parsing the response into a temporary element, then finding the element you need within it:
const holder = document.createElement('div');
holder.innerHTML = response;
const myElement = holder.querySelector('some selector');

Store form input data without posting form

I was wondering, we have this front-end delivered by a third party. They made the design implemented this in a PHP website (Symphony based, irrelevant to my issue I believe).
The problem is, they used a lot of Javascript, which is nice for the dynamic parts. However when submitting the form, the data is being transferred through jQuery $.ajax or post too. Meaning the client side will never store the user's input for future use, which is actually something they'll want since this front end is designed for re-use ever x weeks or per month.
Anyone know if there is a way to make the form behave like if it's being posted?
As addition, the user is NOT logged in, and there could be multiple users allthough it's likely it's his private system, or shared at home. High chance it'll even be a mobile device.
You need to use cookies to save the form data, preferably after the submit. I like to use jquery.cookie when working with stuff like this. I would do something like this. This will only work on a single browser.
$( document ).ready(function() {
// Fetch the submit_form_input cookie that was set after submitting the form
var submit_form_input = JSON.parse($.cookie("submit_form_input"));
// Loop through the values inside the cookie
for (i = 0; i < submit_form_input.length; i++) {
// Find the form with the correct id and set the value on it
$("#" + submit_form_input[i].name).val(submit_form_input[i].value);
}
$("#submit_form").submit(function(ev) {
ev.preventDefault();
var url = $(this).attr('action');
var data = JSON.stringify($(this).serializeArray());
$.ajax({
type: "POST",
url: url,
data: $(this).serialize(), // serializes the form's elements.
success: function(response)
{
// Set the cookie
$.cookie("submit_form_input", data);
alert('Thank you for submitting the form.');
}
});
});
});
Here is a JSFiddle.

Updating total number on website with jQuery / Javascript?

This below is displaying Total racers on my website but its not updating live. I need to referesh the page to grab the new number from the database, so what's the simple way of updating it live with jquery/javascript without refreshing the page? Thanks a lot for taking the time to check my question and possibly answer.
<div id="stats">
<div id="racers">
<span><?=number_format($racers, 0, ' ', ' ')?></span>
RACERS
</div>
</div>
Jquery Ajax:
$.post('page.php', {
postVariable : value
}, function(data) {
//do something with data retrieved from php script
});
You set 'page.php' to a script that gets the data you want and echoes it.
You then retrieve what was echoed in the callback function(data);
So data will be the variable containing the value you need. You put this script in a
javascript function and call it when you need to make a request for information on the back-end.
If you have questions let me know. If you need more information on the ajax request you can find it here as well: api.jquery.com/jquery.post/
What you need to do this is the following:
1. Have an action in a controller that outputs the total number of racers
For example:
class Data extends CI_Controller {
public function GetTotalRacers() {
// This is dummy data. You need to replace this code with the correct
// number of racers retrieved from the database
echo 14;
}
}
Take note of where this action is. I'm assuming codeigniter will make the path something like /Data/GetTotalRacers in this case (that depends on how your route rules are configured).
2. Use JavaScript to ask the server for the data and display the result on the page
I recommend you have a method that runs every X number of seconds to refresh the total number of racers. To achieve this, you can use setInterval. Within the setInterval's function have an ajax call to your action. Finally, display the value that's returned from the server:
setInterval(function() {
$.ajax({
// Replace the url value with the correct url to access your action
url: '/Data/GetTotalRacers',
cache: false
})
.done(function( totalRacers ) {
$("#racers span").text(totalRacers);
});
}, 60000); // ex. Update every 60000ms
Note: I've never used codeigniter, but hopefully this description will help set you on the right path.

How to pass variables from an HTTPObject

I'm very, very new to Javascript, and to web programming in general. I think that I'm misunderstanding something fundamental, but I've been unable to figure out what.
I have the following code:
function checkUserAuth(){
var userAuthHttpObject = new XMLHttpRequest();
var url = baseURL + "/userAuth";
userAuthHttpObject.open("POST",url,true);
userAuthHttpObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
userAuthHttpObject.onload=function(){
if (userAuthHttpObject.readyState == 4) {
var response = json.loads(userAuthHttpObject.responseText);
return response; //This is the part that doesn't work!
}
};
userAuthHttpObject.send(params);
}
I would love to call it from my page with something like:
var authResponse = checkUserAuth();
And then just do what I want with that data.
Returning a variable, however, just returns it to the userAuthObject, and not all the way back to the function that was originally called.
Is there a way to get the data out of the HttpObject, and into the page that called the function?
Working with AJAX requires wrapping your head around asynchronous behavior, which is different than other types of programming. Rather than returning values directly, you want to set up a callback function.
Create another JavaScript function which accepts the AJAX response as a parameter. This function, let's call it "takeAction(response)", should do whatever it needs to, perhaps print a failure message or set a value in a hidden field and submit a form, whatever.
then where you have "return response" put "takeAction(response)".
So now, takeAction will do whatever it was you would have done after you called "var authResponse = checkUserAuth();"
There are a couple of best practices you should start with before you continue to write the script you asked about
XMLHTTTPRequest() is not browser consistent. I would recommend you use a library such as mootools or the excellent jquery.ajax as a starting point. it easier to implement and works more consistently. http://api.jquery.com/jQuery.ajax/
content type is important. You will have have problems trying to parse json data if you used a form content type. use "application/json" if you want to use json.
true user authorization should be done on the server, never in the browser. I'm not sure how you are using this script, but I suggest you may want to reconsider.
Preliminaries out of the way, Here is one way I would get information from an ajax call into the page with jquery:
$.ajax({
//get an html chunk
url: 'ajax/test.html',
// do something with the html chunk
success: function(htmlData) {
//replace the content of <div id="auth">
$('#auth').html(htmlData);
//replace content of #auth with only the data in #message from
//the data we recieved in our ajax call
$('#auth').html( function() {
return $(htmlData).find('#message').text();
});
}
});

How can delete Ajax Request from browser memory?

I have a simple problem, how can I delete the ajax request store into the memory. I'll try to explain what I'm will trying to get.
I have a form for edit a table into database.
All runs well the first time, but the problem is after trying again. If I don't refresh the page, it always sent the same data from the first request.
Example:
Into database I have
id
user
password
I have a form with the same parameters, and I called this form with ajax.
I edited a register from the database, and I sent the data edited, and run well, but into the browser memory, the request is stored.
I try to edit again the same register, but when I send again, the data is the same like the first time.
If the first time send:
user : 'userx'
password : 'usex1234'
When I try again to edit this register for example with:
user: 'userxx'
password : 'password1234'
at the end, the data send has these values
user : 'userx'
password : 'usex1234'
How can fix this? I suppose delete the first request, but I can't.
I want to clean the memory from browser without f5 or refreshing, because only with f5, running again well.
I tried:
request = new Request();
request = null; but not happens nothing
delete request; but is the same, nothing changes.
Who can help me please?
MY CODE:
function _update(id){
var n = Number(new Date());
var edit = new Request({
url: 'users/edit?'+new Date().getTime(),
noCache: true,
onRequest: function(){
$('dark').setStyle('display','block');
},
onSuccess: function(data){
$('dark').setStyle('display','none');
box_edit.close();
update();
},
onComplete: function(response){
console.log(response);
},
onFailure: function(){
Sexy.error("Ocurrio un error procesando su solicitud, intente más tarde.");
}
});
var box_edit = new LightFace.Request({
url: 'users/edit?'+new Date().getTime(),
draggable:true,
title: 'Editar usuario.',
request:{
method: 'post',
data: { isc_user_id: id }
},
buttons: [ { title: 'Editar', color:'blue', event: function(){
var id__ = $('isc_user_frm_id_'+id).get('value');
if (before_update(id__)){
if ( $('isc_password_'+id__).get('value')=='' && $('isc_re-password_'+id__).get('value')==''){
var data = 'userEdit=Ok&isc_user='+$('isc_user_'+id__).get('value')+'&isc_group='+$('isc_group_'+id__).getSelected().get('name')+'&isc_user_id='+ id;
}else{
var data = 'userEdit=Ok&isc_user='+$('isc_user_'+id__).get('value')+'&isc_password='+hex_md5($('isc_password_'+id__).get('value'))+'&isc_group='+$('isc_group_'+id__).getSelected().get('name')+'&isc_user_id='+ id;
}
edit.send(data);
}
}
},
{ title:'Cancelar', event:function(){ this.close(); } }]
});
box_edit.open();}
The simplest solution, as your server-side should be stateless, and the variables shouldn't be cached to send to the server, so the problem is probably with how you are getting the values.
The browser may cache when it requests information from the server, which is why it was suggested to turn off caching, but that is for data coming from the server.
So, I would suggest you use the Firebug extension on Firefox and you can put in breakpoints to see if the values are changing.
For every part of setting data you should put these in variables so you can check each value easily.
I didn't create all the variables, but I wanted to show an example to help you.
var val1 = $('isc_user_'+id__).get('value');
var val2 = $('isc_password_'+id__).get('value');
var data = 'userEdit=Ok&isc_user='+$('isc_user_'+id__).get('value')+'&isc_password='+hex_md5($('isc_password_'+id__).get('value'))+'&isc_group='+$('isc_group_'+id__).getSelected().get('name')+'&isc_user_id='+ id;
You will also want to look at the value of id as you may not be appropriately changing that value when the password is changed. I expect this will be your problem.
Append a string like e.g. a timestamp to the requested url, this prevents the browser from using the cached version of the requested ressource.
In mootools there is a noCache-option for Request, set it to true.(default is false, so the cache will be used there without setting the option)
The OP wrote:
FIX
Ok, after tring a lot of ways to fix, I found a solution, which consist of creating a dynamic form. I created a random variable and sent just before to get the form with ajax, after recovery this value into the server code, I put this value like a name of the form and I have a dynamic form. With this I fixed the problem.
Example
function rand(){
return Math.floor(Math.random()*1000);
}
function _update(id){
var form_rand = rand();
...
data: { isc_user_id: id , form_rand : form_rand }
...
To get the value now:
var id__ = $('isc_user_frm_id_'+id+form_rand).get('value');
Into the html I have and hidden input like this:
<input type="hidden" id="isc_user_frm_id_<?php echo $form_rand; ?>" value="<?php echo $r; ?>" ?>

Categories