tags:

views:

84

answers:

4

I have a form with inputs for 'name' and 'email'. And another for 'data-1'. The user can click on add button and jQuery will dynamically add a input for 'data-2', 'data-3' etc..as needed.

The form is posted to a PHP emailer script which validates fields and places data into a template for mailing.

How can i add inputs 'data-2', 'data-3' etc.. if they are created? And if they are not how can i avoid gaps in my email template?

(is there a way to write it so if the post is received add this and if not do nothing?)

Here is an example of the code i am using:

$name = $_POST['name'];
$email = $_POST['email'];
$data-1 = $_POST['data-1'];

(do i need to add: $data-2 = $_POST['data-2'] and $data-3....up to a set value of say 10?)

$e_body = "You were contacted by $name today.\r\n\n";
$e_data = "Data Set 1: $data-1.\r\n\n"; 

Here is where i would like to show "Data Set 2/3/4....etc" if they exist

$e_reply = "You can contact $name via email, $email";

$msg = $e_body . $e_data . $e_reply;

if(mail($address, $e_subject, $msg, "From: $email\r\nReply-To: $email\r\nReturn-Path: $email\r\n")) {

I hope that is clear and thank you for any help or guidance

thom

+2  A: 

You should be using input arrays for this purpose.

In your HTML, set the name of the form element to conform to this naming scheme: data[].

Then, when the form is submitted you can simply loop through this array and add fields to the email within the loop:

$name = $_POST['name'];
$email = $_POST['email'];
$data = $_POST['data'];
$e_data = '';

foreach($data as $i => $d) {
   if((int) $i != $i) continue; //thanks Alex
   $e_data .= "Data Set {$i}: " . $d . "\r\n\n";
}

//...

On the client side, your code should be something like this:

<input type="hidden" name="data[]"/>
Jacob Relkin
Not a fan of `foreach` ?
alex
If the array being passed in isn't an associative array, you can use `foreach($data as $i => $field)`. That said, it doesn't mean that a, potentially malicious, user can't pass in an associative array. Of course, one can guard against this.
George Marian
I think I've always used `foreach` with a `if ((int) $key != $key) continue;` but yeah I suppose it doesn't matter either way. Even with the `for` loop, however, one could send a non numerical key (and cause problems with the loop). Edit: I got rid of `is_int()` because I *think* PHP gets those keys as strings by default.
alex
hi thanks for reply, unfortuantely i am getting this error:Parse error: syntax error, unexpected T_IF inerror refers to line starting with if((int)am i doing something wrong?
thom
@thom, sorry i had a typo in there. Try again with my revised code.
Jacob Relkin
thanks again, i tried the new code and the script passes but it does not input the data. just name and email
thom
@thom, did you make sure to append `[]` to your input `name`s in your HTML?
Jacob Relkin
would you be able to take a look at --- http://designsbythom.com/meter/test.html --- also getting an error on line 15 although the mail does send
thom
yes i appended [] - sorry if your are looking at the code and its a bit messy and more complicated than original question. thank you so much for your help
thom
hang on was it supposed to be [ ] or [] - difference being space between -- does that make a difference?
thom
@thom, There's no difference as far as I know. Hit me up on AIM. It's a lowercase version of my name joined together.
Jacob Relkin
@thom, I can't do it right now though. I've gotta go to sleep. I'm on the US east coast, it's 2am now. I'll be back online at ~10am tomorrow.
Jacob Relkin
ok, thank you for your help
thom
A: 

Use something like this:

if(isset($_POST['data-1']))
{
    // $_POST['data-1'] exists, include it.
}
else
{
    // $_POST['data-1'] doesn't exists, don't include it.
}
Dani
A: 

As a general point form processing is trick and has many traps for the unwary. It's worth having a look at this post on best practice form processing

The crux of your problem is that you do not know how many "data" values you will get in your $_POST array. The answer is simply to iterate over the $_POST array to find your data values.

$rawData = array();
foreach ($_POST as $index => $value) {
// Test for a "data-n" index
    if ((preg_match('#^data-\d+#i', $index, $matches))) {
        $rawData[] = $value;
    }
}

The above code will copy all the $_POST values with keys of the form 'data-0', 'data-1', etc. You can then filter and validate these values.

All we do is iterate over $_POST to get each key and value. We then test the key using preg_match to see if it starts with the string 'data-' and is followed by one or more digits. If so, we add it to our raw (unfiltered, non validated) data.

In this example, we could replace the preg_match with the strpos function -

if ( strpos  ($index, 'data-') === 0) {

The use of the preg_match gives us more flexibility. For example, if you wanted to capture the numeric portion of your 'data-n' keys - 'data-23', 'data-999', 'data-5', etc. Then change the if statement to

if ((preg_match('#^data-(\d+)#i', $index, $matches))) {
    $rawData[$matches[1]] = $value;
}

The variable $matches is an array that captures the results of the search. The complete matching string is is $matches[0]. However, we have enclosed the digit matching pattern in parenthesis and hence the captured digits are placed into $matches1 which we then use to key the $rawData array. In this case $rawData would have the keys = 23, 999 and 5.

thank you for replying, this is going over my head a bit, will take a while to try and understand it, this is my first time using php really
thom
A: 

i am at this point now and i feel so close but just cannot get some of the data in the email.

would you be able to take a look at --- designsbythom.com/meter/test.html

the Php is as follows ;

<?php

if(!$_POST) exit;

    $name = $_POST['name'];
    $account = $_POST['account'];
    $email = $_POST['email'];
    $printer = $_POST['printer'];
    $serial = $_POST['serial'];
    $mono = $_POST['mono'];
    $colour = $_POST['colour'];
    $express = $_POST['express'];


    foreach($data as $i => $d) {
       if((int) $i != $i) continue; //thanks Alex
       $e_content .= "Data Set {$i}: " . $d . "\r\n\n";
    }

    $e_content = '';

    if(trim($name) == '') {
        echo '<div class="error_message">Attention! You must enter your name.</div>';
        exit();

a bit more validation here but currently turned off

$address = "[email protected]";

$e_subject = 'You\'ve been contacted by ' . $name . '. Account Number ' . account . '.';

$e_body = "You have been contacted by $name , account number $account, their meter readings are as follows.\r\n\n";


     $e_reply = "You can contact $name via email, $email";

     $msg = $e_body . $e_content . $e_reply;

     if(mail($address, $e_subject, $msg, "From: $email\r\nReply-To: $email\r\nReturn-Path: $email\r\n")) {


     // Email has sent successfully, echo a success page.

     echo "<fieldset>";         
     echo "<div id='success_page'>";
     echo "<h1>Email Sent Successfully.</h1>";
     echo "<p>Thank you <strong>$name</strong>, your message has been submitted to us.</p>";
     echo "</div>";
     echo "</fieldset>";

     } else {

     echo 'ERROR!';

     }

}

function isEmail($email) { // Email address verification, do not edit.

return(preg_match("/^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+(ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$/i",$email));

}
?>

how can i display the mono, colour and express input in a nice format, so the recipient of email can clearly see the printer with corresponding serial# and meter reading?

i know this is a big ask but i really appreciate everyones help

thom