{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Yesod.Form.Jquery
( YesodJquery (..)
, jqueryDayField
, jqueryDatePickerDayField
, jqueryAutocompleteField
, jqueryAutocompleteField'
, googleHostedJqueryUiCss
, JqueryDaySettings (..)
, Default (..)
) where
import Yesod.Core
import Yesod.Form
import Data.Time (Day)
import Data.Default
import Text.Julius (rawJS)
import Data.Text (Text, pack, unpack)
import Data.Monoid (mconcat)
googleHostedJqueryUiCss :: Text -> Text
googleHostedJqueryUiCss :: Text -> Text
googleHostedJqueryUiCss Text
theme = forall a. Monoid a => [a] -> a
Data.Monoid.mconcat
[ Text
"//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/"
, Text
theme
, Text
"/jquery-ui.css"
]
class YesodJquery a where
urlJqueryJs :: a -> Either (Route a) Text
urlJqueryJs a
_ = forall a b. b -> Either a b
Right Text
"//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"
urlJqueryUiJs :: a -> Either (Route a) Text
urlJqueryUiJs a
_ = forall a b. b -> Either a b
Right Text
"//ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"
urlJqueryUiCss :: a -> Either (Route a) Text
urlJqueryUiCss a
_ = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Text -> Text
googleHostedJqueryUiCss Text
"cupertino"
urlJqueryUiDateTimePicker :: a -> Either (Route a) Text
urlJqueryUiDateTimePicker a
_ = forall a b. b -> Either a b
Right Text
"http://github.com/gregwebs/jquery.ui.datetimepicker/raw/master/jquery.ui.datetimepicker.js"
jqueryDayField :: (RenderMessage site FormMessage, YesodJquery site) => JqueryDaySettings -> Field (HandlerFor site) Day
jqueryDayField :: forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
JqueryDaySettings -> Field (HandlerFor site) Day
jqueryDayField = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
JqueryDaySettings -> Text -> Field (HandlerFor site) Day
jqueryDayField' Text
"date"
jqueryDatePickerDayField :: (RenderMessage site FormMessage, YesodJquery site) => JqueryDaySettings -> Field (HandlerFor site) Day
jqueryDatePickerDayField :: forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
JqueryDaySettings -> Field (HandlerFor site) Day
jqueryDatePickerDayField = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
JqueryDaySettings -> Text -> Field (HandlerFor site) Day
jqueryDayField' Text
"text"
jqueryDayField' :: (RenderMessage site FormMessage, YesodJquery site) => JqueryDaySettings -> Text -> Field (HandlerFor site) Day
jqueryDayField' :: forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
JqueryDaySettings -> Text -> Field (HandlerFor site) Day
jqueryDayField' JqueryDaySettings
jds Text
inputType = Field
{ fieldParse :: [Text]
-> [FileInfo]
-> HandlerFor
site
(Either (SomeMessage (HandlerSite (HandlerFor site))) (Maybe Day))
fieldParse = forall (m :: * -> *) site a.
(Monad m, RenderMessage site FormMessage) =>
(Text -> Either FormMessage a)
-> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a))
parseHelper forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall a b. a -> Either a b
Left FormMessage
MsgInvalidDay)
forall a b. b -> Either a b
Right
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Read a => String -> Maybe a
readMay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack
, fieldView :: FieldViewFunc (HandlerFor site) Day
fieldView = \Text
theId Text
name [(Text, Text)]
attrs Either Text Day
val Bool
isReq -> do
forall site a (m :: * -> *).
(ToWidget site a, MonadWidget m, HandlerSite m ~ site) =>
a -> m ()
toWidget [shamlet|
$newline never
<input id="#{theId}" name="#{name}" *{attrs} type="#{inputType}" :isReq:required="" value="#{showVal val}">
|]
forall (m :: * -> *) site.
(HandlerSite m ~ site, MonadWidget m) =>
(site -> Either (Route site) Text) -> m ()
addScript' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryJs
forall (m :: * -> *) site.
(HandlerSite m ~ site, MonadWidget m) =>
(site -> Either (Route site) Text) -> m ()
addScript' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryUiJs
forall (m :: * -> *) site.
(MonadWidget m, HandlerSite m ~ site) =>
(site -> Either (Route site) Text) -> m ()
addStylesheet' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryUiCss
forall site a (m :: * -> *).
(ToWidget site a, MonadWidget m, HandlerSite m ~ site) =>
a -> m ()
toWidget [julius|
$(function(){
var i = document.getElementById("#{rawJS theId}");
if (i.type != "date") {
$(i).datepicker({
dateFormat:'yy-mm-dd',
changeMonth:#{jsBool $ jdsChangeMonth jds},
changeYear:#{jsBool $ jdsChangeYear jds},
numberOfMonths:#{rawJS $ mos $ jdsNumberOfMonths jds},
yearRange:#{toJSON $ jdsYearRange jds}
});
}
});
|]
, fieldEnctype :: Enctype
fieldEnctype = Enctype
UrlEncoded
}
where
showVal :: Either Text Day -> Text
showVal = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (String -> Text
pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show)
jsBool :: Bool -> Value
jsBool Bool
True = forall a. ToJSON a => a -> Value
toJSON Bool
True
jsBool Bool
False = forall a. ToJSON a => a -> Value
toJSON Bool
False
mos :: Either a (a, a) -> String
mos (Left a
i) = forall a. Show a => a -> String
show a
i
mos (Right (a
x, a
y)) = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ String
"["
, forall a. Show a => a -> String
show a
x
, String
","
, forall a. Show a => a -> String
show a
y
, String
"]"
]
jqueryAutocompleteField :: (RenderMessage site FormMessage, YesodJquery site)
=> Route site -> Field (HandlerFor site) Text
jqueryAutocompleteField :: forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
Route site -> Field (HandlerFor site) Text
jqueryAutocompleteField = forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
Int -> Route site -> Field (HandlerFor site) Text
jqueryAutocompleteField' Int
2
jqueryAutocompleteField' :: (RenderMessage site FormMessage, YesodJquery site)
=> Int
-> Route site
-> Field (HandlerFor site) Text
jqueryAutocompleteField' :: forall site.
(RenderMessage site FormMessage, YesodJquery site) =>
Int -> Route site -> Field (HandlerFor site) Text
jqueryAutocompleteField' Int
minLen Route site
src = Field
{ fieldParse :: [Text]
-> [FileInfo]
-> HandlerFor
site
(Either (SomeMessage (HandlerSite (HandlerFor site))) (Maybe Text))
fieldParse = forall (m :: * -> *) site a.
(Monad m, RenderMessage site FormMessage) =>
(Text -> Either FormMessage a)
-> [Text] -> [FileInfo] -> m (Either (SomeMessage site) (Maybe a))
parseHelper forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right
, fieldView :: FieldViewFunc (HandlerFor site) Text
fieldView = \Text
theId Text
name [(Text, Text)]
attrs Either Text Text
val Bool
isReq -> do
forall site a (m :: * -> *).
(ToWidget site a, MonadWidget m, HandlerSite m ~ site) =>
a -> m ()
toWidget [shamlet|
$newline never
<input id="#{theId}" name="#{name}" *{attrs} type="text" :isReq:required="" value="#{either id id val}" .autocomplete>
|]
forall (m :: * -> *) site.
(HandlerSite m ~ site, MonadWidget m) =>
(site -> Either (Route site) Text) -> m ()
addScript' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryJs
forall (m :: * -> *) site.
(HandlerSite m ~ site, MonadWidget m) =>
(site -> Either (Route site) Text) -> m ()
addScript' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryUiJs
forall (m :: * -> *) site.
(MonadWidget m, HandlerSite m ~ site) =>
(site -> Either (Route site) Text) -> m ()
addStylesheet' forall a. YesodJquery a => a -> Either (Route a) Text
urlJqueryUiCss
forall site a (m :: * -> *).
(ToWidget site a, MonadWidget m, HandlerSite m ~ site) =>
a -> m ()
toWidget [julius|
$(function(){$("##{rawJS theId}").autocomplete({source:"@{src}",minLength:#{toJSON minLen}})});
|]
, fieldEnctype :: Enctype
fieldEnctype = Enctype
UrlEncoded
}
addScript' :: (HandlerSite m ~ site, MonadWidget m) => (site -> Either (Route site) Text) -> m ()
addScript' :: forall (m :: * -> *) site.
(HandlerSite m ~ site, MonadWidget m) =>
(site -> Either (Route site) Text) -> m ()
addScript' site -> Either (Route site) Text
f = do
site
y <- forall (m :: * -> *). MonadHandler m => m (HandlerSite m)
getYesod
forall (m :: * -> *).
MonadWidget m =>
Either (Route (HandlerSite m)) Text -> m ()
addScriptEither forall a b. (a -> b) -> a -> b
$ site -> Either (Route site) Text
f site
y
addStylesheet' :: (MonadWidget m, HandlerSite m ~ site)
=> (site -> Either (Route site) Text)
-> m ()
addStylesheet' :: forall (m :: * -> *) site.
(MonadWidget m, HandlerSite m ~ site) =>
(site -> Either (Route site) Text) -> m ()
addStylesheet' site -> Either (Route site) Text
f = do
site
y <- forall (m :: * -> *). MonadHandler m => m (HandlerSite m)
getYesod
forall (m :: * -> *).
MonadWidget m =>
Either (Route (HandlerSite m)) Text -> m ()
addStylesheetEither forall a b. (a -> b) -> a -> b
$ site -> Either (Route site) Text
f site
y
readMay :: Read a => String -> Maybe a
readMay :: forall a. Read a => String -> Maybe a
readMay String
s = case forall a. Read a => ReadS a
reads String
s of
(a
x, String
_):[(a, String)]
_ -> forall a. a -> Maybe a
Just a
x
[] -> forall a. Maybe a
Nothing
data JqueryDaySettings = JqueryDaySettings
{ JqueryDaySettings -> Bool
jdsChangeMonth :: Bool
, JqueryDaySettings -> Bool
jdsChangeYear :: Bool
, JqueryDaySettings -> String
jdsYearRange :: String
, JqueryDaySettings -> Either Int (Int, Int)
jdsNumberOfMonths :: Either Int (Int, Int)
}
instance Default JqueryDaySettings where
def :: JqueryDaySettings
def = JqueryDaySettings
{ jdsChangeMonth :: Bool
jdsChangeMonth = Bool
False
, jdsChangeYear :: Bool
jdsChangeYear = Bool
False
, jdsYearRange :: String
jdsYearRange = String
"c-10:c+10"
, jdsNumberOfMonths :: Either Int (Int, Int)
jdsNumberOfMonths = forall a b. a -> Either a b
Left Int
1
}