我了解here如何在CakePHP 3.x中添加或编辑CoursesMemberships
时将数据保存到连接表student
的字段中。要为许多grades
添加courses
,我可以使用add
和edit
表单执行此操作:
echo $this->Form->control('courses.0.id', ['type' => 'select', 'options' => $courses]);
echo $this->Form->control('courses.0._joinData.grade');
echo $this->Form->control('courses.1.id', ['type' => 'select', 'options' => $courses]);
echo $this->Form->control('courses.1._joinData.grade');
echo $this->Form->control('courses.2.id', ['type' => 'select', 'options' => $courses]);
echo $this->Form->control('courses.2._joinData.grade');
...
但是这个形式:
courses
都有固定数量student
; course id
('type' => 'select'
); grade
字段可以保留为空,但仍然是。)有没有办法让一个更简单的表单,其中列出了所有courses
,只有course
参加了一个复选框并输入相应的grade
?我发现使用control
...
修改
在@ndm
提出了一个非常好的方法之后,我在add.ctp
:
foreach ($courses as $key => $course) {
echo $this->Form->control('courses.'.$key.'.id', ['type' => 'checkbox', 'hiddenField' => false, 'value' => $key,
'label' => $key]);
echo $this->Form->control('courses.'.$key.'._joinData.grades');
}
并相应更正StudentsTable.php
。它运行没有问题。
但是,如果我在edit.ctp
中执行相同操作,则之前保存的记录(例如1,3,5和7 courses
现在列为1,2和3,显示{{1}对于前第3和第5 grades
而且表单强制我检查这三个框。我知道第一条记录消失了,因为我的courses
以courses
开头(所以因此缺少循环中的$ key和' courses.0.id'但一般的问题是id=1
中beforeMarshal
函数不再识别由edit.ctp
函数删除的空字段表格,我找不到合理的方式来编辑student's
记录。
答案 0 :(得分:1)
没有支持你想要实现的目标,你必须提出一个自定义解决方案,这可能需要混合使用表单和编组逻辑,或者JavaScript。
您可以创建一个复选框列表,并使用id
值(如果未选中复选框,则为零;如果 选中)在编组之前从提交的数据中删除未经检查的条目,如下所示:
echo $this->Form->control('courses.0.id', [
'type' => 'checkbox',
'value' => $courses[0]->id,
'label' => $courses[0]->title
]);
echo $this->Form->control('courses.0._joinData.grade');
echo $this->Form->control('courses.1.id', [
'type' => 'checkbox',
'value' => $courses[1]->id,
'label' => $courses[1]->title
]);
echo $this->Form->control('courses.1._joinData.grade');
// ...
// in the `StudentsTable` class
public function beforeMarshal(\Cake\Event\Event $event, \ArrayObject $data, \ArrayObject $options)
{
forach ($data['courses'] as $key => $course) {
if (empty($course['id'])) {
unset($data['courses'][$key])
}
}
}
或者,您可以使用JavaScript来禁用与复选框相关的控件,这样它们就不会被提交。为了使其正常工作,您需要确保禁用默认情况下为复选框生成的隐藏字段(请参阅hiddenField
选项),否则将为未选中的复选框发送零。< / p>
这是一个快速,未经测试的jQuery示例来说明原理:
echo $this->Form->control('courses.0.id', [
'class' => 'course-checkbox',
'data-join-data-input' => '#course-join-data-0',
'type' => 'checkbox',
'hiddenField' => false, // no fallback, unchecked boxes aren't being submitted
'value' => $courses[0]->id,
'label' => $courses[0]->title
]);
echo $this->Form->control('courses.0._joinData.grade', [
'id' => 'course-join-data-0',
'disabled' => true
]);
// ...
$('.course-checkbox').each(function () {
var $checkbox = $(this);
var $joinDataInput = $($checkbox.data('join-data-input'));
$checkbox.on('change', function () {
$joinDataInput.prop('disabled', !$checkbox.prop('checked'));
});
});
另见