www.webdeveloper.com
Results 1 to 4 of 4

Thread: Query inserting twice.

  1. #1
    Join Date
    Apr 2014
    Posts
    42

    Query inserting twice.

    I've been trying to figure out why the queries on liked_button.php are entering twice for about 24 hrs now with no luck.

    I have a liked button that users can click, when that button is clicked, info goes to liked_button.php, that info is subsequently transferred to the `likes` and `notifications` table. But for some reason, the query runs twice.

    Here is the relevant code:

    My echoed like form with like button on index.php
    Code:
    <form name='likes_form' id='likes_form' action='liked_button.php'>
    
                                              <input type='hidden' name='hidden_folder' class='hidden_folder' value='$random_directory'>
    
                                              <input type='hidden' name='hidden_name' class='hidden_name' value='$image_name'>
    
                                              <input type='hidden' name='hidden_image' class='hidden_image' value='$image_info'>
    
                                              <input type='hidden' name='hidden_user' class='hidden_user' value='$posted_by'>
    
                                              <input type='image' id='like_button' class='like_button button' src='$button_source' onClick='return getLikes ()'>
    
                                              <input disabled class='total_likes' value='$liked_count'>
    
                                              </form>
    The JS function that clicking the like button calls:
    Code:
    <script>
    
    function getLikes()  {//function to leave_comment.php
      
      var form = jQuery("#likes_form");
            
            $.ajax({ type: "GET", url: form.attr("action"), data: form.serialize(), success: function() {/**/} });
    
      }
    
    </script>
    The liked_button.php page:
    Code:
    <?php
    
    error_reporting(E_ALL); ini_set('display_errors', 1); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    
    session_start();
    
        if(!isset($_SESSION['id']))	{
    
    	header('location:errors/must_login.php');
    
    	}
    
    		$full_location = $_GET['hidden_image'];
    		
    		$ghost_folder = $_GET['hidden_folder'];
    		
    		$ghost_name = $_GET['hidden_name'];
    
    		$uploading_user = $_GET['hidden_user'];
    
    		$liker = $_SESSION['id'];
    
    		$date = date('M/d/Y');
    		
    		$time = date('Y:m:d h:i:s');
    
    		$action = 'liked';
    
    		$status = '0';
    
    		$conn = mysqli_connect("localhost","root","") or die ("No SQLI");
    				
    				mysqli_select_db($conn, "sample") or die ("No DB");
    
    		$enter_likes = ("INSERT INTO `likes` (action, hidden_folder, hidden_name, liked_img_loc, liked_by, posted_by, liked_unliked, date, time, status) VALUES ('$action','$ghost_folder','$ghost_name','$full_location','$liker','$uploading_user','1','$date','$time','$status')");
    
    		mysqli_query($conn, $enter_likes) or die ("No query");
    
    		var_dump($status);
    
    		$likes_notifications = ("INSERT INTO `notifications` (action, loc_of_img, causing_user, effected_user, time, date) VALUES ('$action','$full_location','$liker','$uploading_user','$time','$date')");
    
    		mysqli_query($conn, $likes_notifications) or die ("No notifications query");
    
    		mysqli_close($conn);
    
    		header('location:index.php');
    
    
    ?>
    I've ran
    Code:
    var_dump
    on all variables on liked_button.php and all the variables contain the correct info.

    For the life of me I just can't figure out why the queries are running twice.

    I have the same sort of setup to get user comments and store them into `comments` and `notifications` and that setup works just fine. Any help is appreciated!

  2. #2
    Join Date
    May 2014
    Posts
    899
    You're not canceling the click you are trapping on the input, so the submit is going through too. Hence, two likes.

    Really you shouldn't be trapping onclick, you should be trapping onsubmit, and even with trapping onsubmit you should be preventing event propagation.

    Normally (assuming 'e' is the event passed to the handler)
    Code:
    	e.cancelBubble = true;
    	if (e.stopPropagation) e.stopPropagation();
    	if (e.preventDefault) e.preventDefault();
    	e.returnValue = false;
    Would cover all the bases -- not sure how you integrate that into the bloated wreck that is jQuery. I think it has the prevent() method...

    It might also help if you had a COMPLETE form with at the very least a fieldset, since INPUT as direct children of FORM is invalid markup, not sure why you're putting classes on hidden inputs, you could probably use proper double quotes in the markup if you stopped using slow double quotes in your PHP...

    Then there's the SQL side of things, where you're not sanitizing the $_GET data just begging to be hacked, and basically you're using mysqli like it was the old mysql_ functions, instead of using it properly with prepared queries.

    Also not sure why you're playing games with date and time when mySQL has a perfectly good DATETIME field and NOW() operation.

    So to 'fix' the markup:
    Code:
    echo '
    <form id="likes_form" action="liked_button.php">
    	<fieldset>
    		<input type="hidden" name="hidden_folder" value="', $random_directory, '" />
    		<input type="hidden" name="hidden_name" value="', $image_name, '" />
    		<input type="hidden" name="hidden_image" value="', $image_info, '" />
    		<input type="hidden" name="hidden_user" value="', $posted_by, '" />
    		<input type="image" id="like_button" src="', $button_source, '" alt="Like" />
    		<input disabled id="total_likes" value="', $liked_count, '" />
    	</fieldset>
    </form>';
    to 'fix' the scripting:
    Code:
    <script type="text/javascript"><!--
    $("#likes_form").submit(function(e) {
    	$.ajax({
    		type: "GET",
    		url: form.attr("action"),
    		data: form.serialize(),
    		success: function() {
    			
    		}
    	});
    	e.prevent();
    });
    --></script>
    Then the PHP
    Code:
    <?php
    
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    
    session_start();
    
    if (!isset($_SESSION['id'])) header('location:errors/must_login.php');
    
    $conn = mysqli_connect("localhost","root","") or die ("No SQLI");
    			
    mysqli_select_db($conn, "sample") or die ("No DB");
    
    $statement = $conn->prepare('
    	INSERT INTO likes (
    		action, hidden_folder, hidden_name, liked_img_loc,
    		liked_by, posted_by, liked_unliked, date, time, status
    	) VALUES ( 
    		'liked', ?, ?, ?, ?, ?, 1, ?, ?, 0,
    	)
    ');
    
    $statement->bindParam(
    	'sssssss',
    	$_GET['hidden_folder'],
    	$_GET['hidden_name'], 
    	$_GET['hidden_image'],
    	$_SESSION['id'], 
    	$_GET['hidden_user'], 
    	date('M/d/Y'),
    	date('Y:m:d h:i:s')
    );
    
    $statement->execute();
    
    $statement = $conn->prepare('
    	INSERT INTO notifications (
    		action, loc_of_img, causing_user, effected_user, time, date
    	) VALUES (
    		'liked', ?, ?, ?, ?, ?
    	)
    ');
    
    $statement->bindParam(
    	'sssss',
    	$_GET['hidden_image'],
    	$_SESSION['id'], 
    	$_GET['hidden_user'], 
    	date('M/d/Y'),
    	date('Y:m:d h:i:s')
    );
    
    $statement->execute();
    	
    /*
    	Are you REALLY sure you want to send a redirect as a AJAX result?!?
    	header('location:index.php');
    */
    	
    ?>
    Though I'm guessing wildly and the above code is untested. I generally don't use jQuery (though I took the time to learn it BEFORE I started badmouting it) or mysqli (I'm a PDO guy)... but still that should be enough for you to get how it should be done.

    Hope this helps.
    Java is to JavaScript as Ham is to Hamburger.

  3. #3
    Join Date
    Apr 2014
    Posts
    42
    Thanks for that deathshadow, I've got it working now. But while I have you..can you tell me why this ajax function refreshes the page instead of no page refresh?

    Function to be called when img is clicked:
    Code:
    <script>
    function leaveYourComment()  {//function to leave_comment.php
      var form = jQuery("#comment_form");   
           $.ajax({ type: "GET", url: form.attr("action"), data: form.serialize(), success: function() {} });
      }
    </script>
    And here is the form:
    Code:
    <form name='comment_form' id='comment_form' action='leave_comments.php' onSubmit='return validateForm() ; return false;'>              
                                            <input type='text' name='user_comment' class='user_comment' placeholder='Leave a comment...'>
                                            <input type='hidden' name='hidden_folder' class='hidden_folder' value='$random_directory'>
                                            <input type='hidden' name='hidden_title' class='hidden_title' value='$title'>
                                            <input type='hidden' name='hidden_name' class='hidden_name' value='$image_name'>
                                            <input type='hidden' name='hidden_image' class='hidden_image' value='$image_info'>
                                            <input type='hidden' name='hidden_user' class='hidden_user' value='$posted_by'>          
                                            <input type='image' src='images/comment_single_button_2.jpg' class='leave_comment button' name='leave_comment button' onClick='return leaveYourComment ()'>
                                  </form>
    The values are correct and everything works, it's just that it refreshes the page, and I want it to submit without page refresh

  4. #4
    Join Date
    May 2014
    Posts
    899
    Because you aren't preventing the submit event... I don't think... Really that's a mess because you have a onsubmit AND a onclick -- on a form that actually again shouldn't be trapping the mouse-only event on the submit for the form.

    The validate AND the leaveYourComment should BOTH be run on the FORM:nsubmit

    Though again, as with the other example I'd be hooking from the scripting instead of using the onevent methods... and as before there's no reason to put a class on hidden inputs; and something I didn't mention was that if that data is all static, why are you wasting time sending it client-side in the first place instead of storing it in the session?

    In any case, first let's clean up the markup:
    Code:
    echo '
    <form id="comment_form" action="leave_comments.php">
    	<label for="user_comment">Leave a comment:</label>
    	<input type="text" name="user_comment" id="user_comment" />
    	<input type="hidden" name="hidden_folder" value="', $random_directory, '" />
    	<input type="hidden" name="hidden_title" value="', $title, '" />
    	<input type="hidden" name="hidden_name" value="', $image_name, '" />
    	<input type="hidden" name="hidden_image" value="', $image_info, '" />
    	<input type="hidden" name="hidden_user" value="', $posted_by, '" />
    	<input type="image" src="images/comment_single_button_2.jpg" alt="leave comment" />
    </form>';
    Note the label -- Placeholder is NOT a substitute for a label, no matter how many PSD jockeys and scripttards try to use it otherwise. See:
    http://baymard.com/blog/false-simplicity
    http://www.pardot.com/faqs/best-prac...rs-and-labels/
    http://www.webaxe.org/placeholder-at...s-not-a-label/
    http://www.456bereastreet.com/archiv...label_element/

    and the HTML 5 specification itself:
    http://www.w3.org/TR/html51/forms.ht...lder-attribute

    ... and I quote:
    The placeholder attribute should not be used as a replacement for a label. For a longer hint or other advisory text, place the text next to the control.
    Then for the scripting (using jQ since that's what you're using -- I'd seriously swing an axe at that too)
    Code:
    $("#comment_form").submit(function(e) {
    	if (validateForm()) {
    		var form = jQuery("#comment_form");   
    		$.ajax({
    			type: "GET",
    			url: form.attr("action"),
    			data: form.serialize(),
    			success: function() {
    			}
    		});
    	}
    	e.prevent();
    });
    Again, attach to the submit, use the validateForm to determine if the ajax should be run. All one operation, with none of those onevent attributes in the markup.

    Pretty much these days if you are saying "onmouseover" or "onsubmit" or "onclick" in the HTML, you're doing it all wrong. Likewise trapping clicks on the submit button doesn't help for keyboard users -- when you want to trap the form being sent for ajax or for validation, you trap the form submit, not clicks on a button/input.
    Java is to JavaScript as Ham is to Hamburger.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles