CakePHP: добавлять поля для формирования (динамически)

Я пытаюсь динамически добавлять поля в форму CakePHP, но кажется, что каждый использованный мной метод имел свои собственные недостатки, которые я не мог исправить. Вот что я пробовал:

  • Не добавляйте новый вход, просто разделяйте значения в одном входе с запятой. Это было довольно легко, с некоторыми проблемами при попытке взорвать входные данные и сохранить каждое значение в новой строке в базе данных. Но я отказался от этой идеи, когда мне пришлось отредактировать эти значения... собрать все значения и взорвать их во входе, а затем, когда я сохраню, проверьте, все ли все еще есть, если нет, удалите соответствующую строку из таблицы..Для большой работы.

  • Я пытался создавать новые входы "на лету" с JS. Но здесь я наткнулся на 2 проблемы: компонент безопасности, который бросал попытку черной дыры (и мне действительно нужен этот компонент для проверки целостности формы) и тот факт, что если проверка не удалась, мои входы исчезнут вместе со своими значениями, Я должен добавить, что у одной Модели могут быть неограниченные поля, поэтому входы будут чем-то вроде name=[Model][14][field], name=[Model][17][field], поэтому я не могу ограничить компонент безопасности не проверять эти определенные входы (я знаю их идентификаторы только тогда, когда добавляю их с помощью JS, в любом случае, путь после того, как компонент безопасности строит свои данные).

  • Добавление полей в PHP (поэтому перезагрузите страницу после добавления нового поля), но я не могу понять, как добавить поле точно после другого текущего поля, а также, как сохранить входные данные при ошибках проверки.

Любое предложение высоко ценится!

Спасибо!

Ответы

Ответ 1

Я не уверен, что могу дать вам полный ответ на ваш вопрос, но, надеюсь, я могу дать вам пару идей.

Я оказался в аналогичной ситуации при попытке создать систему для опросов.

В каждом опросе было много PollOptions, и я хотел, чтобы было возможно динамически добавлять столько параметров опроса, сколько необходимо на моей странице опросов /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 был установлен в PollController. Если в опросе уже были указаны PollOptions, они также были включены в $this->data. Кроме того, если форма уже была отправлена ​​и были ошибки проверки, все необходимые поля PollOption были построены снова, когда страница отображалась, поскольку они все еще находились в $this->data от контроллера.

Итак, я позаботился о том, чтобы у меня всегда были поля, которые мне нужны в представлении.

Когда форма была отправлена, я попытался сохранить данные с помощью простого

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

(Вы можете проверить API или документы CakePHP, если вы не уверены в синтаксисе выше)

Я использовал 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);
});

Вы упомянули, что делали это сами, но не должны беспокоиться об этом, если вы не пытаетесь использовать компонент безопасности в форме.

Надеюсь, это поможет указать вам в правильном направлении или, может быть, дать вам несколько идей.

Ответ 2

в некотором случае это решение:

 var optionCount = $('#poll-options > div').size() + 1;

может переопределять ваши старые данные в сценарии, когда торт находит существующий id (optionCount) в db. если u добавляет новый индекс итерации данных, должен генерироваться генератором uniq.