Jump to content

Prevent people from adding item twice


clausowitz

Recommended Posts

Hi All,

 

not sure if this is a php Q but maybe someone has experience with this.

I use a form for people to add an item to the bulletin board. Sometimes the loading of the page takes very long and people think it didn't work so they click reload and post the item twice. I thought of adding a loading.gif so people know they have to wait. Anyone know how and where to put that in?

<?PHP
   if(isset($_POST['submit']))
   {

  if ($_POST['type']<>"") {  

  $poster_id = $_SESSION['id'];
  $ID=$_GET['ID'];
  $short=$_POST['short'];
  $location=$_POST['location'];
	  if(isset($_POST['type'])) {
		  $type=$_POST['type']; }
  $starthour=$_POST['starthour'];
  $startmin=$_POST['startmin'];
  $endhour=$_POST['endhour'];
  $endmin=$_POST['endmin'];
  $reminders=$_POST['reminders'];
      $reminders=addslashes($reminders);
  if(isset($_POST['view'])) {
  	$view=$_POST['view']; }
  if(isset($_POST['val'])) {
	$val=$_POST['val']; }
  
  $sql = mysql_query("SELECT * from bl_calender where dateclass='$ID' AND viewable='1'");
  $numrows = mysql_num_rows($sql);
		// if the event exists then we want to edit it
	if ($numrows > 0){
		// only the owner can edit an event
		while($row = mysql_fetch_array($sql)){
			if($row['poster_id'] == $logOptions_id || $account_type == 'c' ){

		      $editcal="update bl_calender set datecotent='$reminders', location='$location', type='$type', starthour='$starthour', startmin='$startmin', endhour='$endhour', endmin='$endmin', short='$short', viewable='$view' where dateclass='$ID'";
		      mysql_query($editcal) or die("Could not edit calendar");
	          $msgToUser = '<br /><br /><font color="#FF0000">Your event has been updated. Close this window.</font><p></p>';
			    include_once 'msgToUser2.php';
			} else {  // you are not the owner
				$msgToUser = '<br /><br /><font color="#FF0000">Sorry but only the owner can change the event details.<br> Close this window.</font><p></p>';
			    include_once 'msgToUser2.php';
				   }

			         }

}  else {      // it's a new event we want to add

         $createevent="Insert into bl_calender (poster_id, dateclass, starthour, startmin, endhour, endmin, location, type, short, datecotent, viewable ) values ('$poster_id', '$ID', '$starthour', '$startmin',  '$endhour', '$endmin', '$location', '$type', '$short', '$reminders', '1')";
         mysql_query($createevent) or die(mysql_error());

$sql2 = mysql_query("SELECT * FROM myMembers WHERE notification_calendar='1'"); // query the members who want an email
$numrows = mysql_num_rows($sql2);
if ($numrows > 0){
	while($row = mysql_fetch_array($sql2)){
		if($row['email'] =="") {
			$to = $row['email_work'];
			} else {
			$to = $row['email'];
			}
			$your_firstname = $row['firstname'];
			$your_lastname = $row['lastname'];

					// send an email to everyone who wants it
					$webmaster = "KAI-DEFAT@minbuza.nl";
					$headers = "From: MAAC Webmaster<$webmaster>";
					$subject = "A new message has been posted in the MAAC Calendar.";
					$message = "Hello $your_firstname $your_lastname, a new event has been posted in the MAAC Calendar.\n";
					$message .= "Goto the MAAC website to get the details.\n";
					$message .= "Click here to view the Calendar $dyn_www/Web_Intersect/calen.php\n";
					// send email
					mail($to, $subject, $message, $headers);

	}
				 }

}

	$msgToUser = '<br /><br /><font color="#FF0000">Your event has been created, Close this window.</font><p></p>';
			    include_once 'msgToUser2.php';

}

?>

Link to comment
Share on other sites

If you want a loading image you need to display that BEFORE you actually submit the data. Typically this is done when using AJAX enabled forms. Otherwise, once you submit the form the page will not display until it is done processing.

 

A better solution is to identify WHY the page is taking so long to process and solve that. I see that you are running queries within a loop. This is a very bad idea and can cause huge performance issues. You have a SELECT query that then (within the loop to process those results) performs UPDATE queries. You should be able to accomplish that with one single query. If I get some time I'll analyze further to see if I can provide the appropriate query/code

Link to comment
Share on other sites

Your code is pretty messy, any there are some things that just don't make sense (for example you use variables that are never defined). So, I can't guarantee this code will work, but it should point you in the right direction.

 

You are wide open to SQL Injection attacks. I wasn't sure on the field types for all your variables, so I didn't add logic to handle all of them.

 

Your logic for determining if the record is existing or new is flawed. You should not need to query the DB to determine if the user is attempting to edit or create a new record. Typically, I set an "action" field int he form to make that determination. Alternatively, I assume you have an auto-increment column in the database for the primary key. So, you should be able to check to see if that field has a value. If so, the process should attempt an update. Otherwise, it should perform a new.

 

It seems the length of the script to run is based upon the email part. First off there is no need to define the variables for the email in the loop. Only the email address is changing so redefining the content and headers of the email in the loop is inefficient. Instead of creating individual emails for each person you could simply add all the addresses together and send one email. Put the addresses as BCC if you don't want the users to see the others receiving the email.

 

<?PHP
if(isset($_POST['submit']) && $_POST['type']<>"")
{
    $poster_id = $_SESSION['id'];
    $ID        = intval($_GET['ID'])
    $short     = $_POST['short'];
    $location  = $_POST['location'];
    $type      = isset($_POST['type']) ? intval($_POST['type']) : false;
    $starthour = $_POST['starthour'];
    $startmin  = $_POST['startmin'];
    $endhour   = $_POST['endhour'];
    $endmin    = $_POST['endmin'];
    $reminders = mysql_real_escape_string($_POST['reminders']);
    $view      = isset($_POST['view']) ? $_POST['view'] : false;
    $val       = isset($_POST['val'])) ? $_POST['val']  : false;

    //Determine if this is a new record or one to be edited
    if($ID)
    {
        //Create and run query to update record
        $query = "UPDATE bl_calender
                  SET datecotent='$reminders',
                      location='$location',
                      type='$type',
                      starthour='$starthour',
                      startmin='$startmin',
                      endhour='$endhour',
                      endmin='$endmin',
                      short='$short',
                      viewable='$view'
                  WHERE dateclass='$ID'
                    AND viewable='1'
                    AND poster_id = $logOptions_id";
        $result = mysql_query($query);

        if(!$result)
        {
            $msgToUser = "Error running Query: {$query}<br>Error: " . mysql_error();
        }
        elseif(!mysql_affected_rows())
        {
             // you are not the owner
             $msgToUser = '<br /><br /><font color="#FF0000">Sorry but only the owner can change the event details.<br> Close this window.</font><p></p>';
        }
        else
        {
             $msgToUser = '<br /><br /><font color="#FF0000">Your event has been updated. Close this window.</font><p></p>';
        }
    }
    else
    {
         //it's a new event we want to add
         $query = "INSERT INTO bl_calender
                       (poster_id, dateclass, starthour, startmin, endhour, endmin, location, type, short, datecotent, viewable )
                   VALUES
                       ('$poster_id', '$ID', '$starthour', '$startmin',  '$endhour', '$endmin', '$location', '$type', '$short', '$reminders', '1')";
        $result = mysql_query($query);

        if(!$result)
        {
            $msgToUser = "Error running Query: {$query}<br>Error: " . mysql_error();
        }
        else
        {
            $msgToUser = '<br /><br /><font color="#FF0000">Your event has been created, Close this window.</font><p></p>';

            // query the members who want an email
            $query = "SELECT email, email_work, firstname, lastname
                      FROM myMembers
                      WHERE notification_calendar = '1'";
            $result = mysql_query($query);
            if(!$result)
            {
                $msgToUser = "Error running Query: {$query}<br>Error: " . mysql_error();
            }
            elseif(mysql_num_rows($result))
            {
                //Collect email addresses
                $addresses = array();
                while($row = mysql_fetch_array($result))
                {
                    if(!empty($row['email']))
                    {
                        $addresses[] = "{$row['firstname']} {$row['lastname']}<{$row['email']}>";
                    }
                    elseif(!empty($row['email_work']))
                    {
                        $addresses[] = "{$row['firstname']} {$row['lastname']}<{$row['email_work']}>";
                    }

                }

                $to = implode(', ', $addresses);

                //Set email parameters
                $webmaster = "KAI-DEFAT@minbuza.nl";
                $headers   = "From: MAAC Webmaster<$webmaster>";
                $subject   = "A new message has been posted in the MAAC Calendar.";
                $message   = "A new event has been posted in the MAAC Calendar.\n";
                $message  .= "Goto the MAAC website to get the details.\n";
                $message  .= "Click here to view the Calendar $dyn_www/Web_Intersect/calen.php\n";

                // send email
                mail($to, $subject, $message, $headers);
            }
        }
    }

    include_once 'msgToUser2.php';
}
?>

