I’m not crazy, either.
Yesterday, in extreme programming style, Travis and I worked as a team to lay out a lot of the structural framework of Acropolis. If the marriage of JQuery and CakePHP is our goal, we may not be at an official engagement yet, but the courtship has currently begun. A design pattern I had been working out in my head and sketching down on blank sheets of printer paper several 3 a.m.’s over the last few weeks has now begun to emerge in living form.
The goal is for the page to never have to reload. Why? Because that is how desktop applications work. It is what your average person is used to. It is what “real” software feels like. In order to facilitate this we have to create our own form of organization, our own pattern, so that we don’t confuse ourselves in a mess of “spaghetti-code,” where JQuery functions are intermittently and inconsistently interacting with server-side scripting. I have been down that road a few times by now, and after a certain point, if you don’t have a solid organizational scheme to keep everything in its place, you begin to repeat yourself. This means more code to maintain, more to remember, and more that has to be changed whenever you add a new feature. This is no good. Now Cake takes care of a lot of this, and if you’re content to work with the prototype libraries it comes “out of the box” with, then you’re good. But if you’re like me and you just can’t tear yourself away from the vast potentialities available in JQuery, you have to forge your own path.
(Incidently, the two CakePHP JQuery “helpers” out there don’t seem to really fit the bill. One just helps you with your naming conventions, and the other is, well, not quite as “helpful” as JQuery tends to be on its own.)
But the standard naming conventions and organization of CakePHP just begs to be taken advantage of. It is so hard to write about this in the abstract, so let me just try to hit on a few key points. Hopefully I can elaborate upon these points as we go.
Partial Layouts + AJAX = Never Having to Repeat Yourself.
Small sections of your code that may need to be updated on-the-fly can be stored in “elements.” For our products module, then, we created a “row” element. When we list our products in a table, one product per row, we make use of this row element to format the data in the view. Each row in the HTML (<tr>) is connected to the actual “row” in the database by giving the HTML row an id parameter that corresponds with the Product.id. Whenever the information in that row (database) changes, the row (HTML) is updated via JQuery by calling a function in the controller that calls the same element (row.ctp) used to generate the row in the first place. (I feel like I could have said that in 1/4 the number of words but oh well.)
Predictable naming schemes mean one JQuery function can serve many functions. Kind of like a crossing guard for code.
We constructed our own pattern for “actions” that can be used across modules (e.g. Products, Cateogories, Orders, etc.). We again made use of parameters inherent in HTML. For example, we use a link to fire the action to edit a product row. The code looks something like this:
<a href=”/products/edit/1″ class=”action” id=”Product/products/edit/1″>test</a>
What this basically means is that, first off, if your user is not using javascript the link will work normally, taking the user to /products/edit/1 where he/she can edit product with an id of 1.
If your user’s browser does use javascript, however, then JQuery takes over and things get very exciting. JQuery, upon document load, binds a click event to all elements with a class of “action.” When an action is clicked, JQuery takes the id of the clicked element and splits it up by ‘/’ and loads it into an array data[]. At this point it has all the information it needs.
var modelName = data[0];
var controllerName = data[1];
var actionName = data[2];
var actionId = data[3];
Now we are able to build an AJAX request to pull up a form and place it in a lightbox or whatever. In our case we chose to simply hide the table and then, after save, get rid of the form and re-display the table. Before we do that, however, we are able to update the row that has changed, which is easy, because we have the id of the row to be changed, and row.ctp is easily accessible in our elements directory. All we really need is a small function in the controller that delivers up the HTML of the one row based upon the supplied id.
I am sure it is difficult to picture, so I hope we will soon be able to post a link to a demo. But the result is a very fluid, and lightning-fast user experience that feels much more like “real” software than most people are used to experiencing in a browser. But what makes me excited is how squeaky clean and extensible this structure is. We have a few kinks to work out but once thats done our work will mostly involve customizing forms and the layout.
More to come soon…
Recently

Leave a Reply