Skip to content

Instantly share code, notes, and snippets.

@kujua
Last active February 23, 2017 04:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujua/be062740d201aa0b5212d2aea605167a to your computer and use it in GitHub Desktop.
Save kujua/be062740d201aa0b5212d2aea605167a to your computer and use it in GitHub Desktop.
Form with Elm and Syncfusion Essential Studio
port module AdvancedForm exposing (..)
import AdvancedFormModel exposing (..)
import AdvancedFormView exposing (view)
import AdvancedFormUpdate exposing (update)
import Html exposing (..)
import Time exposing (..)
import Task exposing (..)
main : Program Never Model Msg
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
init : ( Model, Cmd Msg )
init =
(initialModel, Task.perform CurrentTime Time.now)
port setNumber : (String -> msg) -> Sub msg
port setPizza : (String -> msg) -> Sub msg
port setTopping : (String -> msg) -> Sub msg
port removeTopping : (String -> msg) -> Sub msg
port setSize : (String -> msg) -> Sub msg
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch ([
setNumber InputOrderNumber
, setPizza InputPizza
, setTopping InputTopping
, removeTopping RemoveTopping
, setSize InputSize
])a
<!DOCTYPE html>
<html>
<head>
<title>Example Syncfusion - Elm Form</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500|Roboto+Mono|Roboto+Condensed:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.2.0/material.teal-light_blue.min.css" />
<link href="static/css/bootstrap.min.css" rel="stylesheet" />
<link href="static/css/ej.web.all.min.css" rel="stylesheet" />
<link href="static/css/default.css" rel="stylesheet" />
<link href="static/css/default-responsive.css" rel="stylesheet" />
<link href="static/css/ej.responsive.css" rel="stylesheet" />
<link href="static/css/advancedform.css" rel="stylesheet" />
<script src="static/js/jquery-3.1.1.min.js" type="text/javascript"> </script>
<script src="static/js/ej.web.all.min.js" type="text/javascript"></script>
<script src="static/js/properties.js" type="text/javascript"></script>
<script src="static/js/jsrender.min.js"></script>
<script src="advancedform.js" type="text/javascript"></script>
</head>
<body>
<div id="embeddedelm"></div>
<script type="text/javascript">
var elmapp = Elm.AdvancedForm.fullscreen();
elmapp.ports.updateLists.subscribe(function(itemlist) {
$(document).ready(function(){
// window.dbitem =
// [
// { "text": "Calzone"},
// { "text": "Margherita"}
// ];
$("#orderlist").ejListView({
items:itemlist
});
// $("#orders").ejListView({
//
// });
});
});
$(document).ready(function(){
$('#pizzadd').ejDropDownList({
targetID: "pizzaddlist",
watermarkText: "Choose Pizza",
width: "100%",
change: function (args) {
elmapp.ports.setPizza.send(args.value);
}
});
$('#pizzanumber').ejNumericTextbox({
targetID: "pizzanumber",
width: "40%",
value: 1,
minValue: 0,
maxValue: 10,
change: function (args) {
elmapp.ports.setNumber.send(args.value.toString());
}
});
$("#toppingslist").ejListView({
enableCheckMark: true,
mouseUp: function (args) {
if (args.isChecked) {
elmapp.ports.removeTopping.send(args.text);
} else {
elmapp.ports.setTopping.send(args.text);
}
}
});
$("#rmedium").ejRadioButton({
size: "small",
beforeChange: function (args) {
// elmapp.ports.setSize.send(args.value.toString());
}
});
$("#rlarge").ejRadioButton({
size: "small",
change: function (args) {
// elmapp.ports.setSize.send(args.value.toString());
}
});
$("#rxlarge").ejRadioButton({
size: "small",
change: function (args) {
// elmapp.ports.setSize.send(args.value.toString());
}
});
$("#addtoorder").ejButton({
size: "medium",
type: "button",
showRoundedCorner: true
});
// $("#orderlist").ejListView({
//
// });
$("#orders").ejListView({
});
$("#confirmorder").ejButton({
size: "medium",
type: "button",
showRoundedCorner: true
});
$("#cancelorder").ejButton({
size: "medium",
type: "button",
showRoundedCorner: true
});
});
</script>
</body>
</html>
module AdvancedFormModel exposing (..)
import Time exposing (..)
type alias PizzaOrder =
{ number: String
, pizza: String
, toppings: List String
, size: String
}
type alias Customer =
{ name: String
, address: String
, telephone: String
, ordered: List PizzaOrder
, selected: PizzaOrder
, time: String
, amount: Float
}
type alias Model =
{ temporder: Customer
, orders: List PizzaOrder
, currenttime: String
}
initialModel : Model
initialModel =
Model (Customer "" "" "" [] (PizzaOrder "1" "" [] "") "" 0.00) [] ""
type Msg
= NoOp
| AddOrder
| ConfirmOrder
| CancelOrder
| InputName String
| InputAddress String
| InputTelephone String
| InputOrderNumber String
| InputPizza String
| InputTopping String
| RemoveTopping String
| InputSize String
| CurrentTime Time
port module AdvancedFormUpdate exposing (update)
import AdvancedFormModel exposing (..)
import List.Extra exposing (..)
import Time.DateTime as DT exposing (..)
port updateLists : String -> Cmd msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
(model, Cmd.none)
AddOrder ->
let
t = model.temporder
to = model.temporder.ordered
t_ = {t | ordered = t.selected :: to}
p = toFloat ((List.length t_.ordered))*19.95
m = Model {t_ | time = model.currenttime, amount = p} model.orders model.currenttime
itemlist = calculateOrder model.temporder.selected
in
(m, updateLists itemlist)
ConfirmOrder ->
(model, Cmd.none)
CancelOrder ->
(initialModel, Cmd.none)
InputName name ->
let
t = model.temporder
m = Model {t | name = name} model.orders model.currenttime
in
(m, Cmd.none)
InputAddress address ->
let
t = model.temporder
m = Model {t | address = address} model.orders model.currenttime
in
(m, Cmd.none)
InputTelephone telephone ->
let
t = model.temporder
m = Model {t | telephone = telephone} model.orders model.currenttime
in
(m, Cmd.none)
InputOrderNumber n ->
let
t = model.temporder
s = t.selected
s_ = {s | number = n}
m = Model {t | selected = s_} model.orders model.currenttime
in
(m, Cmd.none)
InputPizza p ->
let
t = model.temporder
s = t.selected
s_ = {s | pizza = p}
m = Model {t | selected = s_} model.orders model.currenttime
in
(m, Cmd.none)
InputTopping topping ->
let
t = model.temporder
s = t.selected
s_ = {s | toppings = topping :: s.toppings}
m = Model {t | selected = s_} model.orders model.currenttime
in
(m, Cmd.none)
RemoveTopping topping ->
let
t = model.temporder
s = t.selected
s_ = {s | toppings = remove topping s.toppings}
m = Model {t | selected = s_} model.orders model.currenttime
in
(m, Cmd.none)
InputSize size ->
let
t = model.temporder
s = t.selected
s_ = {s | size = size}
m = Model {t | selected = s_} model.orders model.currenttime
in
(m, Cmd.none)
CurrentTime time ->
let
t = model.temporder
currentplus = addMinutes (((List.length t.ordered)+1)*40) (fromTimestamp time)
s = toString (DT.hour currentplus) ++ ":" ++ toString (DT.minute currentplus)
in
({model | currenttime = s}, Cmd.none)
-- helper functions
calculateOrder : PizzaOrder -> String
calculateOrder order =
let
o = order.number ++ "x " ++ order.pizza
in
""" [{"text":" """ ++ o ++ """ "}] """
module AdvancedFormView exposing (view, amount2CurrencyFormatter)
import AdvancedFormModel exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Formatting as F exposing (..)
view : Model -> Html Msg
view model =
div [class "container"] [
div [ class "jumbotron", style [("background-color","lightblue")] ] [
h1 [] [ text "Pizza Ordering System" ]
, span [style [("font-size","1.4em")]] [text "Example for Syncfusion Blog. First published "]
, a [href "#", style [("font-size","1.4em")]] [text "here."]
]
, div [class "container-fluid"] [
div [class "row"][
div [class "col-md-5"] [
div [class "frame"] [
div [class "control"] [
Html.form [class "form-horizontal"] [
div [class "form-group"] [
label [for "pizzanumber", class "col-sm-2 control-label", style [("background-color","ghostwhite"),("padding-bottom","3px")]] [
text "Number:"
]
, input [id "pizzanumber", value (toString model.temporder.selected.number), class "form-control"][]
]
, div [class "form-group"][
label [for "pizzadd", class "col-sm-2 control-label", style [("background-color","ghostwhite")]] [
text "Pizza:"
]
, input [id "pizzadd"][]
, div [id "pizzaddlist"] [
ul [] [
li [] [text "Calzone"]
, li [] [text "Margherita"]
]
]
]
, div [class "form-group"][
label [for "pizzadd", class "col-sm-2 control-label", style [("background-color","ghostwhite")]] [
text "Toppings:"
]
, div [id "toppingslist"] [
ul [] [
li [] [text "Cheese"]
, li [] [text "Ham"]
]
]
]
, div [class "row", style [("padding-left","10px"), ("display","none")]][
div [class "col-lg-3"] [
label [for "pmedium", class "", style [("background-color","ghostwhite"),("padding-right","10px")]] [
text "Medium"
]
, input [id "pmedium", type_ "radio", name "pizzasize"] []
]
, div [class "col-lg-3"] [
label [for "plarge", class "", style [("background-color","ghostwhite"),("padding-right","10px")]] [
text "Large"
]
, input [id "plarge", type_ "radio", name "pizzasize"] []
]
, div [class "col-lg-3"] [
label [for "pxlarge", class "", style [("background-color","ghostwhite"),("padding-right","10px")]] [
text "X-Large"
]
, input [id "pxlarge", type_ "radio", name "pizzasize"] []
]
]
, div [class "pull-right", style [("padding-top","15px")]] [
button [id "addtoorder", onClick AddOrder, class ("btn btn-default" ++ (defineAddOrderButtonState model.temporder.selected))] [text "Add to Order"]
]
, br [] []
, br [] []
]
]
]
, br [] []
, div [class "frame"] [
div [class "control"] [
label [for "orderlist"] [text "Ordered"]
, div [id "orderlist"] [
]
, br [] []
, Html.form [class "form-horizontal"] [
div [class "form-group"] [
label [for "fname", class "col-sm-2 control-label", style [("background-color","ghostwhite")]] [
text "Name:"
]
, input [id "fname", type_ "text", value model.temporder.name, class "ejinputtext", style [("width","70%")], onInput InputName ] []
]
, div [class "form-group"] [
label [for "faddress", class "col-sm-2 control-label", style [("background-color","ghostwhite")]] [
text "Address:"
]
, input [id "faddress", type_ "text", value model.temporder.address, class "ejinputtext", style [("width","70%")], onInput InputAddress][]
]
, div [class "form-group"] [
label [for "ftel", class "col-sm-2 control-label", style [("background-color","ghostwhite")]] [
text "Telephone:"
]
, input [id "ftel", type_ "text", value model.temporder.telephone, class "ejinputtext", style [("width","70%")], onInput InputTelephone][]
]
, div [class "form-group"] [
label [class "col-sm-5 control-label", style [("background-color","ghostwhite"),("padding-top","0.7em")]] [
text "Estimated Delivery Time:"
]
, p [id "fdeltime", class "form-control-static", style [("background-color","ghostwhite"),("font-size","1.5em"),("font-weight","bold")]] [text model.temporder.time]
]
, div [class "form-group"] [
label [class "col-sm-5 control-label", style [("background-color","ghostwhite"),("padding-top","0.7em")]] [
text "Price:"
]
, p [id "fprice", class "form-control-static", style [("background-color","ghostwhite"),("font-size","1.5em"),("font-weight","bold")]] [text (amount2CurrencyFormatter model.temporder.amount)]
]
, div [class "pull-right", style [("padding-top","15px"),("padding-left","15px")]] [
button [id "cancelorder", onClick CancelOrder, class "btn btn-default"] [text "Cancel Order"]
]
, div [class "pull-right", style [("padding-top","15px")]] [
button [id "confirmorder", onClick ConfirmOrder, class ("btn btn-default" ++ (defineConfirmOrderButtonState model.temporder))] [text "Confirm Order"]
]
, br [] []
, br [] []
]
]
]
]
, div [class "col-md-5"] [
div [style [("padding-left", "30px")]] [
h2 [style [("margin-top", "0px")]] [ text "All Orders"]
, div [id "orders"] [
ul [] [
li [] [text "2x Margherita -> 6:15"]
]
]
]
]
]
]
]
-- helper functions
renderList : List PizzaOrder -> Html msg
renderList l =
ul[]
(List.map (\item -> li [] [ text item.pizza ]) l)
amount2CurrencyFormatter : Float -> String
amount2CurrencyFormatter =
print (F.s "$ " <> float)
defineAddOrderButtonState : PizzaOrder -> String
defineAddOrderButtonState selected =
case String.isEmpty selected.pizza of
True -> " disabled"
False -> ""
defineConfirmOrderButtonState : Customer -> String
defineConfirmOrderButtonState customer =
let
pname = String.isEmpty customer.name
paddress = String.isEmpty customer.address
ptelephone = String.isEmpty customer.telephone
predicate = pname || paddress || ptelephone
in
case predicate of
True -> " disabled"
False -> ""
{
"version": "1.0.0",
"summary": "Syncfusion example with Elm",
"repository": "https://gist.github.com/kujua/be062740d201aa0b5212d2aea605167a",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-community/elm-time": "1.0.1 <= v < 2.0.0",
"elm-community/list-extra": "6.0.0 <= v < 7.0.0",
"elm-lang/core": "5.1.1 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0",
"krisajenkins/formatting": "4.2.0 <= v < 5.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}
@kujua
Copy link
Author

kujua commented Feb 23, 2017

See Blog Syncfusion for explanations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment