I'm new to working with PHP and I am in need of some help. I am currently working on setting up a test using Dreamweaver so that users can log in, then go to the question page, and from there go to a page with a form to answer that question. I had the host up the garbage collection time from 24 minutes to 240, so that the user won't be timed out while working on the reply. I would like install a fail safe so they won't lose all their work. I found an auto-save code on http://jetlogs.org/2007/11/11/auto-saving-with-jquery/
I've been playing around with the code supplied from there, but so far no luck. Does anyone have any advice or is familiar at all with auto-saving with php? I appreciate any help, thanks.

Post your code and I'll give you a hand. The auto-saving is easy to do, and there is no reason to use jQuery, if this is all you want to do. Note: I have not used jQuery myself in any significant way (nor Dreamweaver, for that matter), but I have written many scripts that implement various levels of auto-save functionality.

(Nor do you even need PHP to do specifically what you're asking. Using JavaScript, you can auto-save a cookie in the browser that will store the value, then send it across the wire when the user hits submit. I think it's a more elegant solution, but it would require little more coding (but not much)).

here you go

edit: code does NOT save to a cookie, btw

<?PHP
/******************************************************************************
To be able to run this sample code, you need to have the mysql database 
and insert a dummy record:

    CREATE DATABASE autosave;
    
    CREATE TABLE asave(
      user_id INT,
      saved_text TEXT
    );
    
    INSERT INTO asave(user_id, saved_text) VALUES (1, '');

******************************************************************************/

//replace with your user/pass to get a connection to your database
$db = mysql_connect("localhost:3306", "****" , "****");
mysql_select_db("autosave",$db) or die(mysql_error());

//your user_id is probably stored in your session...just replace
$user_id = 1;                                             

if($_SERVER["REQUEST_METHOD"]=="POST"){
    
    // Make sure you escape your saved data as you need it 
    // It is not done here, in the interest of brevity     
    
    $saved_text = mysql_real_escape_string($_POST["saved_text"]); 

    // Assume an entry in the DB table exists for this user.                        
    
    $sql = "UPDATE asave SET saved_text = '".$saved_text."' ";    
    $sql.= "WHERE user_id = $user_id";                            
    
    mysql_query($sql) or die(mysql_error().$sql);           

    echo "Your data has been saved ".date("h:m:s A");   
    exit;                                                   
}
//else implied by exit

// Get saved_text from the DB to display in the textarea

$sql = "SELECT saved_text FROM asave WHERE user_id = $user_id";
$rs = mysql_query($sql) or die(mysql_error().$sql);       
$arr = mysql_fetch_array($rs);
$saved_text = $arr["saved_text"];
?>
<html>
    <head>
    <script type="text/javascript">
        function init(){
            window.setInterval(autoSave,10000);                  // 10 seconds
        }
        function autoSave(){
            
            var saved_text = document.getElementById("saved_text").value;
            
            var params = "saved_text="+saved_text;
            var http = getHTTPObject();
            http.onreadystatechange = function(){
                if(http.readyState==4 && http.status==200){
                    msg = document.getElementById("msg");
                    msg.innerHTML = "<span onclick='this.style.display=\"none\";'>"+http.responseText+" (<u>close</u>)</span>";
                }
            };
            http.open("POST", window.location.href, true);
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            http.setRequestHeader("Content-length", params.length);
            http.setRequestHeader("Connection", "close");
            http.send(params);
        }
        
        //cross-browser xmlHTTP getter
        function getHTTPObject() { 
            var xmlhttp; 
            /*@cc_on 
            @if (@_jscript_version >= 5) 
                try { 
                    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
                } 
                catch (e) { 
                    try { 
                        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
                    } 
                    catch (E) { 
                        xmlhttp = false; 
                    } 
                } 
            @else 
                xmlhttp = false; 
            @end @*/  
            
            if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { 
                try {   
                    xmlhttp = new XMLHttpRequest(); 
                } catch (e) { 
                    xmlhttp = false; 
                } 
            } 
            
            return xmlhttp;
        }
    </script>
    </head>
    <body onload="init();">
        <span id="msg" style="cursor:pointer;"></span>
        <form method="POST">
            <textarea id="saved_text" name="saved_text" rows="10" cols="100"><?PHP echo $saved_text;?></textarea>
            <br/>
            <input type="submit" value="save now" />
        </form>
    </body>
