Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP: add fields to form (dynamically)

Tags:

forms

cakephp

I am trying to dynamically add fields to my CakePHP form, but it seems that each method I used had its own downsides which I couldn't fix. Here is what I tried:

  1. Don't add a new input, just separate the values in a single input with a comma. It seemed pretty easy, with some problems when trying to explode the input and save each value in a new row in the database. But I abandoned the idea when I had to edit these values...gather all the values and implode them in an input, then when I saved check whether all values are still there, if not, delete the corresponding row from the table...To much work to do.

  2. I tried creating new inputs on the fly, with JS. But here, I stumbled upon 2 problems: the Security component, which was throwing a blackhole attempt (and I really need this component to check the integrity of the form) and the fact that if validation fails, my inputs will disappear together with their values. I must add that a single Model may have unlimited fields, so the inputs will be something like name=[Model][14][field], name=[Model][17][field], therefore I can't restrict the Security component not to validate those certain inputs (I know their IDs only when I add them with JS, anyway, way after the Security component builds its data).

  3. Adding fields with PHP (therefore, reload the page after a new field is added), but I cannot seem to find out how do I add a field exactly after another present field, and also, how to maintain the input's data upon validation errors.

Any suggestion is highly appreciated!

Thank you!

like image 422
linkyndy Avatar asked May 14 '11 13:05

linkyndy


2 Answers

I'm not sure I can give you a full answer to your question, but hopefully I can give you a couple ideas.

I found myself in a similar situation when trying to create an admin system for polls.

Each Poll had many PollOptions and I wanted to make it possible to dynamically add as many poll options as needed on my polls/admin_edit page.

I managed this with CakePHP's built-in functionality plus a bit of Javascript.

When building the form in the admin_edit view, I first put in the Poll fields and under that I added this:

<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 was set in PollsController. If the Poll already had related PollOptions, they were also included in $this->data. Also, if the form had already been submitted and there were validation errors, all the needed PollOption fields were built again when the page displayed because they were still in $this->data from the controller.

So that took care of making sure I always had the fields I needed in the view.

When the form was submitted, I attempted to save the data with a simple

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

(You can check the CakePHP API or docs if you're not sure of the above syntax)

I used Javascript (jQuery) to dynamically add the PollOption fields:

$('#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);
});

You mentioned you were doing this yourself, but you shouldn't have any trouble with it if you don't try to use the Security component on the form.

Hope this helps point you in the right direction, or maybe give you some ideas.

like image 107
Mark Northrop Avatar answered Oct 20 '22 16:10

Mark Northrop


in some case this solution:

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

can override your old data in scenario when cake find existing id (optionCount) in db. if u are adding new data iteration index should be generated by uniq generator..

like image 21
AgBorkowski Avatar answered Oct 20 '22 16:10

AgBorkowski