module HtmlFormF2( FormInput(..),FormOutput(..),FormMsg(..), formTextAreaF,formSelectF,formInputF ) where import AllFudgets hiding (untaggedListF{-,loopThroughRightF-}) import TagAttrs(TagAttrs,lookupAttr,hasAttr) --import HtmlFormSubmit import SelectF(selectF) import Utils2(space,strToLower) import HbcUtils(assoc) --import DialogueIO --import ContinuationIO(stdout) --import Prelude hiding (IOError) type FormInput = FormMsg type FormOutput = FormMsg data FormMsg = Reset | Submit | RadioChange (String,String) -- (name,value) | Output [(String,String)] deriving (Eq,Show) dummyOutput = Output [] -- output from buttons and unimplemented things formTextAreaF attrs s = editWrapF (name attrs) s $ oldScrollF False (size,size) editorF where size = Point (6*w) (13*h) w = val 60 "COLS" h = val 5 "ROWS" val d a = maybe d read $ lookupAttr a attrs formSelectF attrs options0 = -- !!! Bug: should output the VALUE attribute of the selected option(s), -- if present, otherwise the option text. case (multiple,size) of (False,1) -> wrapF myname def $ loopF $ simpleMenuF menuFont longest optstrings id where def = assoc id (head optstrings) options True longest = (snd . maximum . map (swap.pairwith length)) optstrings _ -> listWrapF myname def (map snd>^==^ F FormInput FormOutput formInputF attrs = case typ of "text" -> formTextF "password" -> formPasswordF "checkbox" -> formCheckboxF "radio" -> formRadioF "submit" -> formSubmitF "reset" -> formResetF "button" -> formButtonF "hidden" -> formHiddenF _ -> if typ `elem` textTypes then formTextF else formUnimplF where textTypes = ["email","number","search","tel","text","url"] typ = strToLower (attr "text" "TYPE") name = attr "noname" "NAME" value d = attr d "VALUE" checked = attr "no" "CHECKED"/="no" val d n = maybe d read $ lookupAttr n attrs attr d n = maybe d id $ lookupAttr n attrs formTextF = strF oldStringF formPasswordF = strF oldPasswdF strF f = iWrapF name (value "") $ f (space (val 20 "SIZE")) -- size could be cols,rows !! formCheckboxF = checkboxWrapF name (value "on") checked toggleF' formRadioF = radioWrapF name (value "on") checked toggleF' toggleF' = fromLeft >^=< toggleF False [] nullF >=^< Left formButtonF = nullSP >^^=< buttonF (value "Button") >=^^< nullSP formSubmitF = formActionF Submit "Submit" [([],"Return"),([],"Enter")] formResetF = formActionF Reset "Reset" [([],"Escape")] formActionF msg deflbl hotkeys = submitWrapF output $ const msg>^==^^^==^^^^=< throughF f where -- A submit buttons name & value should be output only if -- this particular submit button is used to submit the form. submit out (Right Submit) = (dummyOutput,[out]) -- form being submitted submit _ (Left Submit) = (output,[Submit]) -- this submit button was pressed submit _ (Left Reset) = (dummyOutput,[Reset]) -- this is a reset button... submit out _ = (out,[]) wrapF = gWrapF (\n v -> [(n,v)]) listWrapF = gWrapF (map.pair) iWrapF = iWrapF' (\n v -> [(n,v)]) checkboxWrapF name value checked = gWrapF g name checked where g n v = if v then [(n,value)] else [] gWrapF g name def fud = iWrapF' g name def (inputChange>^= case msg of Left imsg -> case inputDone imsg of Just _ -> putSP (Right Submit) $ wrapSP v' _ -> wrapSP v' where v' = stripInputMsg imsg Right Reset -> resetSP Right Submit -> submitSP v _ -> wrapSP v radioWrapF name value def f = loopThroughRightF (absF resetSP) f where resetSP = set def $ submitSP def set = putSP.Left submitSP v = putSP (Right (Output (if v then [(name,value)] else []))) $ wrapSP v wrapSP v = getSP $ \ msg -> case msg of Left v' | v'/=v -> putSP (Right (RadioChange (name,value))) $ wrapSP v' -- If a radio button is turned off (v'==False), -- this msg will turn it back on. Right Reset -> resetSP Right Submit -> submitSP v Right (RadioChange (name',value')) -> if name'==name then let v' = value'==value in if v'/=v then set v' $ wrapSP v' else wrapSP v else wrapSP v _ -> wrapSP v editWrapF name def f = loopThroughRightF (absF resetSP) f where resetSP = putsSP (load def) $ submitSP def load s = [Left c|c<-selectall++[EditReplace s]] submitSP s = putSP (Right (Output [(name,s)])) $ wrapSP wrapSP = getSP $ \ msg -> case msg of Right Reset -> resetSP Right Submit -> putSP (Left EditGetText) $ wrapSP Left (EditText s) -> submitSP s _ -> wrapSP name :: TagAttrs -> String name = maybe "noname" id . lookupAttr "NAME" htmldebug = argFlag "htmldebug" False