</html>

After doing some searching around forums some code I found that might work was
<script>
// auto-save the draft every 5 minutes
setInterval( "rcmail.command('savedraft','',null)", 5*60*60*1000 );
</script>

although I would have to change the "rcmail.command" portion to something that would fit my current project. And is there any way I could install a timer so that the user could see how much time remains on their session? Thanks for the help.

After doing some searching around forums some code I found that might work was
<script>
// auto-save the draft every 5 minutes
setInterval( "rcmail.command('savedraft','',null)", 5*60*60*1000 );
</script>

5 * 60 * 60 * 1000 ms == 5 HOURs, not 5 minutes.

But, that is essentially it.

1. Write the code that does the saving, 2. Call that code every 30 seconds (or whatever).

And is there any way I could install a timer so that the user could see how much time remains on their session? Thanks for the help.

Do something similar as above.

Write a function that will use DHTML to decrement a visible timer and call that function every second.

<html><head><script>
var spanCounter = "";           // HTML elem that shows counter's value
var counter;                    // An integer that just decrements
var saveInterval = -1;          // Auto-save frequency

function init(si){
    spanCounter = document.getElementById("spanCounter");

    saveInterval = si;
    spanCounter.innerHTML = si;
    counter = si;          
    
    setInterval(countDown, 1000);  // once a second 
}
function countDown(){

    if(counter == -1){
        counter = saveInterval; // reset the counter 
        //autoSave();           // or whatever your function is named
    }

    spanCounter.innerHTML = (counter--);  // decrement counter, and paint    
}
</script></head>
<body onload="init(5);">
<span id="spanCounter"><span>
</body>
</html>
mysql_query($sql) or die(mysql_error().$sql);           

    echo "Your data has been saved ".date("h:m:s A");   
    exit;                                                   
}
//else implied by exit

// Get saved_text from the DB to display in the textarea

$sql = "SELECT saved_text FROM asave WHERE user_id = $user_id";
$rs = mysql_query($sql) or die(mysql_error().$sql);       
$arr = mysql_fetch_array($rs);
$saved_text = $arr["saved_text"];
?>
<html>
    <head>
    <script type="text/javascript">
        function init(){
            window.setInterval(autoSave,10000);                  // 10 seconds
        }
        function autoSave(){

            var saved_text = document.getElementById("saved_text").value;

            var params = "saved_text="+saved_text;
            var http = getHTTPObject();
            http.onreadystatechange = function(){
                if(http.readyState==4 && http.status==200){
                    msg = document.getElementById("msg");
                    msg.innerHTML = "<span onclick='this.style.display=\"none\";'>"+http.responseText+" (<u>close</u>)</span>";
                }
            };
            http.open("POST", window.location.href, true);
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            http.setRequestHeader("Content-length", params.length);
            http.setRequestHeader("Connection", "close");
            http.send(params);
        }

        //cross-browser xmlHTTP getter
        function getHTTPObject() { 
            var xmlhttp; 
            /*@cc_on 
            @if (@_jscript_version >= 5) 
                try { 
                    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
                } 
                catch (e) { 
                    try { 
                        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
                    } 
                    catch (E) { 
                        xmlhttp = false; 
                    } 
                } 
            @else 
                xmlhttp = false; 
            @end @*/  

            if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { 
                try {   
                    xmlhttp = new XMLHttpRequest(); 
                } catch (e) { 
                    xmlhttp = false; 
                } 
            } 

            return xmlhttp;
        }
    </script>
    </head>
    <body onload="init();">
        <span id="msg" style="cursor:pointer;"></span>
        <form method="POST">
            <textarea id="saved_text" name="saved_text" rows="10" cols="100"><?PHP echo $saved_text;?></textarea>
            <br/>
            <input type="submit" value="save now" />
        </form>
    </body>
</html>

