By Loïc Denuzière on Tuesday, September 8, 2015 — 0 comments

WebSharper.UI.Next 3.4.19 with OnAfterRenderCore team

We just released WebSharper.UI.Next version 3.4.19 to NuGet. This minor release includes a functionality that is widely used with Html.Client and is now also available in UI.Next: OnAfterRender.

This handler allows you to register a callback to be called right after an element has been inserted into the DOM. This is very useful to run functionality from libraries that require an element to be rendered. For example, Google Maps require the container element to have its dimensions already computed. It is easy to create a map using the afterRender handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Client
open WebSharper.Google.Maps

let MyMap () =
    divAttr [
        attr.style "width: 500px; height: 500px;"
        on.afterRender (fun div ->
            let options =
                MapOptions(
                    Center = LatLng(47.4968222, 19.0548256),
                    Zoom = 12)
            let m = Map(div, options)
            ()
        )
    ] [text "Loading Google Maps..."]

Rendered page.

Like all event handlers, afterRender is available both as an attribute on.afterRender and as a method Elt.OnAfterRender.

This is one more step accomplished towards our ultimate goal to completely replace Html.Client with UI.Next. Happy coding!

By Loïc Denuzière on Wednesday, September 2, 2015 — 1 comment

WebSharper 3.4.14 releasedCore team

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

ASP.NET-hosted OWIN

Previously, a bug prevented the WebSharper.Owin middleware from running on top of ASP.NET using Microsoft.Owin.Host.SystemWeb. This has now been solved, and the following is now possible:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
open global.Owin
open Microsoft.Owin
open WebSharper
open WebSharper.Owin

module Site =
    let Main = Application.SinglePage(fun ctx -> Content.Text "Hello world!")

type Startup() =
    member this.Configuration(app: IAppBuilder) =
        app.UseSitelet(System.Web.HttpRuntime.AppDomainAppPath, Site.Main)
        |> ignore

[<assembly:OwinStartup(typeof<Startup>)>]
do ()

For this you need to install the following NuGet packages in your web application: WebSharper, WebSharper.Owin, Microsoft.Owin.Host.SystemWeb and Mono.Cecil.

On the topic of Owin, the Suave team recently pre-released support for running Owin middleware; we will soon publish a blog entry about running WebSharper applications within Suave.

WebSharper UI.Next

A number of new features have also been added to UI.Next.

Data binding: abstract references and lenses

Until now, UI.Next interactive elements such as Doc.Input were only able to interact directly with a Var of primitive type. This was quite limiting in terms of how you could structure your data at the root of the dataflow graph. For example, if you wanted to have a ListModel with a record type for items, and display it with input fields to edit the individual record fields, then those record fields would need to have type Var<'T> themselves.

The new abstract reference type IRef<'T> relieves this restriction. IRef<'T> is an interface type that represents data that can be directly read or written, or observed by a View<'T>. Conceptually, that's exactly what Var<'T> is, and of course Var<'T> implements this interface; but not only. There are now methods on Var<'T> and ListModel<'K, 'T> that return IRef<'U>s where 'U represents a part of the original 'T. This concept is called lensing. For example:

1
2
3
4
5
6
7
8
type Person = { FirstName: string; LastName: string; Id: Key }

let me : Var<Person> =
  Var.Create { FirstName = "Loïc"; LastName = "Denuzière"; Id = Key.Fresh() }
let myFirstName : IRef<string> =
  me.Lens (fun p -> p.FirstName) (fun p n -> { p with FirstName = n })
let myFirstNameInput =
  Doc.Input [] myFirstName

In the above code, myFirstName is an IRef<string> that lenses into the FirstName field of me. Retrieving myFirstName's value retrieves the FirstName field of the current value of me, and setting myFirstName performs a record update on the current value of me. It is therefore possible to create an input field that is bound to the FirstName field of me. Note how the type Person is able to be entirely immutable.

Even more useful is lensing into ListModels. See for example the following editable list of people:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let people = ListModel.Create (fun p -> p.Id) []
let firstNameOf : Key -> IRef<string> =
  people.LensInto (fun p -> p.FirstName) (fun p n -> { p with FirstName = n })
let lastNameOf : Key -> IRef<string> =
  people.LensInto (fun p -> p.LastName) (fun p n -> { p with LastName = n })
let displayPeople =
  ul [
    people.View |> Doc.ConvertSeqBy people.Key (fun pid person ->
      li [
        Doc.Input [] (firstNameOf pid)
        Doc.Input [] (lastNameOf pid)
      ]
    )
  ]

Creating a lensed reference is currently somewhat awkward, since you have to provide both the get and update functions. We are planning on providing a macro that will be able to infer the update function based on the getter function, making lenses more convenient to use.

Submitters