Link to comment
Share on other sites

I tried the following, but still it doesn't show. I don't get it.

<?PHP
  $show .= '<input type="submit" name="submit" id="submit" onclick="$("#loading").show();" value="submit"></form>';
  $show .= '<div id="loading" align="center" style="display:none;"><img src="images/loading2.gif" alt="" />Loading!</div>';
?>

Link to comment
Share on other sites

Yeah, that's not going to work, well not without getting very creative. Once you submit the form the page will refresh and wait for the output from the server. You would have to use AJAX to avoid that.

 

But, there are many different solutions to your problem. But, first you need to find out what is causing your script to take so long to run. I'm guessing it is the multiple emails you are sending. But, you should add some debugging code to take timings throughout the script and echo the results to the page. Then you can make informative decisions on what you should/need to do. Don't try to work around performance problems instead of addressing them!

 

You really should not make a user wait to create/update a record because of notifications or something similar. As I stated you could send ONE email to all recipients to avoid that. Alternatively you could have the process simply add records to a notification table with the message and the email addresses. Then use a cron job to send the notifications on a regular basis. That way the notification process is completely separated from the create/update process.

Link to comment
Share on other sites

I worked a bit with the code you gave me so the email doesn't take that long.

Still I would like to show a loading gif. I tried with AJAX but it doesn't show:

 

