Reputation: 2833
I'm really struggling with an RSVP form I'm trying to set-up and any help would be great!
I have this form so far http://adrianandemma.com/ which I am trying to get to send me a simple email once submitted.
The form has a 'Name' field and a radio button for 'Attending - Yes/No'.
I then have some JS whereby you can clone these fields to RSVP for more than one guest at a time.
The 'Name' fields are passing through fine as an array and coming through by email, as I can just set the name attribute of the input to name="name[]", but I'm having trouble with the radio buttons.
I can't leave the 'name' attribute the same for the cloned radio buttons, because if I do I can only select yes/no for one cloned row, as all the cloned radios have the same name, so I have added a bit of JS to try to amend the name of any cloned radios to 'coming[1], coming[2], etc'.
I can't quite get this to work though, as every time I submit the form the radio button values appear to come through blank.
Can anybody advise the best approach to setting up radio buttons as an array and to carry them through via $_POST and ultimately an email script?
Here's my HTML form:
<?php
if(@$_REQUEST['submit'] == '1') {
include('assets/forms/rsvp.php');
}
?>
<form action="?" method="post">
<?php if(@$errors) :?>
<p class="errors"><?php echo $errors; ?></p>
<?php endif; ?>
<input type="hidden" name="submit" value="1" />
<div class="form-row">
<div class="field-l">
<p>Name</p>
</div>
<div class="field-r">
<p>Attending?</p>
</div>
</div>
<div class="form-row guest">
<div class="field-l">
<input type="text" name="name[]" id="name" value="<?php echo htmlspecialchars(@$_REQUEST['name']); ?>" tabindex="1" />
</div>
<div class="field-r">
<input type="radio" name="coming" id="coming-yes" class="coming-yes" value="Yes"><label for="coming-yes">Yes</label><input type="radio" name="coming" id="coming-no" class="coming-no" value="No"><label for="coming-no">No</label>
</div>
</div>
<a class="addguest" href="#">Add further guest</a>
<div class="form-row">
<button type="submit" id="rsvp-submit" tabindex="2">Submit RSVP</button>
</div>
</form>
Hers My Form Process code:
<?php
$name = $_POST['name'];
$coming = $_POST['coming'];
$errors = "";
if(!@$_POST['name']) { $errors .= "Please enter your name.<br/>\n"; }
if(!@$_POST['coming']) { $errors .= "Please enter yes or no for attending.<br/>\n"; }
if(@$_POST['emailaddress'] != '') { $spam = '1'; }
if (!$errors && @$spam != '1')
{
$to = "[email protected]";
$subject = "Wedding RSVP";
$headers = "From: [email protected]";
$body = "The following RSVP has been sent via the website.\n\n";
for($i=0; $i < count($_POST['name']); $i++) {
$body .= "
Name ".($i+1)." : " . $_POST['name'][$i] . "\n
Coming ".($i+1)." : " . $_POST['coming'][$i] ."\n\n";
}
$body .= "\n\nDate Received: " . date("j F Y, g:i a") . "\n";
mail($to,$subject,$body,$headers);
}
?>
Here's my JS:
$(document).ready(function() {
$('.addguest').on('click', function(e) {
e.preventDefault();
//
// get the current number of ele and increment it
//
var i = $('.guest').length + 1;
$('.guest').first().clone().find("input").attr('id', function(idx, attrVal) {
return attrVal + i; // change the id
});
$('.guest').first().clone().find("input[type=radio]").attr('id', function(idx, attrVal) {
return attrVal + i; // change the id
}).attr('name', function(idx, attrVal) {
return attrVal+'['+i+']'; // change the name
}).val('').end().find('label').attr('for', function(idx, attrVal) {
return attrVal + i; // change the for
}).end().insertBefore(this);
});
});
Here's an example of what I'm receiving by email currently, names come through fine, but radio values for 'Coming Yes/No" are all blank:
The following RSVP has been sent via the website.
Name 1 : John Doe
Coming 1 :
Name 2 : Ann Doe
Coming 2 :
Name 3 : Fred Doe
Coming 3 :
Date Received: 19 April 2017, 1:04 am
Upvotes: 0
Views: 414
Reputation: 2830
Honestly, my best guess is that in the original row, the names of your radio inputs are simply "coming", without the brackets. I think that because there are no brackets on that name, it is clobbering the other ones of the same name that should behave as an array. In other words, PHP is getting two conflicting types for an input of the same name, and taking the string over the array.
Hard to say without testing it directly, and the fact that the input is referenced as an array in your PHP form handler and doesn't throw an error would tend to suggest to me I'm not quite right, but it may be worth a try.
Here's the change to the HTML I would try:
<div class="field-l">
<input type="text" name="name[0]" id="name" value="<?php echo htmlspecialchars(@$_REQUEST['name']); ?>" tabindex="1" />
</div>
<div class="field-r">
<input type="radio" name="coming[0]" id="coming-yes" class="coming-yes" value="Yes">
<label for="coming-yes">Yes</label>
<input type="radio" name="coming[0]" id="coming-no" class="coming-no" value="No">
<label for="coming-no">No</label>
</div>
Notice I specifically marked the first row as row zero, as PHP uses zero-indexed arrays.
This would then require some changes to your javascript. I've found it was easier to create an actual template for your row HTML and use that than to try and clone the first row each time and reset all the inputs and adjust the names. The way this works is you define your template HTML inside a script tag with an ID and a type that is non-standard. The browser ignores it, but JavaScript can access it just like any other element and we can pull the content out with jQuery's html()
method.
Here's what I've come up with (including a fix of your indexing):
<!-- A script with a non-standard type is ignored by the browser -->
<!-- We can reference it by ID in our JS though, and pull out the HTML -->
<script id="guest-row-template" type="text/template">
<div class="form-row guest">
<div class="field-l">
<input type="text" name="" id="name" class="name-ipt" />
</div>
<div class="field-r">
<input type="radio" name="" id="" class="coming-yes coming-yes-ipt" value="Yes" />
<label for="" class="coming-yes coming-yes-label">Yes</label>
<input type="radio" name="" id="" class="coming-no coming-no-ipt" value="No" />
<label for="" class="coming-no coming-no-label">No</label>
</div>
</div>
</script>
<script type="text/javascript">
$(document).ready(function() {
$('.addguest').on('click', function(e) {
e.preventDefault();
//Get the number of rows we have already - this is the index of the *next* row
//If we have 1 row, the first row's index is 0 and so our next row's index should be
//1, which is also our length, no need to increment
var i = $('.guest').length;
//Get HTML template content for a single row
var row = $('#guest-row-template').html();
//Update the name attribute of the name input
row.find('.name-ipt').attr('name', 'name[' + i + ']');
//Update the name and id attributes of the yes radio button
row.find('.coming-yes-ipt').attr('name', 'coming[' + i + ']');
row.find('.coming-yes-ipt').attr('id', 'coming-yes-' + i);
//Update the name and id attributes of the no radio button
row.find('.coming-no-ipt').attr('name', 'coming[' + i + ']');
row.find('.coming-no-ipt').attr('id', 'coming-no-' + i);
//Update the for attribute of the yes label
row.find('.coming-yes-label').attr('for', 'coming-yes-' + i);
//Update the for attribute of the no label
row.find('.coming-no-label').attr('for', 'coming-no-' + i);
row.insertBefore(this);
});
});
</script>
Please note this is untested code. Of course I've gone through a few times to make sure I caught all my obvious bugs, but others may persist. Since I can't actively test it, I can't say it's entirely bug free. But, hopefully as pseudo-code it helps you resolve the issue.
EDIT 1
Just to clarify, you don't ordinarily have to manually provide the index values within the brackets of input names for PHP to interpret the input as an array and to automatically index the input in the appropriate order. I specifically set the first inputs to have use [0]
because all the inputs after them will also need to specify index values in order for your radio buttons to work (I personally appreciate consistency), and because we need to be absolutely sure that the correct names are matched to the correct RSVP value (just trying to be thorough).
Upvotes: 0