Thanks for all your help so far! One problem that keeps occurring is that the autosave function only appears to work when I hit "save". I refresh the database and the text will be there, but only when save has been hit. If I was to remove the button, hypothetically the function would still work. Do you have any insight on why this is happening? Thanks.

Replace:

http.onreadystatechange = function(){
    if(http.readyState==4 && http.status==200){
        msg = document.getElementById("msg");
        msg.innerHTML = "<span onclick='this.style.display=\"none\";'>"+http.responseText+" (<u>close</u>)</span>";
    }
};

with:

http.onreadystatechange = function(){
    if(http.readyState==4){
        if(http.status!=200){ // 200 = HTTP OK
            alert(http.responseText);
        }else{
            msg = document.getElementById("msg");
            msg.innerHTML = "<span onclick='this.style.display=\"none\";'>"+http.responseText+" (<u>close</u>)</span>";
        }
    }
};

That should give you a good start of where to look. Anyway I can execute your code over the Internet?

One problem that keeps occurring is that the autosave function only appears to work when I hit "save". I refresh the database and the text will be there, but only when save has been hit. If I was to remove the button, hypothetically the function would still work. Do you have any insight on why this is happening? Thanks.

Yes, you could remove the button, and it should still work. As you can see, there is an AJAX POST every 10 seconds (i.e., the auto-save), and there is a regular HTML form that POSTs the data when submitted.

Hopefully the code I posted above this will let you know where the problem is. The code works on my setup, so I'll have to get some specific environment info from you, as well as any pertinent error messages.

Also, if you're not using Firefox w/ the Firebug extension (or Web Developer Toolbar), I highly recommend them. These tools help a lot when it comes to debugging javascript.

Hi bill mac,

Your info is very helpfull for me , could you please help me to use this autosave feature for multiple textarea.

Thanks

Here is the PHP and AJAX script for autosaving

date_default_timezone_set('Asia/Kolkata'); //you can add your own timezone
$host = 'localhost';
$user = 'your_db_username';
$pass = 'your_db_password';
$db = 'autosave';
$conn = new mysqli($host, $user, $pass, $db);
function insertPost($title,$content, $conn){
  $sql = "INSERT INTO post VALUES(null, ?, ?)";
  $stmt = $conn->stmt_init();
  if($stmt->prepare($sql)){
    $stmt->bind_param('ss',$title,$content);
    if($stmt->execute()){
      echo $conn->insert_id;
    }
  }}

function updatePost($title,$content,$id, $conn){
  $sql = "UPDATE post SET title = ?, content = ? WHERE id = ?";
  $stmt = $conn->stmt_init();
  if($stmt->prepare($sql)){
    $stmt->bind_param('ssi',$title,$content,$id);
    if($stmt->execute()){
      echo "<i>Draft Saved at ".date("h:i:s a")."</i>";
    }
  }}
if(isset($_GET['save'])){
  $title = $_POST['title'];
  $content = $_POST['content'];
  $id = $_POST['id'];
  if($id != ''){
    updatePost($title, $content,$id, $conn);
  }
  else{
    insertPost($title, $content, $conn);
  }}
?>

AJAX Script

function getData(){
  var fd = new FormData();

  var title = document.getElementsByName('title')[0].value;
  var content = document.getElementsByName('content')[0].value;
  var id = document.getElementsByName('id')[0].value;
  fd.append('title',title);
  fd.append('content',content);
  fd.append('id',id);

  return fd;
}

function savePost(){
  try{
    var xhttp = new XMLHttpRequest();
  }
  catch(e){
    console.log(e);
  }
  var data = getData();
  xhttp.open('POST','autosave.php?save=true');
  xhttp.send(data);
  xhttp.onreadystatechange = function(){
    if(this.status == 200 && this.readyState == 4){
      if(data.get('id') == ""){
        document.getElementsByName('id')[0].value = this.responseText;
      }
      else{
        document.getElementById('message').innerHTML = this.responseText;
      }
      console.log(this.responseText);
    }
  }
}

setInterval(savePost,10000); //savePost will be called in every 10 seconds

Code found at: Data Autosave System using PHP, MySQL and AJAX

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.