packages feed

digestive-functors-blaze 0.0.2.2 → 0.1.0.0

raw patch · 2 files changed

+141/−38 lines, 2 filesdep ~blaze-htmldep ~digestive-functorsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: blaze-html, digestive-functors

API changes (from Hackage documentation)

+ Text.Digestive.Blaze.Html5: inputList :: (Monad m, Functor m, FormInput i f) => Formlet m i e BlazeFormHtml Int -> Formlet m i e BlazeFormHtml a -> Formlet m i e BlazeFormHtml [a]
+ Text.Digestive.Blaze.Html5: inputListJs :: String
- Text.Digestive.Blaze.Html5: inputHidden :: (Monad m, Functor m, FormInput i f) => Maybe String -> Form m i e BlazeFormHtml String
+ Text.Digestive.Blaze.Html5: inputHidden :: (Monad m, Functor m, FormInput i f) => Formlet m i e BlazeFormHtml String
- Text.Digestive.Blaze.Html5: inputText :: (Monad m, Functor m, FormInput i f) => Maybe String -> Form m i e BlazeFormHtml String
+ Text.Digestive.Blaze.Html5: inputText :: (Monad m, Functor m, FormInput i f) => Formlet m i e BlazeFormHtml String

Files

digestive-functors-blaze.cabal view
@@ -1,6 +1,6 @@ Name:                digestive-functors-blaze-Version:             0.0.2.2-Synopsis:            Snap backend for the digestive-functors library+Version:             0.1.0.0+Synopsis:            Blaze frontend for the digestive-functors library Description:         This is a blaze frontend for the digestive-functors library.  Homepage:            http://github.com/jaspervdj/digestive-functors@@ -17,5 +17,5 @@   Hs-source-dirs:    src   Exposed-modules:   Text.Digestive.Blaze.Html5   Build-depends:     base >= 4 && < 5,-                     digestive-functors == 0.0.2.*,-                     blaze-html >= 0.3 && < 0.4+                     digestive-functors == 0.1.0.*,+                     blaze-html >= 0.3 && < 0.6
src/Text/Digestive/Blaze/Html5.hs view
@@ -13,6 +13,8 @@     , label     , errors     , childErrors+    , inputList+    , inputListJs     , module Text.Digestive.Forms.Html     ) where @@ -20,7 +22,7 @@ import Data.Maybe (fromMaybe) import Data.Monoid (mempty) -import Text.Blaze.Html5 (Html, (!))+import Text.Blaze.Html5 (Html, (!), toValue, toHtml) import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as A @@ -41,7 +43,7 @@               -> Html                          -- ^ HTML element               -> Html                          -- ^ Resulting element applyClasses' = applyClasses $ \element value ->-    element ! A.class_ (H.stringValue value)+    element ! A.class_ (toValue value)  -- | Checks the input element when the argument is true --@@ -50,24 +52,22 @@ checked True  x = x ! A.checked "checked"  inputText :: (Monad m, Functor m, FormInput i f)-          => Maybe String-          -> Form m i e BlazeFormHtml String+          => Formlet m i e BlazeFormHtml String inputText = Forms.inputString $ \id' inp -> createFormHtml $ \cfg ->     applyClasses' [htmlInputClasses] cfg $         H.input ! A.type_ "text"-                ! A.name (H.stringValue $ show id')-                ! A.id (H.stringValue $ show id')-                ! A.value (H.stringValue $ fromMaybe "" inp)+                ! A.name (toValue $ show id')+                ! A.id (toValue $ show id')+                ! A.value (toValue $ fromMaybe "" inp)  inputHidden :: (Monad m, Functor m, FormInput i f)-            => Maybe String-            -> Form m i e BlazeFormHtml String+            => Formlet m i e BlazeFormHtml String inputHidden = Forms.inputString $ \id' inp -> createFormHtml $ \cfg ->     applyClasses' [htmlInputClasses] cfg $         H.input ! A.type_ "hidden"-                ! A.name (H.stringValue $ show id')-                ! A.id (H.stringValue $ show id')-                ! A.value (H.stringValue $ fromMaybe "" inp)+                ! A.name (toValue $ show id')+                ! A.id (toValue $ show id')+                ! A.value (toValue $ fromMaybe "" inp)  inputTextArea :: (Monad m, Functor m, FormInput i f)               => Maybe Int                        -- ^ Rows@@ -76,14 +76,14 @@               -> Form m i e BlazeFormHtml String  -- ^ Result inputTextArea r c = Forms.inputString $ \id' inp -> createFormHtml $ \cfg ->     applyClasses' [htmlInputClasses] cfg $ rows r $ cols c $-        H.textarea ! A.name (H.stringValue $ show id')-                   ! A.id (H.stringValue $ show id')-                   $ H.string $ fromMaybe "" inp+        H.textarea ! A.name (toValue $ show id')+                   ! A.id (toValue $ show id')+                   $ toHtml $ fromMaybe "" inp   where     rows Nothing = id-    rows (Just x) = (! A.rows (H.stringValue $ show x))+    rows (Just x) = (! A.rows (toValue $ show x))     cols Nothing = id-    cols (Just x) = (! A.cols (H.stringValue $ show x))+    cols (Just x) = (! A.cols (toValue $ show x))  inputTextRead :: (Monad m, Functor m, FormInput i f, Show a, Read a)               => e@@ -92,18 +92,18 @@ inputTextRead error' = flip Forms.inputRead error' $ \id' inp ->     createFormHtml $ \cfg -> applyClasses' [htmlInputClasses] cfg $         H.input ! A.type_ "text"-                ! A.name (H.stringValue $ show id')-                ! A.id (H.stringValue $ show id')-                ! A.value (H.stringValue $ fromMaybe "" inp)+                ! A.name (toValue $ show id')+                ! A.id (toValue $ show id')+                ! A.value (toValue $ fromMaybe "" inp)  inputPassword :: (Monad m, Functor m, FormInput i f)               => Form m i e BlazeFormHtml String inputPassword = flip Forms.inputString Nothing $ \id' inp ->     createFormHtml $ \cfg -> applyClasses' [htmlInputClasses] cfg $         H.input ! A.type_ "password"-                ! A.name (H.stringValue $ show id')-                ! A.id (H.stringValue $ show id')-                ! A.value (H.stringValue $ fromMaybe "" inp)+                ! A.name (toValue $ show id')+                ! A.id (toValue $ show id')+                ! A.value (toValue $ fromMaybe "" inp)  inputCheckBox :: (Monad m, Functor m, FormInput i f)               => Bool@@ -111,8 +111,8 @@ inputCheckBox inp = flip Forms.inputBool inp $ \id' inp' ->     createFormHtml $ \cfg -> applyClasses' [htmlInputClasses] cfg $         checked inp' $ H.input ! A.type_ "checkbox"-                               ! A.name (H.stringValue $ show id')-                               ! A.id (H.stringValue $ show id')+                               ! A.name (toValue $ show id')+                               ! A.id (toValue $ show id')  inputRadio :: (Monad m, Functor m, FormInput i f, Eq a)            => Bool                        -- ^ Use @<br>@ tags@@ -124,10 +124,10 @@     toView group id' sel val = createFormHtml $ \cfg -> do         applyClasses' [htmlInputClasses] cfg $ checked sel $             H.input ! A.type_ "radio"-                    ! A.name (H.stringValue $ show group)-                    ! A.value (H.stringValue id')-                    ! A.id (H.stringValue id')-        H.label ! A.for (H.stringValue id')+                    ! A.name (toValue $ show group)+                    ! A.value (toValue id')+                    ! A.id (toValue id')+        H.label ! A.for (toValue id')                 $ fromMaybe mempty $ lookup val choices         when br H.br @@ -138,8 +138,8 @@     toView id' = createFormHtmlWith MultiPart $ \cfg -> do         applyClasses' [htmlInputClasses] cfg $             H.input ! A.type_ "file"-                    ! A.name (H.stringValue $ show id')-                    ! A.id (H.stringValue $ show id')+                    ! A.name (toValue $ show id')+                    ! A.id (toValue $ show id')  submit :: Monad m        => String                       -- ^ Text on the submit button@@ -147,15 +147,15 @@ submit text = view $ createFormHtml $ \cfg ->     applyClasses' [htmlInputClasses, htmlSubmitClasses] cfg $         H.input ! A.type_ "submit"-                ! A.value (H.stringValue text)+                ! A.value (toValue text)  label :: Monad m       => String       -> Form m i e BlazeFormHtml () label string = Common.label $ \id' -> createFormHtml $ \cfg ->     applyClasses' [htmlLabelClasses] cfg $-        H.label ! A.for (H.stringValue $ show id')-                $ H.string string+        H.label ! A.for (toValue $ show id')+                $ toHtml string  errorList :: [Html] -> BlazeFormHtml errorList errors' = createFormHtml $ \cfg -> unless (null errors') $@@ -169,3 +169,106 @@ childErrors :: Monad m             => Form m i Html BlazeFormHtml () childErrors = Common.childErrors errorList++-- | Wraps the more generic 'Text.Digestive.Forms.inputList' function to+-- provide a reasonable default for adding add/remove controls to a form.+-- The whole thing is wrapped in another div with the class inputList.  For+-- this function to work, the javascript code in 'inputListJs' or something+-- similar must be in scope.+--+-- The user needs to specify the hidden formlet because transformRead requires+-- an error parameter, and this function can't specify it without loss of+-- generality.  The idea is that the extra power of being able to customize+-- the formlet is worth the small amount of extra code compared to having to+-- specify the error.+--+inputList :: (Monad m, Functor m, FormInput i f)+          => Formlet m i e BlazeFormHtml Int+          -- ^ The formlet holding the number of items in the list+          -> Formlet m i e BlazeFormHtml a+          -- ^ The formlet used for each list item.  This function surrounds it+          -- with a div tag with the inputListItem class.+          -> Formlet m i e BlazeFormHtml [a]+          -- ^ The dynamic list formlet+inputList hidden single d =+    mapView (fmap addControls) $ Forms.inputList hidden s d+  where+    s def = mapView (fmap (H.div ! A.class_ "inputListItem")) $ single def+    addControls form = do+        H.div ! A.class_ "inputList" $ do+            H.div $ do+                H.input ! A.type_ "button"+                        ! A.onclick "addItem(this); return false;"+                        ! A.value "Add Item"+                H.input ! A.type_ "button"+                        ! A.onclick "removeItem(this); return false;"+                        ! A.value "Remove Item"+            form++-- | A string containing the javascript functions needed for inputList.  This+-- code requires JQuery.+--+inputListJs :: String+inputListJs = unlines+    ["// Requires that JQuery also be in scope"+    ,"function findInputList(button) {"+    ,"  var mainDiv = $(button).parent();"+    ,"  while ( !mainDiv.hasClass('inputList') ) {"+    ,"    mainDiv = $(mainDiv).parent();"+    ,"  }"+    ,"  return mainDiv;"+    ,"}"+    ,""+    ,"function findItems(button) {"+    ,"  return $('.inputListItem', findInputList(button));"+    ,"}"+    ,""+    ,"function addItem(button) {"+    ,"  var count = $(':hidden', findInputList(button))[0];"+    ,"  var items = findItems(button);"+    ,"  var item = $(items[items.length-1]);"+    ,"  var newItem = item.clone(true);"+    ,"  var i;"+    ,""+    ,"  // Increment counter"+    ,"  $(count).val(parseInt($(count).val())+1);"+    ,""+    ,"  // We have to change the raw html because IE doesn't allow the"+    ,"  // name field to be changed."+    ,"  newItem.html(newItem.html().replace(/fval\\[(\\d+\\.)*(\\d+)\\.(\\d+)\\]/g,"+    ,"    function(a, b, c, d) {"+    ,"      var newC = parseInt(c)+1;"+    ,"      return a.replace(/\\d+\\.\\d+\\]/, newC+'.'+d+']');"+    ,"    }"+    ,"  ));"+    ,"  newItem.appendTo(item.parent());"+    ,""+    ,"  // Copy the values of all children that had the name attribute set."+    ,"  // The direct html insertion does not preserve the most current"+    ,"  // values.  It only preserves default values, so if we want values"+    ,"  // copied, we have to use an approach like this."+    ,"  var items2 = findItems(button);"+    ,"  var newLast = $(items2[items2.length-1]);"+    ,"  var c1 = $('[name]', item);"+    ,"  var c2 = $('[name]', newLast);"+    ,"  if ( c1.length == c2.length ) {"+    ,"    for ( i = 0; i < c1.length; i++ ) {"+    ,"      $(c2[i]).val($(c1[i]).val());"+    ,"    }"+    ,"  }"+    ,"}"+    ,""+    ,"function removeItem(button) {"+    ,"  var items = findItems(button);"+    ,"  if ( items.length > 1 ) {"+    ,"    var count = $(':hidden', findInputList(button))[0];"+    ,"    var item = $(items[items.length-1]);"+    ,"    item.remove();"+    ,""+    ,"    // Decrement counter"+    ,"    $(count).val(parseInt($(count).val())-1);"+    ,"  } else {"+    ,"    alert('Cannot remove any more rows');"+    ,"  }"+    ,"}"+    ]