CakePHP:添加表单(动态)

时间:2011-05-14 13:20:25

标签: forms cakephp

我正在尝试动态地将字段添加到我的CakePHP表单中,但似乎我使用的每个方法都有自己的缺点,我无法修复。这是我试过的:

  1. 不要添加新输入,只需用逗号分隔单个输入中的值即可。这似乎很容易,在尝试爆炸输入并将每个值保存在数据库中的新行时会出现一些问题。但是当我不得不编辑这些值时,我放弃了这个想法...收集所有值并将它们内插在输入中,然后当我保存时检查是否所有值仍然存在,如果没有,则从表中删除相应的行。 。要做很多工作。

  2. 我尝试使用JS动态创建新输入。但在这里,我偶然发现了两个问题:安全组件,它正在抛出黑洞尝试(我真的需要这个组件来检查表单的完整性)以及如果验证失败,我的输入将与它们的值一起消失。我必须补充说,单个模型可能有无限字段,因此输入类似于name=[Model][14][field], name=[Model][17][field],因此我不能限制安全组件不要验证那些特定输入(我只知道他们添加它们时的ID)无论如何,在安全组件构建其数据之后使用JS。

  3. 使用PHP添加字段(因此,在添加新字段后重新加载页面),但我似乎无法找到如何在另一个当前字段之后准确添加字段,以及如何维护验证错误时输入的数据。

  4. 任何建议都非常感谢!

    谢谢!

2 个答案:

答案 0 :(得分:14)

我不确定我能否完整回答你的问题,但希望我能给你一些想法。

在尝试为民意调查创建管理系统时,我发现自己处于类似情况。

每个民意调查都有很多民意调查,我想在民意调查/ admin_edit页面上根据需要动态添加多个民意调查选项。

我使用CakePHP的内置功能加上一些Javascript来管理它。

在admin_edit视图中构建表单时,我首先输入了Poll字段,然后我添加了这个:

<div id="poll-options">
<?php 
if (isset($this->data['PollOption'])) {
    $i = 0;
    foreach ($this->data['PollOption'] as $opt) {
        echo $form->hidden("PollOption.$i.id");
        echo $form->input("PollOption.$i.name", array('label' => "Option " . ($i + 1)));
        $i++;
    }
}
?>
</div>
在PollsController中设置了

$this->data。如果民意调查已经有相关的民意调查,那么它们也包含在$this->data中。此外,如果表单已经提交并且存在验证错误,则在显示页面时会再次构建所有需要的PollOption字段,因为它们仍然位于控制器的$this->data中。

因此,确保我始终拥有视图中所需的字段。

提交表单时,我尝试用简单的

保存数据
$this->Poll->saveAll($this->data, array('atomic' => false, 'validate' => 'first'));

(如果您不确定上述语法,可以查看CakePHP API或文档)

我使用Javascript(jQuery)动态添加PollOption字段:

$('#add-option-button').click(function(event){
    var optionCount = $('#poll-options > div').size() + 1;
    var inputHtml = '<div class="input text"><label for="PollOption' + optionCount + 'Name">Option ' + optionCount
        + '</label><input id="PollOption' + optionCount + 'Name" type="text" name="data[PollOption][' + optionCount + '][name]" /></div>';
    event.preventDefault();
    $('#poll-options').append(inputHtml);
});

你提到你自己这样做了,但是如果你不尝试使用表单上的安全组件,你就不会有任何麻烦。

希望这有助于指明您正确的方向,或者可能会给您一些想法。

答案 1 :(得分:1)

在某些情况下这个解决方案:

 var optionCount = $('#poll-options > div').size() + 1;
当蛋糕在db中找到现有id(optionCount)时,

可以覆盖场景中的旧数据。 如果你要添加新的数据迭代索引应该由uniq生成器生成..