AJAX gives your web applications a better user experience. They'll get quicker feedback on their actions and it won't require a full page refresh. In this post, I'm going to review the basics of doing AJAX in MonoRail. A complete Visual Studio 2008 solution for this sample project is available from my Google Code page.
For this demo, we'll have a dropdown listbox that allows the user to select a number. After selecting the number, we'll update an area of the web page with dynamically generated content and this will all be done without doing a full page refresh.
Like many MVC frameworks, MonoRail allows you to define a common layout for your website (think Master Pages in webforms). My layout for this sample is simple (I'm using the NVelocity view engine):
Some people may ask, "If you install the prototype library in the layout, doesn't it get included in every page even if you don't need it?" Yes, it does. If you'd like to limit where your AJAX is available, move the $AjaxHelper.InstallScripts() into each individual page as needed.
Let's create a simple MonoRail controller for our AJAX sample. For right now, we'll define the "Index" action as the action that is the beginning of this app:
Nothing fancy. We place a range of numbers (1-10) in the PropertyBag and we'll use that to generate our combo box.
We'll keep the view simple so we can focus on concepts. Something like this will do:
We'll implement the above in our view:
Now we've got a dropdown list and we've hooked up the onchange event to call "DoAjax()" -- we'll discuss this later.
Now comes the part of the page for our AJAX update. We'll define a <div> tag to hold the part of our screen we want to dynamically update. Further, we'll define a separate view just for rendering the AJAX portion of the div. Heres' the entire view for the "Index" method:
I placed a border around the <div> and changed the background color to help differentiate it from the rest of the page. What do we put in "ajaxview.vm"? Whatever we want to! Here's ajaxview.vm. It looks for the existence of a "selectedCount" variable and loops to create the <p> tags:
Client-side AJAX Code
The first thing DoAjax does it determine the item selected in the dropdown list. Next, it creates an Ajax.Request object that calls the "GenerateCounts" method of our controller. The "count" parameter is set to the value selected in the dropdown. Finally we set the "onSuccess" and "onFailure" callbacks. As you might have guessed, one of these will be called depending on the success or failure of our AJAX call.
The update callback takes the responseText of our AJAX request and updates our <div> tag we set up earlier. The prototype documentation contains a full description of all of the properties and methods exposed by the transport object in the callbacks.
Server-side AJAX Code
The controller code for our method is even simpler that our client-side code:
All we do is take the value passed in (the value selected in the dropdown list) and place it in the PropertyBag as "selectedCount" (NOTE: MonoRail's SmartDispatcherController takes care of pulling the "count" from the HTTP request and assigning it to the "count" parameter of the method). Then we tell MonoRail that it should render the view "ajaxview". Remember that this view simply loops and creates <P> tags based on the value of "selectedCount".
That's it! That's all there is to it. Run the sample code and select a value from the dropdown list. You'll notice that the area under the dropdown is updated as you pick different values and there is no full page refresh.
This exmaple just showed the mechanics of making AJAX requests via MonoRail's built-in AJAX support. You can see how something like this can easily be used to render an entire <TABLE> from a database query or do some other complex logic -- all without a full page refresh. If you have any questions, please don't hesitate to contact me.