We’re going to step things up a notch with this one, so hang on for the ride, because for those of you not already well versed in symfony and jQuery, there will be a lot of new information, and it will go pretty quickly, but I will try to make sure to keep everyone caught up. This is another post I hinted towards back when I first wrote about symfony widgets. Right, so, on to the fun!
First things first, let’s talk about requirements. My only real requirement is that it must be seamless. We must be able to only implement the widget, and have everything else work exactly as intended. For a date widget, this means when the user clicks that submit button, an array with ‘month’, ‘day’, and ‘year’ must be sent back. Not a string, not JSON, just that basic array.
It’s for the above reason that we will need to make a widget on top of the basic jQuery UI Datepicker Widget. The Datepicker alone would just return a string when we submitted the form, which would then require at least a custom validator, if not much more. So to simplify things later, we’ll put in more effort now.
There are four things we will be doing in this tutorial to make this happen. Here’s a quick overview:
We made our plugin, then we made the directory our jQuery plugins will go in, and the directory where we will store our widgets. The -p flag means “no error if existing, make parent directories as needed” which saved us a few mkdir commands.
3. Making our symfony widget
Now open up plugins/majaxWidgetPlugin/lib/widget/majaxWidgetFormDate.class.php and here’s our code:
So, to start out, we extend sfWidgetFormDate, as that will make the controls we need to manage a date submission. The only change we need to do, is to override the render function, which will let us add some custom code around the standard output, to allow us to more easily control the display.
4. Making our jQuery Plugin
As is the standard, I’ll show you the code, then highlight portions that are interesting. This file goes in plugins/majaxWidgetPlugin/web/js/jquery.majax.dateselector.js
You know, looking over, it’s pretty clear, I feel, what most parts do. The functions “_hide_real_ctrls”, and “_show_real_ctrls” hide and show that wrapping div we built around the original controls, so we can keep them in play, but not have to worry about controlling them. The “_build_facade” function builds our fake interactive Datepicker object, and optionally our ‘Clear’ button, if our date is allowed to be empty. Functions “_clear_display” and “_update_ctrls” to exactly as you would expect. Cure functions “_create” and “destroy” are from the jQuery UI Widget framework, and are called … can you guess when? 🙂
Once you’re done, you can replace any sfWidgetFormDate instance with a majaxWidgetFormDate instance, and everything else is handled. A little bit of effort up front, and many rewards down the road!
The simplest way, hands down, is to simply include the sfJqueryReloadedPlugin in your project. This also enables you to include the sfAdminDashPlugin which makes for easy navigation and a nice login screen for your back-end systems.
However, the problem with jQuery Reloaded, is that it is both old, and for our purposes, incomplete.
Since the last update to jQuery Reloaded, jQuery has progressed to version 1.4.2 (from 1.3.2), and more importantly jQuery UI has upgraded to 1.8.2 (from 1.7.3) and added some very nice and easy pieces we can use in our quest to simplify some of the widgets users are commonly presented.
The other problem we will run into with jQuery Reloaded, is that it doesn’t provide the CSS half of the jQuery UI library, meaning we would not be able to see any widgets we used properly.
One of the biggest problems with any user interface is ensuring the forms and controls are simple and straight forward to use. While Symfony comes with a great many of widgets that you can use in your forms, some of the most common ones are not as user friendly as one would hope.