I want to document this nifty little thing I did today because, unfortunately it turns out that I can’t use it for this particular page at all. But there will be a day when I can use it. And the me of that day is really going to be keen on the me of today for creating this blog post.
Here’s the scenario:
I have an action on my view page that makes an ajax request. If that request is successful, I dynamically add some elements to the DOM via jQuery. However, I found that I also needed to dynamically add in all this extra HTML that was usually contained in a cake view/element. So how the heck do you do that? Here’s how:
The view element contains the HTML for a table tr (which contains in it a form). That form needs to be pre-populated with data about this particular parent element. It was going to be real messy to recreate all that HTML in a JS function, not to mention it goes against the DRY concept. So here’s how to load that view element:
- Create the container in jQuery for the element (my actual code was a little more complex):
$(‘<tr class = “editform hidden” ></tr>’).insertAfter(‘table > tbody > tr:first’);
So now I have a tr element in my table that I can use to load my element into
Use the jQuery load function to call my cakephp controller function:
This is telling jQuery to send a request to some controller and look for a function called renderEditForm. That function is going to send back the appropriate element. So what’s with the “.details”? That’s the magic! Inside the particular element that I want to load is a tr element called “editform”. But I actually don’t want that because I needed to create it in my jQuery so that I could dump the form somewhere! So by adding this additional parameter to the load call, I’m telling it to process what I get back from cake and only load the code starting at the .details element! Here’s what the elements file (view/elements/someview.ctp) actually contains (stripped down for simplicity):
<tr class = “editform hidden” >
<td class=“details” colspan=“3”>
<div class=“table-details”>Some Details </div>
So you can see that if I had included the entire contents of the ctp file, I would have been doubling up on the editform element. Here’s what the controller renderEditForm function looks like:
And that’s all there is to it! It’s a pretty cool little trick if you want to be able to dynamically include existing cake code!