A simple way to allow the dataflow to react to isolated events is to have a view whose value is taken from an input view, but only gets updated when events occur. This was already possible using View.SnapshotOn, but somewhat more involved than it needed to be. The new type Submitter<'T> simplifies this task:

1
2
3
4
5
6
7
8
9
10
let rvInput = Var.Create "the input data"
let submit = Submitter.Create rvInput.View "no data submitted yet"
div [
  Doc.Input [] rvInput
  Doc.Button "Submit" [] submit.Trigger
  p [
    text "You entered: "
    textView submit.View
  ]
]

Other UI.Next features

  • Add some instance equivalents to static members: the functions View.Map, View.Bind and ListModel.View are now available as instance members on the corresponding types, allowing slightly shorter code for those who prefer this style.

  • ListModel.Key: both as a static and instance member, retrieves the function that is used by a ListModel to get the key of an item. Typically needed by View.Convert*By or Doc.Convert*By (see the lens example above).

  • Doc.BindView: it is rare, when inserting a dynamic doc using Doc.EmbedView, to have a View<Doc> handy; instead, you generally have a View<'T> that needs to be mapped to a View<Doc>. The new function Doc.BindView : ('T -> Doc) -> View<'T> -> Doc combines these two steps in a single function call.

  • Event handlers that can use a View's current value: it is fairly common to need the current value of a reactive View inside the callback of an event handler. It is now very easy to do so using the function Attr.HandlerView, or methods such as on.clickView.

  • Templating: allow an element to be both a hole and a subtemplate. This is useful for example when the hole is to be filled with a list of items, and the subtemplate describes how these items will be displayed.

  • doc.On* methods for standard events have been added, akin to the on.* attributes. They also exist in server-side friendly version, taking a quotation as argument.

  • on.* attributes have been converted to camelCase; for example, on.animationend is now on.animationEnd.

Bug fixes

  • #464: Fixed the client-side JSON encoding of option<_> union case arguments.

  • #463: Track dependencies from the body of [<Macro>]-annotated functions.

  • Fixed the type of JQuery.Position fields from int to float.

  • UI.Next#28: correctly map from string the value of Doc.IntInput and Doc.FloatInput.

Future plans

As mentioned in previous blog entries, our intention is to merge UI.Next into the main WebSharper distribution and to obsolete Html.Client and Html.Server. We are planning to have this done for version 3.5.

At the same time, we are starting to implement UI.Next-based Formlets and Piglets. Piglets are pretty much usable already, while Formlets are still in a more early phase. In both cases, we are seeing huge gains compared with the IntelliFactory.Reactive-based counterparts in terms of code simplicity and safety. Look forward to being able to use Piglets and Formlets within UI.Next!

Happy coding!

By Adam Granicz on Tuesday, September 1, 2015 — 0 comments

Live F# coding and snippets with dependencies in Try WebSharperCore team

Try WebSharper reached an important milestone today: we just released the first bits of on-the-fly typechecking and code completion, and you can now develop F# web snippets, without any installation, online more easily than ever.

Here is what it looks like:

You don't have to do anything fancy, just start typing and the type checker will guide you, including code completion with Ctrl+Space as you would expect. When you are ready to run your snippet, hit Run and you will see your snippet run in the Result panel.

Snippets with dependencies

You may also notice the little gear icon in the F# source tab, with that, now you can set up dependencies for your snippet. Currently, we support a wide range of WebSharper extensions, with more coming soon:

Type

Packages

Charting

WebSharper.Charting, WebSharper.ChartJs

Visualization

WebSharper.D3, WebSharper.Google.Visualization

3D graphics

WebSharper.GlMatrix, WebSharper.O3D

Mobile UIs/apps

WebSharper.SenchaTouch, WebSharper.MaterialUI

WebSharper abstractions

WebSharper.Formlets, WebSharper.Piglets

Reactive development

WebSharper.React, WebSharper.UI.Next

We will add third-party extensions shortly, including a variant of FSharp.Data to enable data-aware snippets that communicate with web services, etc.

Even more enhancements will be coming shortly, until then happy coding!

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

FSharpArm - part 2Community

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 Kimserey Lam on Wednesday, August 26, 2015 — 0 comments

Single page app with WebSharper UI.Next and BootstrapCommunity

ComputationExpressionApproachForRestApi.md@import url(http://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.2.0/katex.min.css);code{color:#c7254e;background-color:#f9f2f4;border-radius:4px}code,kbd{padding:2px 4px}kbd{color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;box-shadow:none}pre{display:block;margin:0 0 10px;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius[...]
>> Read the full article on kimsereyblog.blogspot.com
By István Gansperger on Wednesday, August 26, 2015 — 0 comments

Try WebSharper: update notes for snippetsCommunity

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 availableCore 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 snippetsCore 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 1Community

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 templatesCore 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!