By Frank Joppe on Friday, August 28, 2015 — 0 comments

FSharpArm - part 2 Community

Read the previous article: FSharpArm - part 1 As the previous article was "current-status". Progress brought new insights, and so the following corrections apply:I develop in VS2015 under Windows, so I didn’t need to install Akka.Net on the RPi; installing fsharp for Debian/Ubuntu Linux is enough; The Self-Hosted Websharper template does not work -fully- as was described, see below; Control Panel [...]
>> Read the full article on fjoppe.weebly.com
By István Gansperger on Wednesday, August 26, 2015 — 0 comments

Try WebSharper: update notes for snippets Community

A new version of Try WebSharper just hit the live site featuring update notes to complement the addition of updates from the last release along with some quality of life changes.

  1. When updating your snippet you can now specify notes regarding that specific update. This is similar to the description field with the intent of only showing what changes were made and why. Later we might compile all the notes from the previous versions and show them all for a given snippet.

    which will show up under the description in the next version:

  2. We now have previous and next links on the embed page as well meaning you can switch between versions in an embedded snippet.

  3. You can use WebSharper.React and WebSharper.MaterialUi in your snippets. The extensions have not been publicly released yet so you can access them only on Try WebSharper!

  4. Extensions have been updated to the latest versions which means bugfixes — most notably UI.Next enhancements — and other improvements!

Happy sharing!

By Adam Granicz on Wednesday, August 19, 2015 — 0 comments

Try WebSharper: snippet versioning, gist import, and other enhancements now available Core team

A new Try WebSharper is out adding a couple handy new features and addressing a couple annoyances, making it even more easy to publish your F# and WebSharper snippets. The picture below depicts the main areas of change:

  1. Creating snippets from GitHub gists - You can now easily import a gist, all you have to do is hover over the (+) button in the bottom right corner, hit the GitHub icon and give your gist URL.

  2. Versioning snippets - You can now track different versions of and updates to any given snippet by switching stepping back and forth using the < and > arrows in the main menu. By default, when you visit a snippet you see its latest version, unless the URL includes the exact version (0 being the oldest), such as http://try.websharper.com/snippet/adam.granicz/00002I/1.

  3. Proper indentation support - You may have noticed earlier that highlighting a block of text and hitting Tab or Shift+Tab doesn't exactly behave in a friendly manner: it wipes the selected text instead of indenting. This is now fixed and you get the usual indentation behaviour you'd expect.

  4. Easy embed links - If you need to embed a snippet or "run" it outside of Try WebSharper, you can now easily get those links by following the direct links on the Embed tab.

Keep an eye on this blog and follow @trywebsharper for more awesome upcoming features.

Happy sharing!

By Adam Granicz on Sunday, August 9, 2015 — 4 comments

Share and embed Try WebSharper snippets Core team

Just four days ago we released Try WebSharper, and here we go with the first feature enhancement: embedding snippets. A huge thanks to Don Syme for suggesting it.

Each snippet and example now has an Embed tab, giving you the links or the HTML code for embedding it:

For instance, the snooker example you can play here directly.

You can also view it as an embedded content here, giving you the original source code.

With more features coming soon, we hope you enjoy experimenting and sharing your best F# web programming snippets.

Happy sharing!

By Frank Joppe on Friday, August 7, 2015 — 0 comments

FSharpArm - part 1 Community

I know what's like in the summertime, a bit quiet, so I thought it would be fun to build a Robot Arm, and to control it from a Raspberry Pi using self written F# software. Project goals are: have fun, learn some, and if possible, do a "Sean's dad" trick: inspire a kid.The ingredients are: One Raspberry Pi 2B (quad core!) plus accessories (power, network cable, HDMI cable), a clean Micro SD card (cat 10) with adaptor, a USB keyboard, a MeArm robot arm, four Servo motor cord extensions (3x10cm 1x[...]
>> Read the full article on fjoppe.weebly.com
By Adam Granicz on Thursday, August 6, 2015 — 0 comments

New WebSharper templates Core team

The recent release of WebSharper 3.4 also brought an update to most of the project templates shipped for Visual Studio, MonoDevelop, and Xamarin Studio.

As a quick glance, here is the template client-server (both UI.Next and the older Html type) application, with two simple pages (Home and About), demonstrating how to use master templates and how to make client-server calls.

