0

I have a simple form with one input field and one submit button. When i click submit, i get error

This is the query in php. Query:

   //Using MySQLi
    $stmt = $con->prepare("INSERT INTO `emailsubscribe` 
    (email,medium,country)VAlUE(?,?,?)"); // Use prepared statements. 
    $stmt-> bind_param("sss", $email, $medium, $country);
    $stmt-> execute();

This table has 3 columns email, medium and country.

    $('#formoid').on('submit', function() {
       $.ajax({
            type: "POST",
            url: "subscribe.php",
            data: $(this).serialize(),
	success: function(data){
            $('.message').html(data).fadeIn();
            }
        });
    return false;
});
<div class="message" style="color:black;"></div>
      <form action="subscribe.php" title="" method="post" id="formoid">
        <input type="email" id="email" name="email" minlength="7" size="40" placeholder="Enter your email here.." required><br><br>
        <input type="hidden" name="medium" value="subbox" />
        <input type="hidden" name="country" value="<?php echo $country; ?>" />
        <input type="submit">	 
      </form>

10
  • What error exactly? Commented Jun 3, 2020 at 23:47
  • P.s. the PHP code is a SQL injection disaster waiting to happen. Commented Jun 3, 2020 at 23:47
  • @ADyson This is the error. Notice: Undefined index: email . It looks like i have something wrong in ajax. isn't it? Commented Jun 3, 2020 at 23:59
  • @ADyson I really appreciate you pointing the SQL injection issue. Given my limited knowledge with SQL and other programming language i am lacking the expertise of fixing the issue. If you have something ready to be implemented regarding SQL injection issue, i would be happy to incorporate. Commented Jun 4, 2020 at 0:02
  • You can read about PDO and Prepared Statements. Those are some techniques to prevent such SQL injection issues Commented Jun 4, 2020 at 5:23

2 Answers 2

1

First, let's wrap up the HTML data.

<div class="message"></div>
<form action="subscribe.php" name="subscribeForm">
    <input type="email" name="emailsub" minlength="7" size="40" placeholder="Enter your email here.."><br><br>
    <select name="medium">
        <option value="">Select Medium</option>
        <option value="english">English</option>
        <option value="hindi">Hindi</option>
        <option value="japanese">Japanese</option>
    </select>
    <br><br>
    <select name="country">
        <option value="">Select Country</option>
        <option value="India">India</option>
        <option value="USA">USA</option>
        <option value="Japan">Japan</option>
    </select><br><br>
    <input type="submit" id="action"> 
</form>

AJAX code below takes the form details and sends to subscribe.php. Note that document.subscribeForm below takes your form field variables and stores in the form. For this only name value in HTML part is enough. Hence, I have not added any id field in the HTML form fields.

$('#action').click(function() { 
    var form = document.subscribeForm;
    var dataString = $(form).serialize();
    $.ajax({
      type: 'POST',
      url: $(form).attr("action"),
      data: dataString,
      beforeSend: function(){
        $('.message').hide();
        $("#action").val('Please wait...');
      },
      success: function(data){
        $('.message').html(data).fadeIn();
      }
    });
    return false;
});

Once the data is sent to subscribe.php, it's now time to process it.

// Storing data in variables
$email = (!empty($_POST['emailsub'])?$_POST['emailsub']:null;
$medium = (!empty($_POST['medium'])?$_POST['medium']:null;
$country = (!empty($_POST['country'])?$_POST['country']:null;

if($_POST){
    // Check if email submitted is empty or not. If yes, script will stop executing further.
    if($email == null){
        echo "Email is required";
        exit();
    }

    // Check if medium submitted is empty or not. If yes, script will stop executing further.
    if($medium == null){
        echo "Medium is required";
        exit();
    }

    // Check if country submitted is empty or not. If yes, script will stop executing further.
    if($country == null){
        echo "Country is required";
        exit();
    }

    // All checks cleared. Process the data.

    //Using MySQLi
    $stmt = $con->prepare("INSERT INTO emailsubscribe(email, medium, country)VAlUES(?,?,?)"); // Use prepared statements. 
    $stmt-> bind_param($email, $medium, $country);
    $stmt-> execute();

    // Using PDO (Better: A big bonus is that you can use a readable `:name` instead of confusing `?`)
    $stmt = $con->prepare("INSERT INTO emailsubscribe(email, medium, country)VAlUES(:email, :medium, :country)"); // Use prepared statements. 
    $stmt-> bindValue(':email', $email);
    $stmt-> bindValue(':medium', $medium);
    $stmt-> bindValue(':country', $country);
    $stmt-> execute();

    // Echo Message
    if($stmt){
        echo "Success";
    }else{
        echo "Error";
    }
}

This is the proper way how you should process your forms.

Sign up to request clarification or add additional context in comments.

9 Comments

Please explain the code in a bit more detail, otherwise it's just a dump of data to be blindly copied, with no explanation of how or why it solves the problem. A good quality answer always includes a more detailed explanation
Also mysqli_real_escape_string is not needed here, because you're using parameterised queries. In fact it could even potentially be harmful by adding escaped characters into the data and thus changing it slightly. The parameterisation process will already take care of ensuring that special characters in the data are not interpreted as part of the SQL statement, so there's no use for mysqli_real_escape_string in this situation.
Thanks. I don't think document.registerForm will work though, I just noticed that, there's no form with that name in the HTML. But then again why did you change the OP's code from what it already was, where the form had an ID and the form's "submit" event was being handled by jQuery (instead of a button click)? Handling "submit" is generally the better approach, especially because then you can just write $(this).serialize() to directly serialise the current form, with no messing about.
P.S. cache: true is redundant - a) it's the default for this setting anyway, and b) it doesn't really apply to POST requests anyway, as mentioned in the $.ajax docs
yeah sorry, there were some minor mistakes... 1) It will be document.subscribeForm (2) Cache will be false... Didn't notice these earlier. (3) Even button click does the job well. If the user wants they can change to form submit.
|
1

Firstly I don't see any medium or country in your form as inputs. So I changed your HTML code

$('#formoid').on('submit', function() {

  $.ajax({
    type: "POST",
    url: "subscribe.php",
    data: $(this).serialize(),
    success: function(response) {
      $(this).hide(); //sets css display:none to form
      var message = "Thank you!";
      $('.container-fluid').html(message);
    }
  });

});
<form action="subscribe.php" title="" method="post" id="formoid">
  <input type="email" id="emailsub" name="email" minlength="7" size="40" placeholder="Enter your email here.." required><br><br>
  <input type="text" id="" name="medium" size="40" placeholder="Enter here.." required>
  <input type="text" id="" name="country" size="40" placeholder="Enter here.." required>
  <input type="submit">

</form>

Then in your subscribe.php do the following. Take note, I just copied your exact SQL code. Use prepared statements or PDO to avoid SQL injection

$qry = mysqli_query($con,"INSERT into `emailsubscribe` (email,medium,country) value ('".$_POST['email']."','".$_POST['medium']."','".$_POST['country']."')");

6 Comments

yes although FormData($('form')[0]) would be better as FormData(this) to 1) avoid confusion with any other forms potentially on the page, and b) avoid a pointless jQuery invocation. On the other hand, the code could be simplified - the lines var FD = new FormData($('form')[0]);, and processData: false, contentType: false, could all be removed, and data: FD replaced with data: $(this).serialize() to take advantage of jQuery's built-in ability to automatically collect form data - see api.jquery.com/serialize
Completely agree. But it seems the person is a beginner and thus I left all the details for him to see as it is.
Sorry I don't understand your point in that respect - none of the stuff I've suggested changing was in the questioner's original code, so it won't do any harm for you to simplify the code you're providing in your answer. If you want something that's good for a beginner, then IMHO you should work hard not to clutter it up with irrelevant stuff. In that respect, serialize() is the best solution here because it's clear, simple and doesn't need lines of other code to make it work.
@ADyson I edited the code based on your suggestion. I think it looks cleaner now
Thank you @Anu. In the form, user will only enter email. The other two fields 1. medium is a string constant value like "subbox" 2. country is a two letter country code stored in a php variable $country. medium is used to capture from which place on the wep page user is subscribing as i have multiple points on the website from where user can subscribe. country is again to get the information from which country user has subscribed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.