How to get cloned radio buttons to pass their valu

2019-07-23 03:07发布

问题:

I have an RSVP form (http://adrianandemma.com/) with a name field and a radio for 'Attending - Yes/No'. You can clone these fields to RSVP for more that one guest at a time.

I'm trying to carry these field values through to a form process script to send me the RSVPs by email.

The name fields are coming through fine, but the radio button values all come through blank.

Can see why this might be happening?

Here's my HTML form:

<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[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>
            </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>

Here's 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 = "example@xyz.com";
        $subject = "Wedding RSVP";
        $headers = "From: noreply@adrianandemma.com";
        $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 the JS that clones the fields:

$('.addguest').on('click', function(e) {
        e.preventDefault();
        var i = $('.guest').length;
        $('.guest').first().clone().find("input").attr('id', function(idx, attrVal) {
            return attrVal + i;
        }).attr('name', function(idx, attrVal) {
            return attrVal.replace('[0]','')+'['+i+']'; // fix is here
        }).val('').removeAttr('checked').end().find('label').attr('for', function(idx, attrVal) {
            return attrVal + i;
        }).end().insertBefore(this);
    });

And here's what I'm receiving by email:

The following RSVP has been sent via the website.

        Name 1 : Amy Jones
        Coming 1 : Yes

        Name 2 : Daren Jones
        Coming 2 : 

        Name 3 : Carl Jones
        Coming 3 : 

Date Received: 19 April 2017, 3:19 pm

Here's what my printed array looks like currently:

Array
(
    [submit] => 1
    [name] => Array
        (
            [0] => Dave Jones
            [1] => Amy Jones
            [2] => Mary Jones
        )

    [coming] => Array
        (
            [0] => Yes
            [1] => 
            [2] => 
        )

)

回答1:

The final problem appears to have been the .val('') in your chain.

Since it was referencing all the inputs, it was removing the value of the radio buttons as well. Without values, they passed nothing to the backend when they were checked.

The code below separates actions into those actions common to all the inputs (updating the id and name), then removes the value from just the text field, and then removes the checked attribute from just the radio buttons. Finally, it updates the for attribute of the labels and does the insert.

$('.addguest').on('click', function(e) {
    e.preventDefault();
    var i = $('.guest').length;

    var row = $('.guest').first().clone();

    //Handle the things common to all inputs
    row.find('input')
        .attr('id', function(idx, attrVal) {
            return attrVal + i;
        })
        .attr('name', function(idx, attrVal) {
            return attrVal.replace('[0]','')+'['+i+']'; // fix is here
        });

    //Handle the text input
    row.find('input[type="text"]').val('');

    //Handle the radio buttons
    row.find('input[type="radio"]').removeAttr('checked');

    //Handle the labels
    row.find('label').attr('for', function(idx, attrVal) {
        return attrVal + i;
    });

    row.insertBefore(this);
});

I've tested it in chrome and see that it provides the correct data to the backend - if there are further issues then we know to focus in on the PHP code from here-on-out (assuming this does do the trick for you in sending the right data).



回答2:

When you duplicated the Yes and No checkboxes you forgot to set their values. I inspected the HTML, the values are blank !

You can add these two lines at the end of your click function :

$('.coming-yes').val('Yes');
$('.coming-no').val('No');