Luke Plant avatar Luke Plant committed 4e0e213

Implemented OptionList widget

Comments (0)

Files changed (3)

     Ella.Param, Ella.Forms.Widgets,
     Ella.Forms.Base, Ella.Forms.Widgets.TextInput, Ella.Forms.Widgets.Textarea,
     Ella.Forms.Widgets.RadioButton, Ella.Forms.Widgets.RadioButtonList, 
+    Ella.Forms.Widgets.OptionList,
     Ella.TestUtils
   Other-Modules:
     Ella.CGI.Header, Ella.CGI.Multipart

src/Ella/Forms/Widgets/OptionList.hs

+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}
+
+module Ella.Forms.Widgets.OptionList where
+
+import Control.Monad (liftM)
+import Data.Maybe (catMaybes)
+import Ella.Forms.Base
+import Ella.GenUtils (nullToNothing)
+import qualified Text.XHtml as X
+import Text.XHtml ( (<<)
+                  , (!)
+                  )
+
+data OptionList = OptionList {
+      selectedValues :: [String]
+    , name :: String
+    , identifier :: String
+    , values :: [String]
+    , captions :: [String]
+    , multiple :: Bool
+    , size :: Int
+}
+
+instance X.HTML OptionList where
+    toHtml ol = let attrs = [ X.name $ name ol
+                            , X.size $ show $ size ol
+                            ] ++ catMaybes
+                            [ liftM X.identifier $ nullToNothing $ identifier ol
+                            , if multiple ol then Just $ X.multiple else Nothing
+                            ]
+                in X.select ! attrs
+                       << (X.toHtml $ do
+                             (val, caption) <- zip (values ol) (captions ol)
+                             let optattrs = [ X.value val ] ++
+                                            if val `elem` selectedValues ol
+                                            then [ X.selected ]
+                                            else [ ]
+                             return $ X.option ! optattrs << (X.toHtml caption)
+                          )
+
+instance HasId OptionList where
+    setId theid t = t { identifier = theid }
+    getId t = identifier t
+
+instance HasVal OptionList [String] where
+    setVal val t = t { selectedValues = val }
+    getVal t = selectedValues t

testsuite/Tests/Ella/Forms/Widgets.hs

 import Text.XHtml ((!))
 import Ella.Forms.Base
 import Ella.Forms.Widgets
+import qualified Ella.Forms.Widgets.OptionList as OL
 import qualified Ella.Forms.Widgets.RadioButton as RB
 import qualified Ella.Forms.Widgets.RadioButtonList as RBL
 import qualified Ella.Forms.Widgets.TextInput as TI
                                                           , captions = map X.toHtml ["Label 1", "Label 2"]
                                                           })
 
+testOptionListRender = ("<select name=\"foo\" size=\"8\" id=\"id_foo\" multiple=\"multiple\">" ++
+                        "<option value=\"val1\">Value 1</option>" ++
+                        "<option value=\"val2\" selected=\"selected\">Value 2</option>" ++
+                        "<option value=\"val3\">Value 3</option>" ++
+                        "<option value=\"val4\" selected=\"selected\">Value 4</option>" ++
+                        "</select>") ~=?
+                       (render $ OL.OptionList { selectedValues = ["val2", "val4"]
+                                               , name = "foo"
+                                               , identifier = "id_foo"
+                                               , values = ["val1", "val2", "val3", "val4"]
+                                               , captions = ["Value 1", "Value 2", "Value 3", "Value 4"]
+                                               , multiple = True
+                                               , size = 8
+                                               })
+
 
 tests = test [ testTextInputRender_1
              , testTextInputRender_2
              , testRadioButtonRender
              , testRadioButtonRender2
              , testRadioButtonListRender
+             , testOptionListRender
              ]
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.