Post and submit problems using javascript, forms and php - php

I am trying to create a validate-email javascript and get it working with forms and PHP. Of coures, some problems...
As you can see in my form, I did define "post" as the method. But I can only retreive the data as if it was a get method. It was working before I started to add the e-mail verification script and adopt the code to it.
If the e-mail is incorrect, I do return false. Isn't the point that the request to the test.php (defined in action) should not be executed? As it is now, the page is accessed even if I return false.
Depending on the answers to the questions above, do I need to submit the form from the Javascript if the e-mail is verified ok?
javascript:
function isValidEmail() {
regExp = /^[a-zA-Z]+([_\.-]?[a-zA-Z0-9]+)*#[a-zA-Z0-9]+([\.-]?[a-zA-Z0-9]+)*(\.[a-zA-Z]{2,4})+$/;
if(document.subscribe.email1.value.search(regExp) == -1){
alert(document.subscribe.email1.value + " Incorrect email address");
return false;
}
//document.subscribeForm.submit();
return true;
}
php:
<?php
echo $_POST['email1'];
$mysqli = mysqli_connect("localhost", "root", "", "test", "3306");
$result = mysqli_query($mysqli, "SELECT email, id, subscriber, subscribed_date FROM `user` u;");
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
foreach($row as $key => $value){
echo "$key = $value<BR/>";
}
}
mysqli_free_result($result);
mysqli_close($mysqli);
?>
html:
<div id="subscribe">
<form action="test.php" name="subscribe" method=post">
<p id="formlabel">E-mail</p> <input type="text" name="email1">
<br>
<p id="formlabel">Repeat e-mail</p> <input type="text" name="email2"> <br/>
<input type="submit" value="Subscribe" onclick="isValidEmail()">
</form>