While the templates organize client and server aspects into separate files (Client.fs, Remoting.fs, Main.fs), here is all the code you need in a single file for the above application (the master template Main.html is not listed here):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
namespace MyApplication

open WebSharper
open WebSharper.Sitelets
open WebSharper.UI.Next
open WebSharper.UI.Next.Server

type EndPoint =
    | [<EndPoint "/">] Home
    | [<EndPoint "/about">] About

module Server =

    [<Rpc>]
    let DoSomething input =
        let R (s: string) = System.String(Array.rev(s.ToCharArray()))
        async {
            return R input
        }

[<JavaScript>]
module Client =
    open WebSharper.UI.Next.Client
    open WebSharper.UI.Next.Html

    let Start input k =
        async {
            let! data = Server.DoSomething input
            return k data
        }
        |> Async.Start

    let Main () =
        let input = inputAttr [attr.value ""] []
        let output = h1 []
        div [
            input
            buttonAttr [
                on.click (fun _ _ ->
                    async {
                        let! data = Server.DoSomething input.Value
                        output.Text <- data
                    }
                    |> Async.Start
                )
            ] [text "Send"]
            hr []
            h4Attr [attr.``class`` "text-muted"] [text "The server responded:"]
            divAttr [attr.``class`` "jumbotron"] [output]
        ]

module Templating =
    open WebSharper.UI.Next.Html

    type MainTemplate = Templating.Template<"Main.html">

    // Compute a menubar where the menu item for the given endpoint is active
    let MenuBar (ctx: Context<EndPoint>) endpoint : Doc list =
        let ( => ) txt act =
             liAttr [if endpoint = act then yield attr.``class`` "active"] [
                aAttr [attr.href (ctx.Link act)] [text txt]
             ]
        [
            li ["Home" => EndPoint.Home]
            li ["About" => EndPoint.About]
        ]

    let Main ctx action title body =
        Content.Doc(
            MainTemplate.Doc(
                title = title,
                menubar = MenuBar ctx action,
                body = body
            )
        )

module Site =
    open WebSharper.UI.Next.Html

    let HomePage ctx =
        Templating.Main ctx EndPoint.Home "Home" [
            h1 [text "Say Hi to the server!"]
            div [client <@ Client.Main() @>]
        ]

    let AboutPage ctx =
        Templating.Main ctx EndPoint.About "About" [
            h1 [text "About"]
            p [text "This is a template WebSharper client-server application."]
        ]

    [<Website>]
    let Main =
        Application.MultiPage (fun ctx endpoint ->
            match endpoint with
            | EndPoint.Home -> HomePage ctx
            | EndPoint.About -> AboutPage ctx
        )

Future plans

We are planning to introduce additional tools to create WebSharper projects via these standard and other templates without needing the corresponding Visual Studio or Xamarin Studio plugins/extensions installed. This will make it super-easy to create WebSharper projects from within any context, IDE, or OS. Keep an eye on this blog for upcoming announcements.

Happy coding!

By Adam Granicz on Tuesday, August 4, 2015 — 0 comments

Introducing Try WebSharper Core team

We are thrilled to announce the availability of Try WebSharper, a simple and fun way to create and share WebSharper snippets with others!

The code you share can be run (=>Run) right in your browser, and you get basic type checking with warnings and errors showing up as red/yellow squiggles. Currently, this takes a couple seconds to complete so it's not the most convenient way to experiment, but it will get a lot better soon.

We aim to keep this site current with upcoming WebSharper releases, so you can use it to experiment with even the newest WebSharper features, including reactive markup and templating via UI.Next.

Converting F# snippets to WebSharper

