Advertisement
Guest User

ui.next validation commented

a guest
Jul 28th, 2014
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. namespace Validation_Scratchpad
  2.  
  3. open System
  4. open IntelliFactory.WebSharper
  5. open IntelliFactory.WebSharper.UI.Next
  6. open IntelliFactory.WebSharper.UI.Next.Html
  7.  
  8. [<JavaScript>]
  9. module Client =
  10.  
  11.     // Model-y Stuff Here
  12.     type EMailAddress = EMail of string
  13.     type TelephoneNumber = TN of string
  14.  
  15.     let showPhone (TN s) = s
  16.     let showEMail (EMail e) = e
  17.  
  18.     type Person =
  19.         {
  20.             PersonName : string
  21.             PersonEMailAddress : EMailAddress
  22.             PersonTelephoneNumber : TelephoneNumber
  23.         }
  24.  
  25.     let mkPerson name num email =
  26.         {
  27.             PersonName = name
  28.             PersonEMailAddress = email
  29.             PersonTelephoneNumber = num
  30.         }
  31.  
  32.     // Define Result sum type
  33.     type ErrorMsg = string
  34.     type Result<'a> = | Success of 'a | Failure of ErrorMsg
  35.  
  36.     // Helpers
  37.     let txt = Doc.TextNode
  38.     let (==>) attrId attrVal = Attr.Create attrId attrVal
  39.  
  40.     // Validation: takes num var, produces Result<TelephoneNumber>
  41.     let validateNum vNum =
  42.         View.FromVar vNum
  43.         |> View.Map (fun num ->
  44.             if String.forall Char.IsDigit num && num.Length > 0 then
  45.                 TN num |> Success
  46.             else
  47.                 Failure "Not a valid telephone number"
  48.         )
  49.  
  50.     // Same for email
  51.     let validateEmail vEmail =
  52.         View.FromVar vEmail
  53.         |> View.Map (fun (email : string) ->
  54.             if email.Contains("@") then
  55.                 EMail email |> Success
  56.             else
  57.                 Failure "Not a valid email address"
  58.         )
  59.  
  60.     // Displays nothing if success, err if failure
  61.     let DisplayFailure = function
  62.         | Success _ -> ""
  63.         | Failure err -> err + ", "
  64.  
  65.  
  66.     // View.Do and let! translate to View.Bind, so this updates whenever
  67.     // any of the fields change.
  68.     // We take a View<string> for name, and View<Result<TelephoneNumber>> and
  69.     // View<Result<EmailAddress>> for the validated fields
  70.     // NOTE: This won't compile in W# in the public UI.Next just yet (we forgot a JS tag)
  71.     // but will do on next release
  72.     let PersonView nameView telView emailView =
  73.         View.Do {
  74.             let! name = nameView
  75.             let! tel = telView
  76.             let! email = emailView
  77.             match (tel, email) with
  78.                 // If successfully validated for both, we can construct a View<Success<Person>>
  79.                 | (Success t, Success e) ->
  80.                     return mkPerson name t e |> Success
  81.                 | _ ->
  82.                     // If not, we concat the errors to get a failure
  83.                     // This is the bit I'm not happy about -- would be much nicer to make this more
  84.                     // general
  85.                     return
  86.                         DisplayFailure tel + DisplayFailure email
  87.                         |> Failure
  88.         }
  89.  
  90.  
  91.     // Person -> Doc
  92.     let showPerson p =
  93.         Div0 [
  94.             P0 [txt <| "Name: " + p.PersonName]
  95.             P0 [txt <| "Phone Number: " + (showPhone p.PersonTelephoneNumber)]
  96.             P0 [txt <| "EMail Address: " + (showEMail p.PersonEMailAddress)]
  97.         ]
  98.  
  99.     // Result<Person> -> Doc
  100.     let ShowResult personView =
  101.         personView
  102.         |> View.Map (fun personRes ->
  103.             match personRes with
  104.                 | Success p -> showPerson p
  105.                 | Failure errs -> txt errs
  106.         )
  107.  
  108.     // Form and main document
  109.     let myForm =
  110.         // Create variables
  111.         let rvName = Var.Create ""
  112.         let rvTel = Var.Create ""
  113.         let rvEmail = Var.Create ""
  114.  
  115.         Div0 [
  116.             Div0 [
  117.                 // Create form controls
  118.                 Div0 [
  119.                     Html.Label ["for" ==> "nameBox"] [txt "Name:"]
  120.                     Doc.Input ["id" ==> "nameBox"] rvName
  121.                 ]
  122.  
  123.                 Div0 [
  124.                     Html.Label ["for" ==> "telBox"] [txt "Telephone Number:"]
  125.                     Doc.Input ["id" ==> "telBox"] rvTel
  126.                 ]
  127.  
  128.                 Div0 [
  129.                     Html.Label ["for" ==> "emailBox"] [txt "Email:"]
  130.                     Doc.Input ["id" ==> "emailBox"] rvEmail
  131.                 ]
  132.             ]
  133.  
  134.             Div0 [
  135.                 txt "Result"
  136.                 Elements.Br [][]
  137.                 // validateNum and validateEmail perform validation on the names and emails,
  138.                 // producing View<Result<TelephoneNumber>> and View<Result<EMailAddress>>
  139.                 PersonView (View.FromVar rvName) (validateNum rvTel) (validateEmail rvEmail)
  140.                 |> ShowResult
  141.                 |> Doc.EmbedView
  142.             ]
  143.         ]
  144.  
  145.     let Main =
  146.         JavaScript.Log("Running JavaScript Entry Point..")
  147.         Doc.RunById "my-container" myForm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement