I just wanted to share with you two approaches to bringing up an add or edit form in a JQuery UI modal dialog and closing the dialog on a successful submit or keeping it open and displaying errors in case of validation or other save problems.
A non-Cake approach
Ingredients
CakePHP 2+
JQuery 1.9+
JQuery UI
JQuery Form Plugin
The Views
Main page
This is the page from which we want to launch our modal add or edit dialog:
<!-- 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>
Our add or edit form
This is shown in the dialog
echo $this->Form->create('User');
echo $this->Form->input('name');
echo $this->Form->end('Submit');
<script>
$('#UserAddForm').ajaxForm({
target: '#contentWrap',
resetForm: false,
beforeSubmit: function() {
$('#contentWrap').html('Loading...');
},
success: function(response) {
if (response=="saved")) {
$('#dialogModal').dialog('close'); //close containing dialog
location.reload(); //if you want to reload parent page to show updated user
}
}
});
</script>
Controller
For our add or edit action
function add() {
...
if (!empty($this->request->data)) {
$this->User->create();
if ($this->User->save($this->request->data)){
return "saved";
}
}
...
}
A more Cakey approach
With thanks to RXC on StackOverflow
Ingredients
CakePHP 2+
JQuery 1.9+
JQuery UI
The Views
Main page
This is the same as above
Our add or edit form
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
Controller
For our add or edit action
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
}
}
...
}
Hope that’s helpful. Would be very interested in alternatives that have worked for you…and corrections to inevitable errors above.