CakePHP 3动态表单字段

时间:2017-08-22 08:53:47

标签: php cakephp save cakephp-3.0

我尝试将此教程https://waltherlalk.com/blog/dynamic-form-input-fields 实施到CakePHP 3 ,一切正常,直到我提交表单。它不会保存任何等级。我在这里读了很多帖子,但没有任何帮助。

我猜控制器有问题,所以这是我的控制器:

    public function add()
{
    $student = $this->Students->newEntity();
    if ($this->request->is('post')) {
        $student = $this->Students->patchEntity($student, $this->request->getData()); 
        if ($this->Students->save($student, ['associated' => ['Grades']])) {
            $this->Flash->success(__('The student has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The student could not be saved. Please, try again.'));
    }
    $this->set(compact('student'));
    $this->set('_serialize', ['student']);
}

Grades.ctp:

 <?php
    $key = isset($key) ? $key : '{{ key }}';
    // I changed <%= key %> to {{ key }}
?>
<tr>
    <td>
        <?php echo $this->Form->hidden("grade.{$key}.id") ?>
        <?php echo $this->Form->text("grade.{$key}.subject",array("id"=>"grade{$key}Subject")); ?>
    </td>   
    <td>
        <?php echo $this->Form->select("grade.{$key}.grade", array(
            'A+',
            'A',
            'B+',
            'B',
            'C+',
            'C',
            'D',
            'E',
            'F'
        ), array(
            'empty' => '-- Select grade --',
            "id"=>"grade{$key}grade"
        )); ?>
    </td>
    <td class="actions">
        <a href="#" class="remove">Remove grade</a>
    </td>
</tr>

并添加.ctp:

<?php
/**
  * @var \App\View\AppView $this
  */
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('List Students'), ['action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('List Grades'), ['controller' => 'Grades', 'action' => 'index']) ?></li>
        <li><?= $this->Html->link(__('New Grade'), ['controller' => 'Grades', 'action' => 'add']) ?></li>
    </ul>
</nav>
<div class="students form large-9 medium-8 columns content">
    <?= $this->Form->create($student) ?>
    <fieldset>
        <legend><?= __('Add Student') ?></legend>
        <?php
            echo $this->Form->control('name');
        ?>
    </fieldset>

    <fieldset>
    <legend><?php echo __('Grades');?></legend>
    <table id="grade-table">
        <thead>
            <tr>
                <th>Subject</th>
                <th>Grade achieved</th>
                <th>&nbsp;</th>
            </tr>
        </thead>
        <tbody></tbody>
        <tfoot>
            <tr>
                <td colspan="2"></td>
                <td class="actions">
                    <a href="#" class="add">Add grade</a>
                </td>
            </tr>
        </tfoot>
    </table>
</fieldset>

<script id="grade-template" type="text/x-underscore-template">
    <?php echo $this->element('grades');?>
</script>

    <?= $this->Form->button(__('Submit')) ?>
    <?= $this->Form->end() ?>
</div>

<script>
    $(document).ready(function() {
        //I changed undescore default template settings
        _.templateSettings = {
          interpolate: /\{\{(.+?)\}\}/g
        }

        var
            gradeTable = $('#grade-table'),
            gradeBody = gradeTable.find('tbody'),
            gradeTemplate = _.template($('#grade-template').remove().text()),
            numberRows = gradeTable.find('tbody > tr').length;

        gradeTable
            .on('click', 'a.add', function(e) {
                e.preventDefault();

                $(gradeTemplate({key: numberRows++}))
                    .hide()
                    .appendTo(gradeBody)
                    .fadeIn('fast');
            })
            .on('click', 'a.remove', function(e) {
                    e.preventDefault();

                $(this)
                    .closest('tr')
                    .fadeOut('fast', function() {
                        $(this).remove();
                    });
            });

            if (numberRows === 0) {
                gradeTable.find('a.add').click();
            }
    });
</script>

调试:

/src/Controller/StudentsController.php (line 55)
[
    'name' => 'asdad',
    'grade' => [
        (int) 0 => [
            'id' => '',
            'subject' => 'adsads',
            'grade' => '0'
        ]
    ]
]
/src/Controller/StudentsController.php (line 56)
object(App\Model\Entity\Student) {

    'name' => 'asdad',
    'grade' => [
        (int) 0 => [
            'id' => '',
            'subject' => 'adsads',
            'grade' => '0'
        ]
    ],
    '[new]' => true,
    '[accessible]' => [
        '*' => true,
        'id' => false
    ],
    '[dirty]' => [
        'name' => true,
        'grade' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[errors]' => [],
    '[invalid]' => [],
    '[repository]' => 'Students'

}

如果您了解任何其他教程如何将动态表单实现到添加页面,请告诉我。谢谢。

1 个答案:

答案 0 :(得分:1)

您的成绩数据未转换为实体,如调试输出中所示,它只是一个数组,表示您的目标是错误的属性。

按照惯例,hasMany关联的实体关联属性是关联别名的下划线复数变体,因此如果名为Grades的关联,则为grades,而不是grade

因此,请务必将所有grade.{$key}grade{key}内容重命名为grades.{$key}grades{$key}

另见