CakePHP:向表单添加字段(动态)
Posted
技术标签:
【中文标题】CakePHP:向表单添加字段(动态)【英文标题】:CakePHP: add fields to form (dynamically) 【发布时间】:2011-05-14 13:20:25 【问题描述】:我正在尝试向我的 Cakephp 表单动态添加字段,但似乎我使用的每种方法都有自己无法解决的缺点。这是我尝试过的:
不要添加新输入,只需用逗号分隔单个输入中的值。这似乎很容易,但在尝试分解输入并将每个值保存在数据库的新行中时会出现一些问题。但是当我不得不编辑这些值时我放弃了这个想法......收集所有值并将它们内爆到输入中,然后当我保存时检查所有值是否仍然存在,如果没有,则从表中删除相应的行.. .要做的工作很多。
我尝试使用 JS 动态创建新输入。但是在这里,我偶然发现了 2 个问题:Security 组件,它正在抛出黑洞尝试(我真的需要这个组件来检查表单的完整性)以及如果验证失败,我的输入将与它们的值一起消失的事实.我必须补充一点,单个模型可能有无限的字段,因此输入将类似于name=[Model][14][field], name=[Model][17][field]
,因此我不能限制安全组件不验证这些特定输入(我只有在使用 JS 添加它们时才知道它们的 ID ,无论如何,在安全组件构建其数据之后)。
使用 PHP 添加字段(因此,在添加新字段后重新加载页面),但我似乎不知道如何在另一个现有字段之后添加一个字段,以及如何维护验证错误时输入的数据。
非常感谢任何建议!
谢谢!
【问题讨论】:
不能肯定地说,但我认为不可能使用安全组件并向表单添加字段。保护表单的重点是校验和并确保没有添加或删除任何字段。您是否可以尝试在没有安全组件的情况下执行此操作并找到另一种方法来确保您的表单被锁定? 好的,假设我不使用安全组件。那么如何验证所有添加的字段,并在表单未验证时检索它们的值? 这是表单验证,在模型中完成。与安全组件所做的非常不同。我会将安全组件放在一边,除非您的应用程序绝对必须拥有它,并且只需验证模型中的表单输入。这里有更多关于验证输入的信息:book.cakephp.org/view/125/Data-Validation 问题是我的表单中有一个主模型,然后是所有关联的类别。此外,这些类别可以包含多个值,因此要保存的类别数量是动态的,我不知道如何准确检索填充了哪些类别以及它们的 id (Model.0.field
, Model.1.field
, .. ., Model.n.field
)
【参考方案1】:
我不确定我能否给你一个完整的答案,但希望我能给你一些想法。
在尝试创建投票管理系统时,我发现自己处于类似情况。
每个投票都有很多 PollOptions,我希望能够在我的 polls/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>
$this->data
在 PollsController 中设置。如果 Poll 已经有相关的 PollOptions,它们也包含在 $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);
);
您提到您自己正在执行此操作,但如果您不尝试使用表单上的安全组件,您应该不会遇到任何问题。
希望这有助于为您指明正确的方向,或者给您一些想法。
【讨论】:
听起来像我需要的。我的逻辑比较复杂,但我相信我会在你的详细示例之后处理它。非常感谢,正是我需要的! 表单生成是使用 jquery 手动(硬编码)完成的,而不是使用 cake 表单助手,这在生成大/许多表单时会有点混乱。我在想 - 有没有办法使用 Js 助手和表单助手来实现同样的效果? Ankan,我也想知道,我有一些非常复杂的表单,并且一直在使用 jQuery 的 .clone() 方法来复制 Cake 的自动生成的表单字段,然后使用 .replace( ),但我觉得它不是很健壮,宁愿 FormHelper 或 JsHelper 中有一个功能来支持 hasMany 关系的多个条目。 动态添加字段如何使用 cakephp 验证规则?因为如果你这样做,输入由 jquery(client size) 生成,你当然不会有任何验证规则,你可以制定客户端验证规则,但我们知道它不是那么安全。【参考方案2】:在某些情况下这个解决方案:
var optionCount = $('#poll-options > div').size() + 1;
当 cake 在 db 中找到现有 id (optionCount) 时,可以覆盖您的旧数据。 如果你正在添加新的数据迭代索引应该由 uniq 生成器生成..
【讨论】:
以上是关于CakePHP:向表单添加字段(动态)的主要内容,如果未能解决你的问题,请参考以下文章