<input type="submit" value="Subscribe" onclick="isValidEmail()">
This executes isValidEmail() and then throws away the result. The onclick itself returns undefined and the submission is not prevented.
You can say onclick="return isValidEmail()". However:
Put validation/submission stuff on form onsubmit, not input click, to ensure it is always called for all types of form submission.
Better to avoid inline event handlers.
You missed a " in your form's method attribute, which is presumably why it was defaulting back to get.
so:
<form id="subscribe" method="post" action="test.php">
...
</form>
<script type="text/javascript>
document.getElementById('subscribe').onsubmit= function() {
if (!this.elements.email1.value.match(/^[^#]+#[^#]+$/) {
alert('Please enter an e-mail address');
return false;
}
if (this.elements.email1.value!=this.elements.email2.value) {
alert('E-mail addresses do not match');
return false;
}
return true;
}
</script>
I replaced the regexp with a trivial one, because the expression you're currently using is bogus and will deny many valid e-mail addresses. Turning customers away because their e-mail address doesn't fit your conception of what an e-mail address is sucks.
‘Validating’ e-mail addresses correctly with regex is absurdly difficult. Better to include only a trivial check for obviously-malformed strings like the above. If you need to really check the e-mail address, you will have to actually try to send a mail to it, or at least try to lookup the domain name part of the address for an MXer.
See this question for discussion.

you should attach the function to the form's onsubmit event:
<form action="test.php" name="subscribe" method="post" onsubmit="isValidEmail()">
where you can stop the event returning false.
Also, you made a typo in method=post", that's why it doesn't get submitted as POST data.

Related

html form: prevent re-submitting while sending

I have this form:
<form action="" method="post" name="my_form">
<input type="text" name="my_input">
</form>
You can write some text and the submit by pressing the enter key.
My problem: When you press the enter key multiple times, it'll also sent multiple times to my server.
There are solution like this:
onsubmit="my_button=true;return true;"
But these solutions require a submit button.
Is there a way to do this without adding a (hidden) submit button?
If you want to be absolutely sure, for example, submitting the form twice can cause severe damage/cause malicious things to happen, then you need to check this serverside. One rule of webdevelopment and general development is to never trust your end-user, and by simply blocking the form using JavaScript, you cannot be assured that a malicious user won't be sending the form twice by getting around the JavaScript.
What you can do is something like this:
Important: This is just a proof of concept example to explain the idea, this is not a 100% bulletproof solution.
Form
<?php
session_start();
$_SESSION['nonce'] = random_number();
?>
<html>
...
<form method="post" action="process.php">
<input type="hidden" name="nonce" value="<?php echo $_SESSION['nonce']; ?>" />
... other form elements ...
</form>
...
process.php
<?php
session_start();
$nonce = isset($_POST['nonce']) ? (int)$_POST['nonce'] : 0;
$session_nonce = $_SESSION['nonce'];
if ($_SESSION['nonce'] != $nonce) {
die("Invalid nonce, double submission detected.");
}
$_SESSION['nonce'] += 1; // this will cause the previous check to fail on a second submission.
some like this :
<form onsubmit="send();" method="post" name="my_form">
<input type="submit" name="my_input" id="sub">
</form>
js code:
function send(){
$("#sub").attr('disabled', 'disabled');
$.ajax({
// data
success: function(data){
$("#sub").attr('disabled', false);
}
});
}
Like this (untestet):
var formSubmitted = false;
document.getElementById('my-form').addEventListener('submit', function(){
if(formSubmitted === false) {
formSubmitted = true;
return true;
}
return false;
});
You could disable the button once it's set so the User cannot click it again
<form action="" method="post" name="my_form">
<input type="text" name="my_input" <?php if(isset($_POST['my_input'])) { print
'disabled'; } ?>>
</form>

How to make multiple AJAX queries after user input?

This seems like such a simple thing, but I have not been able to find adequate guidance on it for the life of me. I have only been able to find things about successive AJAX queries regardless of user input, like this or this.
What I'm trying to do is create a survey such that after a user answers a question, the website replaces the question with the next question, and so on.
Here's what I have so far (in a .php file):
In <head>, I have a function for each successive element to call:
<script type="text/javascript">
function nextPage(url) {
$("#consent-form").empty();
$("#consent-form").load(url);
}
</script>
Maybe that's just not how it's done. I have no idea. Like I said, I have not been able to find adequate help on this. As far as I can tell, empty() should not delete #consent-form, but only its content and children, which is exactly the behavior I want.
This is the initial html and php for the div I want to swap out after each answered question:
<div id="consent-form">
<?php
// Check for a valid email address.
$email = $emailErr = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["email"])) {
$emailErr = "* Your email address is required.";
} else {
$email = test_input($_POST["email"]);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "* Please enter a valid email address.";
} else {
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$query = "INSERT INTO survey VALUES ('" . $email . "','" . $actual_link . "','','')";
mysql_query($query);
echo '<script type="text/javascript">'
, 'nextPage("survey.php");'
, '</script>'
;
}
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<p>
[Consent form text]
</p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Please enter your email address: <input type="text" name="email" value="<?php echo $email;?>">
<span class="error"> <?php echo $emailErr;?></span>
<br>
<input type="submit" value="Begin Study">
</form>
</div>
As I'm sure you can tell, I'm trying to do some form validation there.
This succcessfully injects the content of the next page ("survey.php") into the consent-form div. "survey.php" includes the following, using the nextPage() function shown above:
$("#csp_form").on('submit', function() {
nextPage("other.php");
});
But this fails to inject the consent-form div with "other.php".
Now, however, not even the form validation works. According to Firebug, the jquery library has raised some sort of error, even when I comment out all the jquery and javascript functions, and it's stuck in some perpetual loading operation. (This issue has been fixed.)
I am about to start throwing things. I have tried many different other techniques, but none of them worked and I have lost track of them. Hopefully this latest version will be sufficient to get guidance on this.
Sorry all that was so long, but usually people complain that there's too little information, so I wanted to make sure to include everything.
EDIT:
Per request, here's the current full content of survey.php (with the text content changed for privacy purposes):
<script type="text/javascript">
$("#icecream_form").on('submit', function() {
nextPage("other.php");
return false;
});
</script>
<br>
<h2>What's your favorite ice cream flavor?</h2>
<form method="post" id="icecream_form">
<input type="radio" name="icecream" value="vanilla"> Vanilla
<br>
<input type="radio" name="icecream" value="chocolate"> Chocolate
<br>
<input type="radio" name="icecream" value="other"> Something else
<br>
<input type="radio" name="icecream" value="none" checked> I don't have a favorite.
<br>
<br>
<input type="submit" name="icecream_submit" value="Go" onsubmit="return(false)">
</form>
After hitting submit, the content from consent-form comes back with an error message from the email form ("Please enter an email address"), implying that the email form was posted again. I cannot comprehend how that is possible if all the stuff from that div had truly been replaced by the stuff in survey.php.
I believe the issue was just that I was missing $(document).ready(function () { before $("#icecream_form").on('submit', function() {. This enabled return false; to actually work.
However, I also swapped out the PHP form validation with a jQuery version and deleted the nextPage() function in lieu of just having each page have their own .load(), so those things may also have made a difference.

PHP sanitize email from a Wordpress form

I'm writing a plugin which calls an API and uses an email address as part of the authentication.
I'm getting really confused regarding which way round parts of my code should go in terms of variables, and as such keep getting undefined variable errors.
This function outputs a form on a Worpdress admin page and allows the user to input their email address. I wish to sanitise the email after it has been input, then spit back out the sanitised version into the input field.
function dotmailer_options() {
?>
<div class="wrap">
<h2>Dotmailer API information</h2>
<form method="post" action="options.php">
<?php settings_fields( 'settings-group' ); ?>
<?php do_settings_sections( 'settings-group' ); ?>
<label>API key</label><br />
<input type="email" name="apiemail" value="<?php echo $sanitized_email; ?>"><br />
<label>Password</label><br />
<input type="password" name="apipassword" value="<?php echo get_option('apipassword'); ?>"><br />
<p><input type="submit" value="Save" class="button-primary" /></p>
<?php
// Store email field as var
$apiemail = get_option('apiemail');
// Sanitize var
$sanitized_email = filter_var($apiemail, FILTER_SANITIZE_EMAIL);
?>
</form>
</div>
However when I do this I get an "undefined" error actually in the input box.
I understand this is probably because the code to create $sanitized_email runs after the input has called for it, but I can't work out how else I should do this.
Also will having code directly in this function open me up to attacks? I have the following at the top of my plugin code: defined('ABSPATH') or die(); - but I don't know if that is enough.
you will need to use either javascript or ajax for this as php is server code rather than browser code (i.e. it runs on the serverside only) whilst javascript is browser code and can re-act to changes in the browser.
But there is no point in sanitizing at this stage, but you would of course sanitize and validate the form submission $_POST items. If displaying variable information from $_POST or the database to the user, you escape the values before inputting them into html.
You could validate the email using javascript to speed things up for the user if there is an issue..
<script>
function validateEmail() {
var x = document.forms["myForm"]["apiemail"].value;
var atpos = x.indexOf("#");
var dotpos = x.lastIndexOf(".");
if (atpos< 1 || dotpos<atpos+2 || dotpos+2>=x.length) {
document.elements["apiemail"].value = "Invalid email";
return false;
}
}
</script>
and in your form:
<input type="email" name="apiemail" value="" onchange="validateEmail()">
I think the reason you're getting an undefined error is you haven't defined the variable in advance - Try putting…
$sanitized_email = "";
in before your form processing code.
Also, are you using some form of checking if the form has been set or not? You can use a hidden field and check if_isset using php to see if the user has attempted to process the form. Only then would the sanitized variable be needed.

PHP: Refresh page on invalid form submit

How can I refresh a page with a form on submission pending the outcome of the submitted data and display a result.
e.g I have a page with a form:
<form action="" method="post">
<input type="name" value="" name="name" placeholder="Your Name" />
<input type="button" name="submit" value="submit form "/>
</form>
The engine that handles the form is external, but required in the page:
require_once 'form_engine.php';
form_engine.php checks the input,
$success = "true";
$errorMessage = " ";
$name = $_POST['name'];
if ( $name == '') {
$errorMessage = 'Please enter your name';
$success = false;
}
else (if $success = true) {
// do something with the data
}
The form page contains the result:
<form action="" method="post">
<input type="name" value="" name="name" placeholder="Your Name" />
<input type="button" name="submit" value="submit form "/>
</form>
<p><?php echo $errorMessage; ?></p>
Will the error message get displayed after the form is submitted incorrectly? Or do I have to use a session to store it?
You need something like this:
if (!isset($_POST['name']))
instead of
if ( $name == 'name')
UPDATE
Try this, it should give you the idea:
<?php
$errorMessage = false;
if (isset($_POST['submit'])) {
if (!isset($_POST['name']) || $_POST['name']=='') {
$errorMessage = 'Please enter your name';
}
else {
// do something with the data
echo "Success!!";
}
}
?>
<form method="post">
<input type="name" value="" name="name" placeholder="Your Name" />
<input type="submit" name="submit" />
</form>
<p><?php if ($errorMessage) echo $errorMessage; ?></p>
Note: leaving out the action attribute will just submit the form to the current page
Note 2: The PHP here could very well be stored in another page. Using require() is the same as putting the code directly into the page.
You can use redirect on php side:
header('Location: www.mysite.com/index.php');
You seem to be a little confused in terms of the exact process that occurs in terms of rendering a page, as do some of those commenting. You do not need to use sessions to solve this problem. There is no need to store anything server-side between page requests because the user's browser with retain everything that you need, at least for this situation. My guess is the others took you mentioning an "external engine" and thought that the form would be submitting away to a different site/page.
form loops
Below is a diagram showing a typical form request loop:
You do not have to do this, as coding is as much about personal preference to anything else, but typically people will design their form to submit back to the same URI that generated it — as you seem to be doing in your example, by leaving the action attribute blank. By doing this, as long as you embed everything you wish to pass back to the server side within the form — each time the user submits — that information will be resent and be available in PHP.
Obviously you need to be wary of what information might constitute as sensitive, as this data should only ever be written into markup if your requests are protected by HTTPS/SSL. You should also filter/escape any user input to prevent markup injection into your site. You can prevent many problems by using htmlentities, however this can cause issues depending on the values you are trying to capture from the user. Because you are using double quoted HTML attributes (the right way to do them ;) I have not set the ENT_QUOTES option.
back to the point
So in the above loop the user will be shown the form for the first time, and after any subsequent submit, which means that each time your PHP notices that there is an error you can just add your message into the page flow. The trick with this kind of system is what exactly do you do once the form is fully complete. To get out of the loop most people will use a header location call:
<?php
require_once 'form_engine.php';
$name = !empty($_POST['name']) ? trim($_POST['name']) : '';
$name = htmlentities($name);
if ( $success ) {
header('location: next-step.php');
exit;
}
?>
<form action="" method="post">
<input type="name" value="<?php echo $name; ?>" name="name" placeholder="Your Name" />
<input type="button" name="submit" value="submit form "/>
</form>
<?php
if ( $errorMessage ) {
echo "<p>$errorMessage</p>";
}
?>
form engine repairs
You should also rectify your form_engine.php as per my comments above and Shekhar Joshi's answer, although I would keep the header code outside of your engine logic, and leave that decision to the code that requires in the engine — as the above does.
may be, you are looking for this! the header() method.
$success = true;
$errorMessage = " ";
$name = $_POST['name'];
if(isset($_POST['name'])) {
if ( $_POST['name'] == '') {
$errorMessage = 'Please enter your name';
$success = false;
header('Location: www.something.com/some.php');
}
else if ($success == true) {
// do something with the data
}
}

Why are these <form>'s not recognized by FF and Chrome?

I have the following forms that are rendered by some PHP logic. The forms render fine; you can see the text inputs and submit button and all.
In IE the forms work as expected. The first form goes to 'index.php?subscribe=go' and the second to 'index.php?unsub=go', but in FF and Chrome, clicking the submit button reloads the page (does not go to form action). I have not checked other browsers.
I found in Firebug that the <form> tag doesn't even exist on the page in Firefox. This is very strange; check it out:
else
{
echo '<div class="subs_main">';
if (isset($_GET['subscribe']))
{
if ($_GET['subscribe'] != 'go')
{?>
Subscribe to <b>Bella Blog</b> for specials, sales, news and more!
<br />
<form action="index.php?subscribe=go" method="post" name="subscribe_form" onsubmit="return checkForm();">
Name: <input type="text" name="name" size="15" />
<br />
Email: <input type="email" name="email" size="20" />
<br />
<input type="submit" value="subscribe!" name="submit" />
</form>
<p class="unsub">You can unsubscribe at any time</p>
<?php
}
else
{
// subscribe user
}
}
elseif (isset($_GET['unsub']))
{
if ($_GET['unsub'] != 'go')
{?>
Sorry to see you go! You can re-subscribe at any time!
<br />
<form onsubmit="return checkForm2()" name="unsub_form" method="post" action="index.php?unsub=go">
Email: <input type="email" name="email" size="20" />
<br />
<input type="submit" value="unsubscribe" name="submit" />
</form>
<?php
}
else
{
// process unsubscription HERE
}
}
echo '</div>';
}
This is the JS for form validation (negligible I think because it works in IE and I get the same result when commenting this script out):
<script type="text/javascript" language="javascript">
function checkForm()
{
var regex = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
var form = document.forms.subscribe_form;
var name = form.name.value;
var email = form.email.value;
if (name == '' || email == '')
{
alert('You must enter both your name and email address!');
return false;
}
else if (!email.match(regex))
{
alert('You must enter a valid email!');
return false;
}
return true;
}
function checkForm2()
{
var form = document.forms.unsub_form;
var email = form.email.value;
if (email == '')
{
alert('You must enter an email address!');
return false;
}
return true;
}
</script>
If you use POST method into your forms all parameters should be passed through INPUT html elements (i.e. action="index.php?subscribe=go" and action="index.php?unsub=go" are wrong).
The <form> tag doesn't exist? Unless you have code that tailors the output to the USER_AGENT, any browser that passes a given set of GET/POST input to the page should receive identical output. It's possible, of course, that they'll render the page and respond to events in (potentially significantly) different ways, but the source code should be identical.
Post the page source and we can look and see what the issue might be.
This was an outlandish WAMP issue. I had some other PHP code in the file that generated a WAMP error (but no error on the live site) that I've been ignoring because it is meaningless. 'Undefined index' is what it's called and the error appears when you call a PHP variable using $_POST[example] instead of $_POST['example']. Most ridiculous.
So WAMP spit out a bunch of HTML (error <table>s) that got mixed up with the other form on my page. IE can handle the messed up form being there and my form (shown in question) worked normally, while FF/Chrome cannot.
Hope this helps someone.

Categories