如何最好地格式化单选按钮数组并在 $_POST 中捕获

Posted

技术标签:

【中文标题】如何最好地格式化单选按钮数组并在 $_POST 中捕获【英文标题】:How best to format radio button array and capture in $_POST 【发布时间】:2017-09-14 23:56:24 【问题描述】:

我正在努力设置我正在尝试设置的 RSVP 表单,任何帮助都会很棒!

到目前为止,我有这个表格http://adrianandemma.com/,我想在提交后给我发送一封简单的电子邮件。

表单有一个“姓名”字段和一个用于“参加 - 是/否”的单选按钮。

然后我有一些 JS,您可以将这些字段克隆到一次为多个客人的 RSVP。

“名称”字段作为数组传递并通过电子邮件传递,因为我可以将输入的名称属性设置为 name="name[]",但我在使用收音机时遇到问题按钮。

我不能为克隆的单选按钮保留相同的“名称”属性,因为如果这样做,我只能为一个克隆的行选择是/否,因为所有克隆的单选按钮都具有相同的名称,所以我有添加了一些 JS 以尝试将任何克隆无线电的名称修改为 'coming[1],coming[2], etc'。

虽然我不能完全让它工作,因为每次我提交表单时,单选按钮的值似乎都是空白的。

谁能建议将单选按钮设置为数组并通过 $_POST 并最终通过电子邮件脚本执行的最佳方法?

这是我的 html 表单:

<?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>

她的我的表单处理代码:

<?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 = "xxx@example.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);
    

?>

这是我的 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);
    );

);

这是我目前通过电子邮件收到的一个示例,名称通过正常,但“是/否”的单选值都是空白的:

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

【问题讨论】:

您应该首先清除克隆的行字段内容 一张图片可以节省 1000 个单词,而使用 @ 错误抑制符号会导致 1000 艘船沉没 问题出在您的 javascript 代码中。 FWIW,我可以告诉您,就您的收音机命名'coming[1]coming[2] 等而言,您的想法是正确的;如果您使用这些名称创建一个直接的 HTML 表单,您将按照您的期望将它们的值作为一个数组获取,但是您的 JS 没有正确设置名称,而且我没有足够的 JS 人员来调试它。 【参考方案1】:

老实说,我的最佳猜测是,在原始行中,您的无线电输入的名称只是“即将到来”,没有括号。我认为因为该名称上没有括号,所以它破坏了应该作为数组运行的其他同名名称。换句话说,PHP 会为同名输入获取两种冲突的类型,并通过数组获取字符串。

如果不直接测试就很难说,而且输入在 PHP 表单处理程序中被引用为数组并且不会引发错误这一事实往往会向我暗示我不太正确,但它可能值得一试。

这是我要尝试的对 HTML 的更改:

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

请注意,我特别将第一行标记为第零行,因为 PHP 使用零索引数组。

这将需要对您的 javascript 进行一些更改。我发现为您的行 HTML 创建一个实际模板并使用它比每次尝试克隆第一行并重置所有输入并调整名称更容易。它的工作方式是在脚本标签内定义模板 HTML,其中包含非标准的 ID 和类型。浏览器会忽略它,但 JavaScript 可以像访问任何其他元素一样访问它,我们可以使用 jQuery 的 html() 方法提取内容。

这是我想出的(包括修复您的索引):

<!-- 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>

请注意这是未经测试的代码。当然,我已经经历了几次以确保我抓住了所有明显的错误,但其他人可能会坚持下去。由于我不能主动测试它,我不能说它完全没有错误。但是,希望它作为伪代码可以帮助您解决问题。


编辑 1

澄清一下,您通常必须手动在输入名称的括号内提供索引值,以便 PHP 将输入解释为数组并在适当的位置自动索引输入命令。我特别将第一个输入设置为使用[0],因为它们之后的所有输入还需要指定索引值才能使您的单选按钮工作(我个人很欣赏一致性),并且因为我们需要绝对确定正确的名称与正确的 RSVP 值相匹配(只是想彻底)。

【讨论】:

感谢以上详细建议。我已经尝试过实现这一点,但是一旦我将它包装在

以上是关于如何最好地格式化单选按钮数组并在 $_POST 中捕获的主要内容,如果未能解决你的问题,请参考以下文章

如何以单选按钮格式显示问题和答案的数组列表?使用 JSP 和 servlet

如何使用 PHP OOP 插入多个单选按钮值

当数据来自数据库时,如何一次只选择一个单选按钮并在javascript中取消选择其他单选按钮?

$.post,单选按钮值,jquery

MFC 中的广播组

如果页面重新加载,如何在表单上保留对单选按钮的选择