Erik L
Erik L

Reputation: 1194

How to reduce form code duplication in CakePHP

I have a form in CakePHP with a few dozen fields in it. From all the examples I have seen, there is duplicate form code for an add view and an edit view.

Is there any tricks to keep the duplication out? What is best method in CakePHP for this?

Upvotes: 5

Views: 1585

Answers (6)

Sumit Kumar
Sumit Kumar

Reputation: 1902

in edit.ctp

if($this->data[ModelName]['id']) {
   $this->Form->input('id');
}

// create rest of the fields

in Controller::add()

$this->autoRender=false; // at the start of function

$this->render('edit.ctp'); // at the point where you actually want to render

no need to create add.ctp

Upvotes: 0

Usman Akram
Usman Akram

Reputation: 111

in your app controller

public function render($view = null, $layout = null) {

    $viewPaths = App::path('View', $this->plugin);
    $rootPath = $viewPaths[0] . DS . $this->viewPath . DS;
    $requested = $rootPath . $view . '.ctp';
    if (in_array($this->request->action, array('admin_edit', 'admin_add', 'edit', 'add'))) {
        $viewPath = $rootPath . $this->request->action . '.ctp';
        if (!file_exists($requested) && !file_exists($viewPath)) {
            if (strpos($this->request->action, 'admin_') === false) {
                $view = 'form';
            } else {
                $view = 'admin_form';
            }
        }
    }
    return parent::render($view, $layout);
}

and in your view you can always check whether its edit or add

   if ($this->request->params['action'] == 'admin_edit') {
    //do something
}
if ($this->request->params['action'] == 'admin_add') {
    //do something
}

Upvotes: 0

kaklon
kaklon

Reputation: 2432

What I do, is to put all form fields in an element, and then insert the element in the add.ctp and edit.ctp

Don't forget to add the hidden field with the id in the edit.ctp

This way all visible elements are in one file, easier to maintain.

View/MyModel/add.ctp
echo $this->Form->create('MyModel');
echo $this->element('my_form'); 
echo $this->Form->end();

View/MyModel/edit.ctp
echo $this->Form->create('MyModel');
echo $this->Form->input('id');
echo $this->element('my_form'); 
echo $this->Form->end();

View/Elements/my_form.ctp
// your form inputs
// whatever they are

Upvotes: 14

dogmatic69
dogmatic69

Reputation: 7575

this code will check if you have admin_form.ctp or form.ctp which will make it use the same code for add / edit

https://github.com/infinitas/infinitas/blob/dev/app_controller.php#L389

1.3 submits the forms automatically to where the are from so when you go to /edit/1 it will post to there, and /add will post to add.

that is all you need to do. if you have a edit that is vastly different to the add, then you just create the 2 files. when you want them the same, just make the one.

Upvotes: 0

Ish
Ish

Reputation: 29546

You should NOT merge those views, because add/edit are different actions and deserve separate view files. As your application grows you will realize that its good to have separate views to reduce complexity of if else conditions.

If you still want to avoid the separate files, Use

function add() {
    .....
    $this->render('edit')
}

Upvotes: 7

Leo
Leo

Reputation: 6571

I've done this before, but reverted back to having separate views, mainly for my own sanity.

It's easy enough to do. The edit requires an input for the record id. This is usually hidden. Any default form values for the add form will have to be contained in conditionals so that the stored values are not overwritten with defaults when you are editing a record

On the controller side of things, you'll need a conditional statement to decide whether to act as an add or edit depending on whether the $this->data['MyModel']['id'] is set.

I think that covers it - if I think of anything else I'll add it in.

My work pattern tends to be to build the edit view, then copy and paste to create the basis for the add view.

Upvotes: 6

Related Questions