While Try WebSharper is intended primarily for sharing WebSharper snippets (e.g. F# snippets that produce web output), you can also convert simple F# snippets by following a few simple steps.

Say, you wanted to run the following:

1
2
3
open System

sprintf "Time now is %s" (DateTime.Now.ToShortTimeString())

First, it helps to understand that snippets are not simply run as written in F#; they are converted to JavaScript with WebSharper and executed in your browser. For this, we use the single-page application (SPA) WebSharper template. This takes a master HTML document (index.html - and you can write to this file on the second tab) that references the JavaScript code generated from your F# code.

Using JS.Alert

In order for this to have a visible effect, you could simply raise a JavaScript popup with your output:

1
2
3
4
5
6
7
8
open System
open WebSharper
open WebSharper.JavaScript

[<JavaScript>]
let Main =
    sprintf "Time now is %s" (DateTime.Now.ToShortTimeString())
    |> JS.Alert

Note that you will always need to open WebSharper for the [<JavaScript>] attribute and other WebSharper pervasives, and it's also handy to open WebSharper.JavaScript for client-side/EcmaScript functions like JS.Alert.

Caveat

You may be tempted to throw away the name of the top-level binding, but this will yield no output due to let _ = ... being interpreted as do ... - which acts as a module initializer (instead of a top-level binding) that currently is not translated to JavaScript by WebSharper.

1
2
[<JavaScript>]
let _ =  ...

Using WebSharper.Html.Client

Another thing you can do is to show it in the markup that is rendered from index.html as your output. Note, that by default this document has a div node with id=main, which you can write to using the AppendTo member on any HTML.Client element.

1
2
3
4
5
6
7
8
9
open System
open WebSharper
open WebSharper.JavaScript
open WebSharper.Html.Client

[<JavaScript>]
let Main =
    Div([Text (sprintf "Time now is %s" (DateTime.Now.ToLongTimeString()))])
       .AppendTo "main"

Here, you are opening WebSharper.Html.Client for accessing client-side HTML functions like Div.

Using WebSharper.UI.Next

If you followed our recent announcements for WebSharper 3.4, you will likely prefer to do the above via the more flexible reactive HTML language introduced via UI.Next. Here is how that goes:

1
2
3
4
5
6
7
8
9
open System
open WebSharper    
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client

[<JavaScript>]
let Main =
    div [text (sprintf "Time now is %s" (DateTime.Now.ToLongTimeString()))]
    |> Doc.RunById "main"

So all in all, these should give you three different strategies to convert F# snippets into WebSharper ones.

Site features and plans

As a code snippets site, Try WebSharper has the usual toolset for snippets: you can create a new snippet by hitting the big red plus (+) button in the bottom right corner, fork an existing snippet (=>Fork), or save the one you are working on (=>Save).

We also added a basic set of examples (with more being moved from WebSharper examples), which you can find under the hamburger icon, along with any saved snippets you may have:

Coming up

In future releases, we will be introducing additional functionality to help with "templating" basic snippets using any one of the above methods, spinning up snippets via GitHub gists, and lighting up much more refined code assistance services (code completion, type checking as you type, hover comments and signatures, etc.)

Happy sharing!

By Loïc Denuzière on Monday, August 3, 2015 — 3 comments

WebSharper UI.Next 3.4: the new HTML syntax Core team

As its name suggests, UI.Next was created to be the next-generation standard library for UI programming in WebSharper. As a consequence, as of WebSharper 4.0, UI.Next will be merged into WebSharper itself under a less "codenamey" moniker that we haven't decided yet. It will completely obsolete the current Html.Client and Html.Server.

The recently released version 3.4 prepares the terrain for this merger. It streamlines the embedded markup syntax, introduces server-side capability and adds client-side functionality.

Streamlined syntax

WebSharper UI.Next 3.4 overhauls the syntax for embedding HTML elements in F# for enhanced readability and familiarity.

The most visible change is the switch to lowercase elements and attributes, making UI.Next code more similar to what you would write in an HTML file. For elements, the function Div0 which creates a <div> tag with child elements becomes simply div, and Div which creates a <div> tag with attributes and child elements becomes divAttr. For attributes, the class attr contains static methods to create standard attributes and on creates event handlers. Here is a list of the new constructors available under WebSharper.UI.Next.Html:

New syntax

Old / Verbose syntax

divAttr [attrs...] [children...]

Div [attrs...] [children...]

div [children...]

Div0 [children...]

text "Hello"

Doc.TextNode "Hello"

textView aView

Doc.TextView aView

Needs open WebSharper.UI.Next.Client

attr.color "black"

Attr.Create Attributes.Color "black"

attr.colorDyn aView

Attr.Dynamic Attributes.Color aView

Needs open WebSharper.UI.Next.Client

attr.colorDynPred aView aBoolView

Attr.DynamicPred Attributes.Color aBoolView aView

Needs open WebSharper.UI.Next.Client

attr.anim aView aFunc aTrans

Attr.Animated aTrans aView aFunc

Needs open WebSharper.UI.Next.Client

See "Tier-specific functionality" below for the rationale behind needing open WebSharper.UI.Next.Client for some of these.

Here is a small code sample:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// New syntax                              │ /// Old syntax
open WebSharper.UI.Next                     │ open WebSharper.UI.Next
open WebSharper.UI.Next.Html                │ open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client              │
                                            │
let myDocument =                            │ let myDocument =
  let rvInput = Var.Create ""               │   let rvInput = Var.Create ""
  div [                                     │   Div0 [
    h1 [text "A small example"]             │     H10 [Doc.TextNode "A small example"]
    label [text "Type something here: "]    │     Label0 [Doc.TextNode "Type something here: "]
    Doc.Input [] rvInput                    │     Doc.Input [] rvInput
    pAttr [attr.``class`` "paragraph"] [    │     P [Attr.Create Attributes.Class "paragraph"] [
      text "You typed: "                    │       Doc.TextNode "You typed: "
      textView rvInput.View                 │       Doc.TextView rvInput.View
    ]                                       │     ]
  ]                                         │   ]

Server-side markup

It is now possible to use the Doc type, and the above syntax, to create server-side markup, ie. markup that is generated on the server and output in the HTML document, as opposed to client-side markup, generated dynamically in JavaScript.

Returning a server-side Doc as content

There are two ways to use a Doc as server-side content:

  • Use Content.Doc to create a Sitelets Content<_> value:

    1
    2
    3
    4
    5
    6
    7
    8
    
    open WebSharper.Sitelets
    open WebSharper.UI.Next
    open WebSharper.UI.Next.Server
    
    [<Website>]
    let MyWebsite =
      Application.SinglePage <| fun context ->
        Content.Doc myDocument
  • Convert it to Html.Server elements using Doc.AsElements:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    open WebSharper.Sitelets
    open WebSharper.UI.Next
    open WebSharper.UI.Next.Server
    
    [<Website>]
    let MyWebsite =
      Application.SinglePage <| fun context ->
        Content.Page(
          Body = Doc.AsElements myDocument
        )

Including client-side markup

In order to include a client-generated Doc inside a server-side Doc, you can use the function client. This function is analogous to ClientSide from Html.Server: it takes a quotation of a top-level, [<JavaScript>]-annotated function and includes it in server-side markup.

You can also add event handlers on server-side Docs using the methods in the on class. These methods take a quotation of a top-level, [<JavaScript>]-annotated function and return an Attr value that sets the handler as a static attribute on the element. This means that only one handler of a given type can be added to an element this way: you can't have two instances of eg. on.click <@ ... @> on the same server-side Doc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
open WebSharper
open WebSharper.UI.Next
open WebSharper.UI.Next.Html

[<JavaScript>]
module Client =
  open WebSharper.JavaScript
  open WebSharper.UI.Next.Client
  
  let Widget() =
    let rvInput = Var.Create ""
    Doc.Concat [
      Doc.Input [] rvInput
      p [text "You typed: "; textView rvInput.View]
    ]
    
  let Alert el ev =
    JS.Alert "Clicked!"

module Server =
  open WebSharper.Sitelets
  open WebSharper.UI.Next.Server

  [<Website>]
  let MyWebsite =
    Application.SinglePage <| fun context ->
      Content.Doc(
        div [
          h1 [text "Enter text below"]
          client <@ Client.Widget() @>
          buttonAttr [on.click <@ Client.Alert @>] [text "Click me!"]
        ]
      )

Tier-specific functionality

Some Doc functionality is only available on the client, or only on the server. To use such functionality, you need to open WebSharper.UI.Next.Client or WebSharper.UI.Next.Server, respectively.

The following is only available on the client side, and will raise a runtime error if used from the server side:

  • Reactive elements and attributes: textView, Doc.EmbedView, attr.*Dyn, attr.*DynPred, attr.*Anim, Doc.Convert*, reactive form elements (Doc.Input, etc).
  • Doc.Run, Doc.RunById, Doc.AsPagelet
  • on.* event handlers taking a function as argument. On the server you must use the version taking a quotation as argument.
  • Element methods and properties described below in "New client-side functionality".

The following is only available on the server side, and will raise a compile-time error if used from the client side:

  • Content.Doc, Doc.AsElements, Attr.AsAttributes.

New client-side functionality and the Elt type

One challenge in entirely replacing Html.Client with Doc is that existing applications using Html.Client should be convertible without requiring a complete change in paradigm. This means that we need to add as much of the imperative capabilities of Html.Client to Doc as possible. However, a Doc value is not guaranteed to be composed of a single root element, so accessing the element to perform actions such as SetAttribute or Append cannot be guaranteed to succeed. To fix this, we made the following change to the API.

The Doc type is now an abstract class, and there is a new type Elt that inherits from it and represents docs that are guaranteed to be composed of a single root element. The following functions return an Elt:

  • Element constructors, such as div and divAttr.
  • Doc.Element, Doc.SvgElement, Doc.Static.
  • Form input element constructors: Doc.Input, Doc.Button, etc.

Values of type Elt, in addition to being Docs, also have the following properties and methods (non-exhaustive list):

  • Dom returns the underlying Dom.Element.
  • Append(doc) and Prepend(doc) add child Docs to the beginning / end of the element. Reactive Docs are properly handled.
  • Clear() removes all children. Reactive children are properly disconnected from the View graph.
  • Text gets or sets the text content. The setter properly disconnects reactive children from the View graph.
  • Value gets or sets the value.
  • Methods to get, set, remove, test the presence of attributes, classes, styles: GetAttribute, SetProperty, HasClass, etc.
  • On "eventName" function adds an event callback.

We are still ironing out tricky parts required to implement OnAfterRender, which is quite ubiquitous in Html.Client code.

Templating language change

In order to allow using ${string} holes from the server side, the following change has been implemented:

  • ${string} holes now have type string instead of View<string>.
  • $!{string} is the new syntax for holes of type View<string>.

Conclusion

As you can see, a lot of enhancements are necessary to allow UI.Next markup to be usable as a replacement of Html.Client and Html.Server. We are confident that these changes will make it easy to convert existing applications to UI.Next for WebSharper 4.0.

Happy coding!

By Loïc Denuzière on Monday, August 3, 2015 — 4 comments

WebSharper 3.4 released Core team

We are happy to announce the availability of WebSharper 3.4, which you can download here. Here are the main highlights of this release.

Revamped Sitelets API

The sitelets API has received a well-needed cleanup and simplification.

  • Content is now always asynchronous: constructors and combinators take and return values of type Async<Content<_>>.

  • Context is now always passed from the sitelet to the content, rather than as a callback when constructing the content.

  • Content creation functions have been renamed:
    • Content.PageContent[Async] --> Content.Page overloaded with named arguments instead of a record
    • Content.JsonContent[Async] --> Content.Json
    • Content.CustomContent[Async] --> Content.Custom
    • Content.Text was added.
    • Content.File was added.

  • A new module WebSharper.Application contains functions to create sitelets:
    • MultiPage is equivalent to Sitelet.Infer.
    • SinglePage creates a sitelet with a single endpoint (action) and HTML content.
    • Text creates a sitelet with a single endpoint and text content.

Here is a small before/after comparison on a small 2-page application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
open WebSharper
open WebSharper.Sitelets

type EndPoint =
    | [<EndPoint "GET /">] Home
    | [<EndPoint "GET /api">] Api

// WebSharper 3.3

let HomePage =
    Content.PageContent <| fun ctx ->
        { Page.Default with
            Title = Some "Home"
            Body = [A [HRef (ctx.Link Action.Home)] -< [Text "This is the home page."]]
        }

let ApiPage =
    Content.JsonContent <| fun ctx ->
        ["a value"; "serialized"; "to json"]

[<Website>]
let MyWebsite =
    Sitelet.Infer <| function
        | Action.Home -> HomePage
        | Action.Api -> ApiPage

// WebSharper 3.4

let HomePage (ctx: Context<EndPoint>) =
    Content.Page(
        Title = "Home",
        Body = [A [HRef (ctx.Link Action.Home)] -< [Text "This is the home page."]]
    )

let ApiPage =
    Content.Json ["a value"; "serialized"; "to json"]

[<Website>]
let MyWebsite =
    Application.MultiPage <| fun ctx -> function
        | Action.Home -> HomePage ctx
        | Action.Api -> ApiPage ctx

A number of these new functions are equivalent to functions that were in WebSharper.Warp, which are now marked as obsolete.

New HTML language for UI.Next

We completely redesigned the HTML embedded language for WebSharper UI.Next. We will post another blog entry soon to fully describe the new design, but here are the main take-aways:

  • Element and attribute combinators are now lowercase, for a hopefully more natural-looking syntax.
  • The type Doc can be used for both client-side and server-side markup. Some features are only available on one side, such as UI.Next reactive elements for the client and conversion to a Content<_> for the server. To use these features, you need to open WebSharper.UI.Next.Client or WebSharper.UI.Next.Server, respectively.
    A template for client-server UI.Next applications has also been added to the Visual Studio and Xamarin Studio extensions.

Our goal for WebSharper 4.0 is to obsolete the current Html.Client and Html.Server, and to merge WebSharper.UI.Next into WebSharper under a new name. Doc will be the unique way to deal with HTML content, both on the client and the server side.

F# 4.0 proxies

WebSharper 3.4 provides JavaScript proxies for the functions that were added to the standard library in F# 4.0. You can now call functions such as Seq.mapFold and Array.last from the client-side.

Cross-site features for RPC functions

WebSharper 3.4 integrates several features related to cross-site requests to RPC functions:

  • Protection against Cross-Site Request Forgery using a cookie-to-header token. This protection is active by default and completely automatic.
    If you need to deactivate it, in particular to be able to call RPC functions from a PhoneGap mobile application, you can simply call DisableCsrfProtection() from module WebSharper.Web.Remoting at the top-level on the server side.
  • Management of allowed CORS origins. In module WebSharper.Web.Remoting, the functions AddAllowedOrigin and associated can be called at the top-level on the server side to add CORS origins accepted by the RPC handler. In particular, PhoneGap applications need to add file:// as an allowed origin.

Other changes

Here are the minor changes and bug fixes for WebSharper 3.4:

  • Fix #453: whitespace around the title in Content.Page.
  • Fix #459: Error 500 when replying to an RPC from a page with url "file://..."

Happy coding!

By Loïc Denuzière on Wednesday, July 22, 2015 — 7 comments

WebSharper 3.3 released with client-side JSON serialization Core team

We are happy to announce the availability of WebSharper 3.3, which you can download here. The main highlight of this release is the addition of JSON serialization functions for client-side code.

The format used for this serialization is identical to the format used by inferred Sitelets. This means that you can now easily craft your request data on the client, perform an AJAX call to your Sitelets API, and parse the reply, all of this type-safely!

For example, for a website defined as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
open WebSharper
open WebSharper.Sitelets

type EndPoints =
    | [<EndPoint "POST /article"; Json "article">]
      PostArticle of article: Article
and Article = { title: string; body: string }

[<Website>]
let app = Sitelet.Infer <| function
    | PostArticle article ->
        let articleId = ApplicationLogic.SaveArticle article
        Content.JsonContent (fun _ -> articleId)

You can invoke the REST endpoint POST /article from the client-side like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[<JavaScript>]
module Client =
    open WebSharper.JavaScript
    open WebSharper.JQuery

    /// General function to send an AJAX request with a body.
    let Ajax (method: string) (url: string) (serializedData: string) : Async<string> =
        Async.FromContinuations <| fun (ok, ko, _) ->
            JQuery.Ajax(
                JQuery.AjaxSettings(
                    Url = url,
                    Type = As<JQuery.RequestType> method,
                    ContentType = "application/json",
                    DataType = JQuery.DataType.Text,
                    Data = serializedData,
                    Success = (fun (result, _, _) -> ok (result :?> string)),
                    Error = (fun (jqXHR, _, _) -> ko (System.Exception(jqXHR.ResponseText)))))
            |> ignore

    /// Use Json.Serialize and Deserialize to send and receive data to and from the server.
    let PostBlogArticle (article: Article) : Async<int> =
        async { let! response = Ajax "POST" "/article" (Json.Serialize article)
                return Json.Deserialize<int> response }

This new API is located in the module WebSharper.Json. Its only limitation compared with Sitelets is that the [<DateTimeFormat>] attribute is currently ignored, as JavaScript doesn't have built-in datetime formatting capabilities. We might consider using an external library such as moment.js for this purpose in the future.

Future plans

We have lots of exciting things to come in WebSharper. Here is what you can expect from upcoming releases:

  • F# 4.0 support, including JavaScript proxies for the new collection library functions.
  • A new, cleaner HTML combinator syntax. This syntax will supersede the current Html.Server, Html.Client and UI.Next.HTML with a unique type. This means that the same HTML code will be usable both from the server and client side.

Happy coding!