<div style="display:none" id="dvloader"><img src="images/loading.gif" /></div>

 

$(function() {

    $(".changepass").click(function() {

        $("#dvloader").show();

        $(".block1").load("editcalendar.php", function(){ $("#dvloader").hide(); });

        return false;

    });

});

 

don't know exactly where to put it.

Link to comment
Share on other sites

How would that work?

you mean like this:

<form id='form33' action='editcalendar.php?ID=$ID' method='post'>

 

<script language="javascript" type="text/javascript">

function toggleDiv(divid){

   

    if(document.getElementById(divid).style.display == 'none'){

      document.getElementById(divid).style.display = 'block';

    }else{

      document.getElementById(divid).style.display = 'none';

    }

  }

</script>

Link to comment
Share on other sites

Sorry for being such an amateur.

What I basically do is load a page called editcalendar.php. The users fills in an event with date and all and hits Submit.

The event is saved in the database and all users get an email. During this process I want the loading.gif displayed to make

sure people don't click Submit again thinking nothings happening.

When the process is done the loading.gif should dissapear and a text should show up saying: Your event has been created, Close this window.

 

So if I use the $.post function I would use it like this:

 

$.post("editcalendart.php", function(data) {

  alert("Your event has been created, Close this window.");

});

 

 

Link to comment
Share on other sites

I got it to work but not quiet. WHen I use following function:

 

$(function() {

    $("form#form33").submit(function() {

        $("#dvloader").show();

        $.post("editcalendar.php", function(data) {

  alert("Your event has been created, Close this window.");

});

  return false;

});

 

I see the loading gif but the data doesn't get saved to the table.

 

When I take out the "return false" to go back to the html

The data gets saved but I don't see the loading gif.

 

Also the loading gif gets displayed in the upper left corner of the form, even with this:

 

#dvloader{

position:absolute;

top:300;

right:300;

z-index:1;

}

 

What am I missing here (except knowledge of course)

Link to comment
Share on other sites

OK, you mean all this has to go with AJAX?

 

$short=$_POST['short'];

  $location=$_POST['location'];

  if(isset($_POST['type'])) {

  $type=$_POST['type']; }

  $starthour=$_POST['starthour'];

  $startmin=$_POST['startmin'];

  $endhour=$_POST['endhour'];

  $endmin=$_POST['endmin'];

  $reminders=$_POST['reminders'];

      $reminders=addslashes($reminders);

  if(isset($_POST['view'])) {

  $view=$_POST['view']; }

  if(isset($_POST['val'])) {

$val=$_POST['val']; }

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.