Cakephp add form inside modal window while in index view

David W picture David W · Feb 19, 2014 · Viewed 10.8k times · Source

New to cakephp here.. wondering how i could have a button whilst in my index view to open an add form ( for the same model ). once i submit this form i'd like the modal to disappear and the new record to be show in the index view. I was thinking of putting the add form in a cake element? but not sure how to put this in a modal window. any advice would be great thanks.

Answer

theotherdy picture theotherdy · Feb 20, 2014

What @savedario says makes perfect sense. I blogged about this just before Christmas and have copied the relevant bits below:

View/Users/index.php:

<!-- overlayed element -->
   <div id="dialogModal">
     <!-- the external content is loaded inside this tag -->
     <div class="contentWrap"></div>
   </div>
...
<div class="actions">
    <ul>
        <li>
            <?php echo $this->Html->link(__('Add user', true), array("controller"=>"users", "action"=>"add"), array("class"=>"overlay", "title"=>"Add User"));
        </li>
    </ul>
</div>
...
<script>
$(document).ready(function() {
    //prepare the dialog
    $( "#dialogModal" ).dialog({
        autoOpen: false,
        show: {
            effect: "blind",
            duration: 500
            },
        hide: {
            effect: "blind",
            duration: 500
            },
        modal: true
        });
    //respond to click event on anything with 'overlay' class
    $(".overlay").click(function(event){
        event.preventDefault();
        $('#contentWrap').load($(this).attr("href"));  //load content from href of link
        $('#dialogModal').dialog('option', 'title', $(this).attr("title"));  //make dialog title that of link
        $('#dialogModal').dialog('open');  //open the dialog
        });
    });
</script>

Views/Users/add.ctp:

echo $this->Form->create('User');
echo $this->Form->input('name');
echo $this->Js->submit('Save', array(  //create 'ajax' save button
    'update' => '#contentWrap'  //id of DOM element to update with selector
    ));
if (false != $saved){ //will only be true if saved OK in controller from ajax save above
    echo "<script>
        $('#dialogModal').dialog('close');  //close containing dialog         
        location.reload();  //if you want to reload parent page to show updated user
    </script>";
    }
echo $this->Form->end();
echo $this->Js->writeBuffer(); //assuming this view is rendered without the default layout, make sure you write out the JS buffer at the bottom of the page

Controllers/UsersController.php:

function add() {
    ...
    $this->set('saved', false); //false by default - controls closure of overlay in which this is opened
    if (!empty($this->request->data)) {
        $this->User->create();
        if ($this->User->save($this->request->data)){ 
            $this->set('saved', true); //only set true if data saves OK
            } 
        }
    ...
    }

You'll need to have included JQuery 1.9+ and JQuery UI js files in the layout used by your index.ctp and add.ctp.

Actually I have now switched to Bootstrap modals in my own code because I think they look nicer but the approach is very similar.