I'm working on a port of an existing Java app to Salesforce.com and I ran into a Visualforce page that gave me some problems. The current JSP page allows the user to fill out a form, submit a new record to the database and then pop-up a new window to show some results while keeping the users on the same page with the form.
This is actually somewhat difficult to do with Apex and Visualforce. I searched the message boards but couldn't find anything comparable.LuckilyWes Nolte came to the rescue with his mad JavaScript skillz to point me in the right direction.
Typically you save a record with a commandButton that invokes a method in the Controller specified by the action attribute. However, this method returns a PageReference which, if not null, will redirect the user to a new page. However, I wanted the Controller method to notify the Visualforce page that the insert was successful and then pop open a new window via JavaScript that loaded another page.
Here's something similar to what I came up with. You can run this example on my developer site.
ActionFunctionDemoController
The Controller exposes a public 'message' attribute that is used by the Visualforce page to display the results of the submission. The save() method inserts the record and set the value of the 'message' attribute if no error. If an error occurred, it set the error message to the 'message' attribute instead.
ActionFunctionDemo
The Visualforce page has a number of interesting aspects. First it defines an actionFunction which allows us to invoke a controller action method from JavaScript. The component's name isdoControllerSave and it calls the save() method in the Controller. Instead of using the action attribute, the commandButton component instead uses the onclick method to call the doControllerSave JavaScript method (which in turn calls save() action method in the Controller) and then specifies that the onControllerReturn JavaScript method should be called when the Ajax request completes on the client. The magic here is that we wrap the entire onControllerReturn function in an outputPanel which is rerendered by the ActionFunction. Without the outputPanel this entire operation doesn't work at all.