Thursday, May 27, 2010

Getting Started with WebSharper Platform 2010

A little while ago a cool new product was brought to my attention that allows client-based web development in F#.  The name of this product is WebSharper Platform 2010.  In this post, I will show a simple example for getting started with WebSharper Platform 2010.

Overview of this Example: 
The following code is a slimmed down and slightly modified version of the example provided in the default WebSharper-1.0 template.  Additionally, this example saves the information captured on the form to a CouchDB database.  Note: To run this example, you will need to download and install the WebSharper Platform 2010 Standard - Version 1.0.28 - Public Release (Instructions can be found at http://www.intellifactory.com/products/wsp/GettingStarted.aspx).  Additionally, in order for the registration information to be saved to the CouchDB database, CouchDB must be running on the default port (5984) of the local machine and a database named registration must exist.

Setting up the Form:
Our basic form is setup with the help of the Formlets library ("a library for type-safe web form combinators" - http://www.intellifactory.com/docs/websharper.pdf). The JavaScript attribute informs the WebSharper compiler that the function should be translated from F# to JavaScript.
    [<JavaScript>]
    let RegistrationForm : Formlet<RegistrationInformation> =
        Formlet.Yield (fun firstName lastName email -> 
                           {FirstName = firstName; 
                            LastName = lastName; Email = email})
        <*> input "First Name" "Please enter your first name"
        <*> input "Last Name" "Please enter your last name"
        <*> inputEmail "Email" "Please enter a valid email address"
Creating the Form Validation:
You probably noticed the input and inputEmail function calls in the form setup. These functions create the form elements with appropriate validation.  The code is as follows:
    [<JavaScript>]
    let input (label: string) (error: string) = 
        Controls.Input ""
        |> Validator.IsNotEmpty error
        |> Enhance.WithValidationIcon
        |> Enhance.WithTextLabel label

    [<JavaScript>]
    let inputEmail (label: string) (error: string) = 
        Controls.Input ""
        |> Validator.IsEmail error
        |> Enhance.WithValidationIcon
        |> Enhance.WithTextLabel label
Adding the Flow:
In this simple example, the user completes the three fields and clicks submit. The information is then saved to couch and the user is redirected to a summary page. That sequence is setup with the following code:
    [<JavaScript>]
    let RegistrationSequence =
        let registrationForm =
            RegistrationForm
            |> Enhance.WithSubmitAndResetButtons
            |> Enhance.WithCustomFormContainer {
                Enhance.FormContainerConfiguration.Default with
                    Header = 
                        "Enter the following information to register:" 
                        |> Enhance.FormPart.Text 
                        |> Some
                }
        let completeRegistration registrationInformation () =
            SaveRegistrationToCouch registrationInformation
            FieldSet [
                Legend [Text "Registration summary"]
                P ["Hi " + registrationInformation.FirstName + " " + 
                    registrationInformation.LastName + "!" |> Text]
                P ["You are now registered." |> Text]]
        let flow =
            Flowlet.Do {
                let! initialForm = registrationForm
                return! Formlet.OfElement (completeRegistration initialForm)
            }
        Div [H1 [Text "Register today!"]] -< [flow.BuildForm()]

Saving the Information to CouchDB: 
The final piece of code that I will show from this example is the server side method that is called from the client to save the information to CouchDB. In the RegistrationSequence function, we saw a call to a function named SaveRegistrationToCouch. This function looks like this:
    [<Rpc>]
    let SaveRegistrationToCouch (registrationInformation:RegistrationInformation) =
        JsonConvert.SerializeObject registrationInformation
        |> FSharpCouch.CreateDocument couchDBUrl 
        |> ignore
As you can see, all it takes for us to expose a server-side method is to add the Rpc attribute to that function.

Viewing the Result:
The result is a nice little registration sequence that contains client-side validation.  An example of the initial form with all completed information is below:

Conclusion:
This example shows how easy it is to throw together a simple registration form with WebSharper Platform 2010. We've only touched the surface on the capabilities of this platform.  You can find out more by visiting the Intellifactory web site.  You can find the full solution at http://github.com/dmohl/WebSharper-Example.

No comments:

Post a Comment