Commit 55565170 authored by Rinus Plasmeijer's avatar Rinus Plasmeijer
Browse files

*** empty log message ***

parent 13e93635
...@@ -7,10 +7,11 @@ import ...@@ -7,10 +7,11 @@ import
// intended for end user: // intended for end user:
htmlHandler // the kernel module for iData creation htmlFormlib // handy collection of form creating functions
, htmlFormData // iData type definitions , htmlButtons // basic collections of buttons, data types for lay-out control
, htmlFormlib // illustrative collection of form creating functions defined on top of htmlHandler , htmlHandler // the kernel module for iData creation
, htmlFormData // iData type definitions
, htmlDataDef // Clean's ADT representation of Html , htmlDataDef // Clean's ADT representation of Html
, htmlStyleDef // Clean's ADT representation of Style sheets , htmlStyleDef // Clean's ADT representation of Style sheets
......
definition module htmlButtons
// Prdefined i-Data making html Buttons, forms, and lay-out
import htmlHandler
derive gForm (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
derive gUpd (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
derive gPrint (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
derive gParse (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
instance toBool CheckBox, Button, RadioButton // True if checkbox checked, button pressed
instance toInt PullDownMenu // Current index in pull down list
instance toString PullDownMenu // Corresponding element in pull down list
// lay out
:: <-> a b = (<->) infixl 5 a b // place b to the left of a
:: <|> a b = (<|>) infixl 4 a b // place b below a
:: DisplayMode a
= DisplayMode a // non-editable display of a
| EditMode a // editable
| HideMode a // hiding a
| EmptyMode // nothing to display or hide
// buttons representing classical html buttons
:: Button = Pressed // button pressed
| LButton Int String // label button, size in pixels, label of button
| PButton (Int,Int) String // picture button, (height,width), reference to picture
:: CheckBox = CBChecked String // checkbox checked
| CBNotChecked String // checkbox not checked
:: RadioButton = RBChecked String // radiobutton checked
| RBNotChecked String // radiobutton not checked
:: PullDownMenu = PullDown (Int,Int) (Int,[String]) // pulldownmenu (number visible,width) (item chosen,menulist)
:: TextInput = TI Int Int // Input box of size Size for Integers
| TR Int Real // Input box of size Size for Reals
| TS Int String // Input box of size Size for Strings
// special's
:: Date = Date Int Int Int // Day Month Year
implementation module htmlButtons
import StdEnv, ArgEnv, StdMaybe
import htmlHandler, htmlStylelib, htmlTrivial
derive gUpd (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, /*Button, */CheckBox, RadioButton /*, PullDownMenu, TextInput */
derive gPrint (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
derive gParse (,), (,,), (,,,), (<->), <|>, Date, DisplayMode, Button, CheckBox, RadioButton, PullDownMenu, TextInput
:: TextInput = TI Int Int // Input box of size Size for Integers
| TR Int Real // Input box of size Size for Reals
| TS Int String // Input box of size Size for Strings
// Types that have an effect on lay-out
// Tuples are placed next to each other, pairs below each other ...
gForm{|(,)|} gHa gHb formid hst
# (na,hst) = gHa (reuseFormId formid a) (incrHSt 1 hst) // one more for the now invisable (,) constructor
# (nb,hst) = gHb (reuseFormId formid b) hst
= ( {changed= na.changed || nb.changed
,value = (na.value,nb.value)
,form = [STable [Tbl_CellPadding (Pixels 0), Tbl_CellSpacing (Pixels 0)] [[BodyTag na.form, BodyTag nb.form]]]
},hst)
where
(a,b) = formid.ival
gForm{|(,,)|} gHa gHb gHc formid hst
# (na,hst) = gHa (reuseFormId formid a) (incrHSt 1 hst) // one more for the now invisable (,,) constructor
# (nb,hst) = gHb (reuseFormId formid b) hst
# (nc,hst) = gHc (reuseFormId formid c) hst
= ( {changed= na.changed || nb.changed || nc.changed
,value = (na.value,nb.value,nc.value)
,form = [STable [Tbl_CellPadding (Pixels 0), Tbl_CellSpacing (Pixels 0)] [[BodyTag na.form,BodyTag nb.form,BodyTag nc.form]]]
},hst)
where
(a,b,c) = formid.ival
gForm{|(,,,)|} gHa gHb gHc gHd formid hst
# (na,hst) = gHa (reuseFormId formid a) (incrHSt 1 hst) // one more for the now invisable (,,) constructor
# (nb,hst) = gHb (reuseFormId formid b) hst
# (nc,hst) = gHc (reuseFormId formid c) hst
# (nd,hst) = gHd (reuseFormId formid d) hst
= ( {changed= na.changed || nb.changed || nc.changed || nd.changed
,value = (na.value,nb.value,nc.value,nd.value)
,form = [STable [Tbl_CellPadding (Pixels 0), Tbl_CellSpacing (Pixels 0)]
[[BodyTag na.form,BodyTag nb.form,BodyTag nc.form, BodyTag nd.form]]]
},hst)
where
(a,b,c,d) = formid.ival
// <-> works exactly the same as (,) and places its arguments next to each other, for compatibility with GEC's
gForm{|(<->)|} gHa gHb formid hst
# (na,hst) = gHa (reuseFormId formid a) (incrHSt 1 hst) // one more for the now invisable <-> constructor
# (nb,hst) = gHb (reuseFormId formid b) hst
= ( {changed= na.changed || nb.changed
,value = na.value <-> nb.value
,form = [STable [Tbl_CellPadding (Pixels 0), Tbl_CellSpacing (Pixels 0)] [[BodyTag na.form, BodyTag nb.form]]]
},hst)
where
(a <-> b) = formid.ival
// <|> works exactly the same as PAIR and places its arguments below each other, for compatibility with GEC's
gForm{|(<|>)|} gHa gHb formid hst
# (na,hst) = gHa (reuseFormId formid a) (incrHSt 1 hst) // one more for the now invisable <|> constructor
# (nb,hst) = gHb (reuseFormId formid b) hst
= ( {changed= na.changed || nb.changed
,value = na.value <|> nb.value
,form = [STable [Tbl_CellPadding (Pixels 0), Tbl_CellSpacing (Pixels 0)] [na.form, nb.form]]
},hst)
where
(a <|> b) = formid.ival
// to switch between modes within a type ...
gForm{|DisplayMode|} gHa formid hst
= case formid.ival of
(HideMode a)
# (na,hst) = gHa {formid & mode = Display, ival = a} (incrHSt 1 hst)
= ( {changed= na.changed
,value = HideMode na.value
,form = [EmptyBody]
},hst)
(DisplayMode a)
# (na,hst) = gHa {formid & mode = Display, ival = a} (incrHSt 1 hst)
= ( {changed= False
,value = DisplayMode na.value
,form = na.form
},hst)
(EditMode a)
# (na,hst) = gHa {formid & mode = Edit, ival = a} (incrHSt 1 hst)
= ( {changed= na.changed
,value = EditMode na.value
,form = na.form
},hst)
EmptyMode
= ( {changed= False
,value = EmptyMode
,form = [EmptyBody]
},(incrHSt 1 hst))
// Buttons to press
gForm{|Button|} formid hst
# (cntr,hst) = CntrHSt hst
= case formid.ival of
v=:(LButton size bname)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Button
, Inp_Value (SV bname)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS bname))
, `Inp_Std [Std_Style ("width:" +++ toString size)]
, `Inp_Events [OnClick callClean]
]) ""]
},(incrHSt 1 hst))
v=:(PButton (height,width) ref)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Image
, Inp_Value (SV ref)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS ref))
, `Inp_Std [Std_Style ("width:" +++ toString width +++ " height:" +++ toString height)]
, `Inp_Events [OnClick callClean]
, Inp_Src ref
]) ""]
},(incrHSt 1 hst))
Pressed
= gForm {|*|} (setFormId formid (LButton defpixel "??")) hst // end user should reset button
gForm{|CheckBox|} formid hst
# (cntr,hst) = CntrHSt hst
= case formid.ival of
v=:(CBChecked name)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Checkbox
, Inp_Value (SV name)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, Inp_Checked Checked
, `Inp_Events [OnClick callClean]
]) ""]
},(incrHSt 1 hst))
v=:(CBNotChecked name)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Checkbox
, Inp_Value (SV name)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, `Inp_Events [OnClick callClean]
]) ""]
},(incrHSt 1 hst))
gForm{|RadioButton|} formid hst
# (cntr,hst) = CntrHSt hst
= case formid.ival of
v=:(RBChecked name)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Radio
, Inp_Value (SV name)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, Inp_Checked Checked
, `Inp_Events [OnClick callClean]
]) ""]
},(incrHSt 1 hst))
v=:(RBNotChecked name)
= ( {changed= False
,value = v
,form = [Input (ifEdit formid.mode [] [Inp_Disabled Disabled] ++
[ Inp_Type Inp_Radio
, Inp_Value (SV name)
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, `Inp_Events [OnClick callClean]
]) ""]
},(incrHSt 1 hst))
gForm{|PullDownMenu|} formid hst
# (cntr,hst) = CntrHSt hst
= case formid.ival of
v=:(PullDown (size,width) (menuindex,itemlist))
= ( {changed= False
,value = v
,form = [Select (ifEdit formid.mode [] [Sel_Disabled Disabled] ++
[ Sel_Name ("CS")
, Sel_Size size
, `Sel_Std [Std_Style ("width:" +++ (toString width) +++ "px")]
, `Sel_Events [OnChange callClean]
])
[ Option
[ Opt_Value (encodeTriplet (formid.id,cntr,UpdC (itemlist!!j)))
: if (j == menuindex) [Opt_Selected Selected] []
]
elem
\\ elem <- itemlist & j <- [0..]
]]
},(incrHSt 1 hst))
gForm{|TextInput|} formid hst
# (cntr,hst) = CntrHSt hst
= case formid.ival of
(TI size i)
# (body,hst) = mkInput size formid (IV i) (UpdI i) hst
= ({changed=False, value=TI size i, form=[body]},incrHSt 2 hst)
(TR size r)
# (body,hst) = mkInput size formid (RV r) (UpdR r) hst
= ({changed=False, value=TR size r, form=[body]},incrHSt 2 hst)
(TS size s)
# (body,hst) = mkInput size formid (SV s) (UpdS s) hst
= ({changed=False, value=TS size s, form=[body]},incrHSt 2 hst)
gForm {|Date|} formid hst
= specialize myeditor (Init,formid) hst
where
myeditor (init,formid) hst = mkBimapEditor (init,formid) bimap hst
where
(Date day month year) = formid.ival
bimap = {map_to = toPullDown, map_from = fromPullDown}
where
toPullDown (Date day month year) = (pddays,pdmonths,pdyears)
where
pddays = PullDown (1, defpixel/2) (day-1, [toString i \\ i <- [1..31]])
pdmonths = PullDown (1, defpixel/2) (month-1,[toString i \\ i <- [1..12]])
pdyears = PullDown (1,2*defpixel/3) (year-1, [toString i \\ i <- [2005..2010]])
fromPullDown (pddays,pdmonths,pdyears) = Date (convert pddays) (convert pdmonths) (convert pdyears)
where
convert x = toInt (toString x)
mkBimapEditor :: !(InIDataId d) !(Bimap d v) !*HSt -> (Form d,!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC v
mkBimapEditor inIDataId {map_to,map_from} hst
= mkViewForm inIDataId { toForm = toViewMap map_to
, updForm = \_ v -> v
, fromForm = \_ v -> map_from v
, resetForm = Nothing
} hst
// Update that have to be treated special:
gUpd{|PullDownMenu|} (UpdSearch (UpdC cname) 0) (PullDown (size,width) (menuindex,itemlist))
= (UpdDone,PullDown (size,width) (nmenuindex 0 cname itemlist,itemlist)) // update integer value
where
nmenuindex cnt name [itemname:items]
| name == itemname = cnt
| otherwise = nmenuindex (cnt+1) name items
nmenuindex _ _ [] = -1
gUpd{|PullDownMenu|} (UpdSearch val cnt) v = (UpdSearch val (cnt - 1),v) // continue search, don't change
gUpd{|PullDownMenu|} (UpdCreate l) _ = (UpdCreate l,PullDown (1,defpixel) (0,["error"])) // create default value
gUpd{|PullDownMenu|} mode v = (mode,v) // don't change
gUpd{|Button|} (UpdSearch (UpdS name) 0) _ = (UpdDone,Pressed) // update integer value
gUpd{|Button|} (UpdSearch val cnt) b = (UpdSearch val (cnt - 1),b) // continue search, don't change
gUpd{|Button|} (UpdCreate l) _ = (UpdCreate l,(LButton defsize "Press")) // create default value
gUpd{|Button|} mode b = (mode,b) // don't change
gUpd{|TextInput|} (UpdSearch (UpdI ni) 0) (TI size i) = (UpdDone,TI size ni) // update integer value
gUpd{|TextInput|} (UpdSearch (UpdR nr) 0) (TR size r) = (UpdDone,TR size nr) // update integer value
gUpd{|TextInput|} (UpdSearch (UpdS ns) 0) (TS size s) = (UpdDone,TS size ns) // update integer value
gUpd{|TextInput|} (UpdSearch val cnt) i = (UpdSearch val (cnt - 3),i) // continue search, don't change
gUpd{|TextInput|} (UpdCreate l) _ = (UpdCreate l,TI defsize 0) // create default value
gUpd{|TextInput|} mode i = (mode,i) // don't change
// small utility stuf
instance toBool RadioButton
where toBool (RBChecked _)= True
toBool _ = False
instance toBool CheckBox
where toBool (CBChecked _)= True
toBool _ = False
instance toBool Button
where toBool Pressed = True
toBool _ = False
instance toInt PullDownMenu
where
toInt:: PullDownMenu -> Int
toInt (PullDown _ (i,_)) = i
instance toString PullDownMenu
where
toString (PullDown _ (i,s)) = if (i>=0 && i <length s) (s!!i) ""
...@@ -76,6 +76,8 @@ reuseFormId :: !(FormId a) !d -> (FormId d) // reuse id for new type (only to ...@@ -76,6 +76,8 @@ reuseFormId :: !(FormId a) !d -> (FormId d) // reuse id for new type (only to
initID :: !(FormId d) -> InIDataId d // (Init,FormId a) initID :: !(FormId d) -> InIDataId d // (Init,FormId a)
setID :: !(FormId d) !d -> InIDataId d // (Set,FormId a) setID :: !(FormId d) !d -> InIDataId d // (Set,FormId a)
ifEdit :: !Mode a a -> a // if Mode is Edit then-part else else-part
// manipulating initial values // manipulating initial values
toViewId :: !Init !d! (Maybe d) -> d // copy second on Set or if third is Nothing toViewId :: !Init !d! (Maybe d) -> d // copy second on Set or if third is Nothing
......
...@@ -63,7 +63,9 @@ initID formid = (Init,formid) ...@@ -63,7 +63,9 @@ initID formid = (Init,formid)
setID :: !(FormId d) !d -> InIDataId d // (Set,FormId a) setID :: !(FormId d) !d -> InIDataId d // (Set,FormId a)
setID formid na = (Set,setFormId formid na) setID formid na = (Set,setFormId formid na)
// frequently used variants of mkViewForm ifEdit :: !Mode a a -> a
ifEdit Edit then else = then
ifEdit Display then else = else
toViewId :: !Init !d !(Maybe d) -> d toViewId :: !Init !d !(Maybe d) -> d
toViewId Set d _ = d toViewId Set d _ = d
......
definition module htmlFormlib definition module htmlFormlib
// Handy collection of Form's // Handy collection of Form creating functions and layout functions
// Form library similar to the AGEC lib
// (c) MJP 2005 // (c) MJP 2005
import StdEnv, htmlHandler import StdEnv, htmlHandler, htmlButtons
// **** easy creation of a simple html page **** // **** easy creation of a simple html page ****
...@@ -15,14 +14,14 @@ simpleHtml :: String [BodyTag] -> Html // as above, without HSt ...@@ -15,14 +14,14 @@ simpleHtml :: String [BodyTag] -> Html // as above, without HSt
(<=>) infixl 5 :: [BodyTag] [BodyTag] -> BodyTag // place next to each other on a page (<=>) infixl 5 :: [BodyTag] [BodyTag] -> BodyTag // place next to each other on a page
(<.=.>) infixl 5 :: BodyTag BodyTag -> BodyTag // place next to each other on a page (<.=.>) infixl 5 :: BodyTag BodyTag -> BodyTag // place next to each other on a page
mkRowForm :: [BodyTag] -> BodyTag // place next to each other on a page mkRowForm :: [BodyTag] -> BodyTag // place every element in a row next to each other on a page
(<||>) infixl 4 :: [BodyTag] [BodyTag] -> BodyTag // Place second below first (<||>) infixl 4 :: [BodyTag] [BodyTag] -> BodyTag // Place second below first
(<.||.>) infixl 4 :: BodyTag BodyTag -> BodyTag // Place second below first (<.||.>) infixl 4 :: BodyTag BodyTag -> BodyTag // Place second below first
mkColForm :: [BodyTag] -> BodyTag // Place second below first mkColForm :: [BodyTag] -> BodyTag // Place every element in a column below first
mkSTable :: [[BodyTag]] -> BodyTag // Make a table mkSTable :: [[BodyTag]] -> BodyTag // Make a table
(<=|>) infixl 4 :: [BodyTag] [BodyTag] -> BodyTag // Make a table by putting elements pairwise below each other (<=|>) infixl 4 :: [BodyTag] [BodyTag] -> BodyTag // Make a table by putting elements pairwise below each other
// **** frquently used "mkViewForm" variants **** // **** frquently used "mkViewForm" variants ****
...@@ -51,6 +50,11 @@ layoutListForm :: !([BodyTag] [BodyTag] -> [BodyTag]) ...@@ -51,6 +50,11 @@ layoutListForm :: !([BodyTag] [BodyTag] -> [BodyTag])
!(!(InIDataId a) !*HSt -> (Form a,*HSt)) !(!(InIDataId a) !*HSt -> (Form a,*HSt))
!(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a !(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
// User controlled number of list elements will be shown, including delete and append buttons; Int indicates max number of browse buttons
vertlistFormButs:: !Int !(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
// **** forms for tuples **** // **** forms for tuples ****
t2EditForm :: !(InIDataId (a,b)) !*HSt -> ((Form a,Form b),!*HSt)| gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a t2EditForm :: !(InIDataId (a,b)) !*HSt -> ((Form a,Form b),!*HSt)| gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
...@@ -67,13 +71,16 @@ t4EditForm :: !(InIDataId (a,b,c,d)) !*HSt -> ((Form a,Form b,Form c,Form d) ...@@ -67,13 +71,16 @@ t4EditForm :: !(InIDataId (a,b,c,d)) !*HSt -> ((Form a,Form b,Form c,Form d)
& gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC d & gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC d
// **** special buttons **** // **** special buttons ****
simpleButton :: !String !(a -> a) !*HSt -> (Form (a -> a),!*HSt)
counterForm :: !(InIDataId a) !*HSt -> (Form a,!*HSt) | +, -, one counterForm :: !(InIDataId a) !*HSt -> (Form a,!*HSt) | +, -, one
, gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a , gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
// buttons returning index between 1 to n given stepsize, n, maximal numberofbuttuns to show
browseButtons :: !(InIDataId !Int) !Int !Int !Int !*HSt -> (Form Int,!*HSt)
// **** to each button below a function is assigned which is returned as iData value when the corresponding button is pressed // **** to each button below a function is assigned which is returned as iData value when the corresponding button is pressed
// **** an identity function is returned when none of the set of buttons pressed // **** an identity function is returned when none of the set of buttons pressed
simpleButton :: !String !(a -> a) !*HSt -> (Form (a -> a),!*HSt)
FuncBut :: !(InIDataId (Button, a -> a)) !*HSt -> (Form (a -> a),!*HSt) FuncBut :: !(InIDataId (Button, a -> a)) !*HSt -> (Form (a -> a),!*HSt)
ListFuncBut :: !(InIDataId [(Button, a -> a)]) !*HSt -> (Form (a -> a),!*HSt) ListFuncBut :: !(InIDataId [(Button, a -> a)]) !*HSt -> (Form (a -> a),!*HSt)
TableFuncBut :: !(InIDataId [[(Button, a -> a)]]) !*HSt -> (Form (a -> a),!*HSt) TableFuncBut :: !(InIDataId [[(Button, a -> a)]]) !*HSt -> (Form (a -> a),!*HSt)
...@@ -98,10 +105,6 @@ ListFuncRadio :: !(InIDataId (Int,[Int a -> a])) !*HSt -> (Form (a -> a,Int) ...@@ -98,10 +105,6 @@ ListFuncRadio :: !(InIDataId (Int,[Int a -> a])) !*HSt -> (Form (a -> a,Int)
FuncMenu :: !(InIDataId (Int,[(String, a -> a)])) !*HSt -> (Form (a -> a,Int),!*HSt) FuncMenu :: !(InIDataId (Int,[(String, a -> a)])) !*HSt -> (Form (a -> a,Int),!*HSt)
// browseButtons initial index, step, length, numberofbuttuns, formid
// returns buttons to step through numbers from 1 to length
browseButtons :: !(InIDataId !Int) !Int !Int !Int !*HSt -> (Form Int,!*HSt)
// **** scripts **** // **** scripts ****
......
...@@ -120,6 +120,56 @@ horlistForm inIDataId hSt = layoutListForm (\f1 f2 -> [f1 <=> f2]) mkEditForm in ...@@ -120,6 +120,56 @@ horlistForm inIDataId hSt = layoutListForm (\f1 f2 -> [f1 <=> f2]) mkEditForm in
vertlistForm :: !(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a vertlistForm :: !(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
vertlistForm inIDataId hSt = layoutListForm (\f1 f2 -> [f1 <||> f2]) mkEditForm inIDataId hSt vertlistForm inIDataId hSt = layoutListForm (\f1 f2 -> [f1 <||> f2]) mkEditForm inIDataId hSt
vertlistFormButs :: !Int !(InIDataId [a]) !*HSt -> (Form [a],!*HSt) | gForm{|*|}, gUpd{|*|}, gPrint{|*|}, gParse{|*|}, TC a
vertlistFormButs nbuts (init,formid) hst
# indexId = subFormId formid "idx" 0
# (index,hst) = mkEditForm (init,indexId) hst
# (list,hst) = listForm (init,formid) hst
# lengthlist = length list.value
# pdmenu = PullDown (1,defpixel) (0, [toString lengthlist +++ " More... " :["Show " +++ toString i \\ i <- [1 .. max 1 lengthlist]]])
# pdmenuId = {subFormId formid "pdm" pdmenu & mode = Edit, lifespan = Session}
# (pdbuts,hst) = mkEditForm (Init, pdmenuId) hst
# (PullDown _ (step,_)) = pdbuts.value
| step == 0 = ({form=pdbuts.form,value=list.value,changed=list.changed || pdbuts.changed},hst)
# bbutsId = {subFormId formid "bb" index.value & mode = Edit, lifespan = Session}
# (bbuts, hst) = browseButtons (Init, bbutsId) step lengthlist nbuts hst
# addId = {subFormId formid "add" addbutton & lifespan = Page}
# (add ,hst) = ListFuncBut (Init, addId) hst
# dellId = {subFormId formid "dell" (delbutton bbuts.value step) & lifespan = Page}
# (del ,hst) = ListFuncBut (Init, dellId) hst
# newlist = del.value (list.value ++ add.value [])
# (list,hst) = listForm (setID formid newlist) hst
# lengthlist = length newlist
# (index,hst) = mkEditForm (setID indexId bbuts.value) hst
# (bbuts, hst) = browseButtons (Init, bbutsId) step lengthlist nbuts hst
# betweenindex = (bbuts.value,bbuts.value + step - 1)
# pdmenu = PullDown (1,defpixel) (step, [toString lengthlist +++ " More... ":["Show " +++ toString i \\ i <- [1 .. max 1 lengthlist]]])
# (pdbuts,hst) = mkEditForm (setID pdmenuId pdmenu) hst
= ( { form = case formid.mode of
Edit -> pdbuts.form ++ [toHtml ("#rec = " +++ toString (length list.value))] ++ bbuts.form ++
[[(toHtml ("nr " +++ toString i) <.||.> del) \\ del <- del.form & i <- [bbuts.value..]] <=|> list.form%betweenindex] ++
add.form