Commit 4fd3129b authored by Bas Lijnse's avatar Bas Lijnse

Fixed first part of focus problem. Focus is now retained for forms without...

Fixed first part of focus problem. Focus is now retained for forms without submit option or ajax/sapl


git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@122 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent fe6dfd60
......@@ -32,14 +32,15 @@ urlDecode :: !String -> *String
// Form submission handling
callClean :: !(Script -> ElementEvents) !Mode !String !Lifespan -> [ElementEvents]
callClean :: !Bool !Mode !String !Lifespan -> [ElementEvents]
submitscript :: BodyTag
globalstateform :: !Value -> BodyTag
initscript :: BodyTag
globalstateform :: !Value !Value -> BodyTag
// serializing, de-serializing of iData states to strings stored in the html page
EncodeHtmlStates :: ![HtmlState] -> String
DecodeHtmlStatesAndUpdate :: (Maybe [(String, String)]) -> (![HtmlState],!Triplets) // hidden state stored in Client + triplets
DecodeHtmlStatesAndUpdate :: (Maybe [(String, String)]) -> (![HtmlState],!Triplets,!String) // hidden state stored in Client + triplets
// serializing, de-serializing of iData state stored in files
......@@ -57,3 +58,4 @@ globalFormName :== "CleanForm" // name of hidden Html form in which iData state
updateInpName :== "UD" // marks update information
globalInpName :== "GS" // marks global state information
selectorInpName :== "CS_" // marks constructor update
focusInpName :== "FS" // marks the focus of the cursor at the time the form was sent
......@@ -18,24 +18,72 @@ derive gPrint UpdValue, (,,), (,)
// script for transmitting name and value of changed input
callClean :: !(Script -> ElementEvents) !Mode !String !Lifespan -> [ElementEvents]
callClean onSomething Edit _ lsp = [onSomething (SScript ("toclean(this," <+++ isOnClient lsp <+++ ")"))]
callClean onSomething Submit myid lsp = [onSomething (SScript ("toclean2(" <+++ myid <+++ "," <+++ isOnClient lsp <+++ ")"))]
callClean onSomething _ _ _ = []
callClean :: !Bool !Mode !String !Lifespan -> [ElementEvents]
callClean onClick Edit _ lsp = [(onSomething onClick) (SScript ("toclean(this," <+++ isOnClient lsp <+++ "," <+++ (doSubmit onClick) <+++ ")"))]
callClean onClick Submit myid lsp = [(onSomething onClick) (SScript ("toclean2(" <+++ myid <+++ "," <+++ isOnClient lsp <+++ ",true)"))]
callClean onClick _ _ _ = []
onSomething True = OnClick
onSomething False = OnChange
isOnClient Client = "true"
isOnClient _ = "false"
doSubmit True = "true"
doSubmit False = "false"
// Initializes a page with javascript after it has been loaded
// It is currently just used to set the focus back to the place it was before a submit was done
initscript :: BodyTag
initscript
= BodyTag
[ Script [] (SScript
( "var cleanUpdated = false; " +++
"function cleanInit() { " +++
" resetFocus();" +++
" attachFocusHandler(\"input\"); " +++
" attachFocusHandler(\"select\"); " +++
" attachFocusHandler(\"textarea\"); " +++
"} " +++
"function sendToClean() {" +++
" if(cleanUpdated) {" +++
" document." +++ globalFormName +++ "." +++ focusInpName +++ ".value=this.name;" +++
" document." +++ globalFormName +++ ".submit();" +++
" }" +++
"} " +++
"function resetFocus() {" +++
" if(document.getElementById('" +++ focusInpName +++ "').value != '') {" +++
" var inp = document.getElementById(document.getElementById('"+++ focusInpName +++ "').value); " +++
" if (inp != undefined) { inp.focus(); } " +++
" }" +++
"} " +++
"function attachFocusHandler(tagname) {" +++
" elems = document.getElementsByTagName(tagname);" +++
" for(var i = 0; i < elems.length; i++) {" +++
" elems[i].onfocus = sendToClean;" +++
" }" +++
"}"
))]
submitscript :: BodyTag
submitscript
= BodyTag
[ Script [] (SScript
( " function toclean(inp,onclient)" +++
" { document." +++ globalFormName +++ "." +++ updateInpName +++ ".value=inp.name+\"=\"+inp.value;" +++
"document." +++ globalFormName +++ ".submit(); }"
( " function toclean(inp,onclient,submit) {" +++
" document." +++ globalFormName +++ "." +++ updateInpName +++ ".value=inp.name+\"=\"+inp.value; " +++
" document." +++ globalFormName +++ "." +++ focusInpName +++ ".value=this.name;\n;" +++
" if(submit) {" +++
" document." +++ globalFormName +++ ".submit();" +++
" }" +++
" cleanUpdated = true;" +++
" }"
))
, Script [] (SScript
( " function toclean2(form,onclient)" +++
( " function toclean2(form,onclient,submit)" +++
" { " +++
"form.hidden.value=" +++ "document." +++ globalFormName +++ "." +++ globalInpName +++ ".value;" +++
"form.submit();" +++
......@@ -46,8 +94,8 @@ submitscript
// form that contains global state and empty input form for storing updated input
globalstateform :: !Value -> BodyTag
globalstateform globalstate
globalstateform :: !Value !Value -> BodyTag
globalstateform globalstate focus
= Form [ Frm_Name globalFormName
, Frm_Method Post
, Frm_Enctype "multipart/form-data" // what to do to enable large data ??
......@@ -59,6 +107,11 @@ globalstateform globalstate
, Inp_Type Inp_Hidden
, Inp_Value globalstate
] ""
, Input [ Inp_Name focusInpName
, Inp_Type Inp_Hidden
, Inp_Value focus
, `Inp_Std [Std_Id focusInpName]
] ""
]
......@@ -134,28 +187,28 @@ where
// reconstruct HtmlState out of the information obtained from browser
DecodeHtmlStatesAndUpdate :: (Maybe [(String, String)]) -> (![HtmlState],!Triplets)
DecodeHtmlStatesAndUpdate :: (Maybe [(String, String)]) -> (![HtmlState],!Triplets, !String)
DecodeHtmlStatesAndUpdate args
# (_,triplets,state) = DecodeArguments args
= ([states \\states=:(id,_,_,nstate) <- DecodeHtmlStates state | id <> "" || nstate <> ""],triplets) // to be sure that no rubbish is passed on
# (_,triplets,state,focus) = DecodeArguments args
= ([states \\states=:(id,_,_,nstate) <- DecodeHtmlStates state | id <> "" || nstate <> ""],triplets, focus) // to be sure that no rubbish is passed on
// Parse and decode low level information obtained from server
// In case of using a php script and external server:
DecodeArguments :: (Maybe [(String, String)]) -> (!String,!Triplets,!String)
DecodeArguments :: (Maybe [(String, String)]) -> (!String,!Triplets,!String, !String)
DecodeArguments (Just args)
# nargs = length args
| nargs == 0 = ("clean",[],"")
| nargs == 0 = ("clean",[],"","")
| nargs == 1 = DecodeCleanServerArguments (foldl (+++) "" [name +++ "=" +++ value +++ ";" \\ (name,value) <- args])
//TODO: Get focus from form when CleanServer is not used
# tripargs = reverse args // state hidden in last field, rest are triplets
# (state,tripargs) = (urlDecode (snd (hd tripargs)),tl tripargs) // decode state, get triplets highest positions first
# alltriplets = ordertriplets [(triplet,string) \\ (mbtriplet,string) <- map decodeNameValue tripargs, Just triplet <- [parseString mbtriplet]] []
= ("clean",determineChanged alltriplets ,state) // order is important, first the structure than the values ...
= ("clean",determineChanged alltriplets ,state,"") // order is important, first the structure than the values ...
where
DecodeCleanServerArguments :: !String -> (!String,!Triplets,!String) // executable, id + update , new , state
DecodeCleanServerArguments :: !String -> (!String,!Triplets,!String, !String) // executable, id + update , new , state, focus
DecodeCleanServerArguments args
# input = [c \\ c <-: args | not (isControl c) ] // get rid of communication noise
# (thisexe,input) = mscan '\"' input // get rid of garbage
......@@ -166,13 +219,18 @@ where
# (_,input) = mscan '=' input
# input = skipping ['\"GS\"'] input
# (found,index) = FindSubstr ['---'] input
# state = if found (take index input) ['']
# (state, input) = splitAt index input
# state = if found (take index state) ['']
# (_,input) = mscan '=' input
# input = skipping ['\"FS\"'] input
# (found,index) = FindSubstr ['--'] input
# focus = if found (take index input) ['']
# striplet = toString triplet
= if (striplet == "")
("clean", [], toString state)
("clean", [], toString state, toString focus)
(if (isSelector striplet)
("clean", [(fromJust` (decodeChars new) (parseString (decodeChars new)), "")], toString state)
("clean", [(fromJust` (decodeChars triplet) (parseString (decodeChars triplet)) , toString new)], toString state))
("clean", [(fromJust` (decodeChars new) (parseString (decodeChars new)), "")], toString state, toString focus)
("clean", [(fromJust` (decodeChars triplet) (parseString (decodeChars triplet)) , toString new)], toString state, toString focus))
fromJust` _ (Just value) = value
fromJust` string Nothing = ("",0,UpdI 0)
......@@ -224,7 +282,7 @@ traceHtmlInput args=:(Just input)
]
where
(htmlState,triplets) = DecodeHtmlStatesAndUpdate args
(htmlState,triplets,focus) = DecodeHtmlStatesAndUpdate args
showTriplet triplets = [STable [] [[Txt (printToString triplet)] \\ triplet <- triplets]]
showl life = toString life
......
......@@ -141,8 +141,8 @@ gForm{|Button|} (init,formid) hst
[ Inp_Type Inp_Button
, Inp_Value (SV (cleanString bname))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS bname))
, `Inp_Std [Std_Style ("width:" <+++ size)]
, `Inp_Events (callClean OnClick Edit "" formid.lifespan)
, `Inp_Std [Std_Style ("width:" <+++ size), Std_Id (encodeTriplet (formid.id,cntr,UpdS bname))]
, `Inp_Events (callClean True Edit "" formid.lifespan)
]) ""]
},(incrHSt 1 hst))
v=:(PButton (height,width) ref)
......@@ -152,8 +152,8 @@ gForm{|Button|} (init,formid) hst
[ Inp_Type Inp_Image
, Inp_Value (SV (cleanString ref))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS ref))
, `Inp_Std [Std_Style ("width:" <+++ width <+++ " height:" <+++ height)]
, `Inp_Events (callClean OnClick Edit "" formid.lifespan)
, `Inp_Std [Std_Style ("width:" <+++ width <+++ " height:" <+++ height), Std_Id (encodeTriplet (formid.id,cntr,UpdS ref))]
, `Inp_Events (callClean True Edit "" formid.lifespan)
, Inp_Src ref
]) ""]
},incrHSt 1 hst)
......@@ -171,7 +171,8 @@ gForm{|CheckBox|} (init,formid) hst
, Inp_Value (SV (cleanString name))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, Inp_Checked Checked
, `Inp_Events (callClean OnClick formid.mode "" formid.lifespan)
, `Inp_Std [Std_Id (encodeTriplet (formid.id,cntr,UpdS name))]
, `Inp_Events (callClean True formid.mode "" formid.lifespan)
]) ""]
},incrHSt 1 hst)
v=:(CBNotChecked name)
......@@ -181,7 +182,8 @@ gForm{|CheckBox|} (init,formid) hst
[ Inp_Type Inp_Checkbox
, Inp_Value (SV (cleanString name))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, `Inp_Events (callClean OnClick formid.mode "" formid.lifespan)
, `Inp_Std [Std_Id (encodeTriplet (formid.id,cntr,UpdS name))]
, `Inp_Events (callClean True formid.mode "" formid.lifespan)
]) ""]
},incrHSt 1 hst)
......@@ -196,7 +198,8 @@ gForm{|RadioButton|} (init,formid) hst
, Inp_Value (SV (cleanString name))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, Inp_Checked Checked
, `Inp_Events (callClean OnClick formid.mode "" formid.lifespan)
, `Inp_Std [Std_Id (encodeTriplet (formid.id,cntr,UpdS name))]
, `Inp_Events (callClean True formid.mode "" formid.lifespan)
]) ""]
},incrHSt 1 hst)
v=:(RBNotChecked name)
......@@ -206,7 +209,8 @@ gForm{|RadioButton|} (init,formid) hst
[ Inp_Type Inp_Radio
, Inp_Value (SV (cleanString name))
, Inp_Name (encodeTriplet (formid.id,cntr,UpdS name))
, `Inp_Events (callClean OnClick formid.mode "" formid.lifespan)
, `Inp_Std [Std_Id (encodeTriplet (formid.id,cntr,UpdS name))]
, `Inp_Events (callClean True formid.mode "" formid.lifespan)
]) ""]
},incrHSt 1 hst)
......@@ -220,8 +224,8 @@ gForm{|PullDownMenu|} (init,formid) hst=:{submits}
[ Sel_Name (selectorInpName +++ encodeString
(if (menuindex >= 0 && menuindex < length itemlist) (itemlist!!menuindex) ""))
, Sel_Size size
, `Sel_Std [Std_Style ("width:" <+++ width <+++ "px")]
, `Sel_Events (if submits [] (callClean OnChange formid.mode formid.id formid.lifespan))
, `Sel_Std [Std_Style ("width:" <+++ width <+++ "px"), Std_Id (selectorInpName +++ encodeString (if (menuindex >= 0 && menuindex < length itemlist) (itemlist!!menuindex) ""))]
, `Sel_Events (if submits [] (callClean False formid.mode formid.id formid.lifespan))
])
[ Option
[ Opt_Value (encodeTriplet (formid.id,cntr,UpdC (itemlist!!j)))
......@@ -249,6 +253,7 @@ gForm{|TextArea|} (init,formid) hst
, form = [myTable [ [ Textarea [ Txa_Name (encodeTriplet (formid.id,cntr,UpdS string))
, Txa_Rows (if (row == 0) 10 row)
, Txa_Cols (if (col == 0) 50 col)
, `Txa_Std [Std_Id (encodeTriplet (formid.id,cntr,UpdS string))]
] string ]
]
]
......@@ -283,8 +288,8 @@ where
, Inp_Value (SV (cleanString sval))
, Inp_Name (encodeTriplet (formid.id,cntr,updval))
, Inp_Size size
, `Inp_Std [EditBoxStyle, Std_Title "::Password"]
, `Inp_Events if (mode == Edit && not submits) (callClean OnChange Edit "" formid.lifespan) []
, `Inp_Std [EditBoxStyle, Std_Title "::Password", Std_Id (encodeTriplet (formid.id,cntr,updval))]
, `Inp_Events if (mode == Edit && not submits) (callClean False Edit "" formid.lifespan) []
] ""
,incrHSt 1 hst)
| mode == Display
......
......@@ -161,7 +161,10 @@ where
AjaxCombine [Ajax bodytags:ys] debug = [Ajax [("debug",debug):bodytags]:ys]
AjaxCombine [] debug = abort "AjaxCombine cannot combine empty result"
extra_body_attr = [Batt_background (ThisExe +++ "/back35.jpg"),`Batt_Std [CleanStyle]]
extra_body_attr = [ Batt_background (ThisExe +++ "/back35.jpg")
, `Batt_Std [CleanStyle]
, `Batt_Events [OnLoad (SScript "cleanInit()")]
]
extra_style = if StyleSheetIntern internal_css external_ccs
debugInput = if TraceInput (traceHtmlInput args) EmptyBody
......@@ -379,7 +382,7 @@ mkForm (init,formid=:{mode = Submit}) hst=:{submits = False}
] ""
# submit = Input [ Inp_Type Inp_Button
, Inp_Value (SV "Submit")
,`Inp_Events (callClean OnClick Submit formname formid.lifespan)
,`Inp_Events (callClean True Submit formname formid.lifespan)
] ""
# clear = Input [ Inp_Type Inp_Reset, Inp_Value (SV "Clear")] ""
# sform = [Form [ Frm_Method Post
......@@ -490,7 +493,7 @@ where
where
styles = case formid.mode of
Edit -> [ `Sel_Std [Std_Style width, EditBoxStyle]
, `Sel_Events (if submits [] (callClean OnChange Edit formid.id formid.lifespan))
, `Sel_Events (if submits [] (callClean False Edit formid.id formid.lifespan))
]
Submit -> [ `Sel_Std [Std_Style width, EditBoxStyle]
]
......@@ -640,8 +643,8 @@ mkInput size (init,formid=:{mode}) val updval hst=:{cntr,submits}
, Inp_Value val
, Inp_Name (encodeTriplet (formid.id,cntr,updval))
, Inp_Size size
, `Inp_Std [EditBoxStyle, Std_Title (showType val)]
, `Inp_Events if (mode == Edit && not submits) (callClean OnChange formid.mode "" formid.lifespan) []
, `Inp_Std [EditBoxStyle, Std_Title (showType val), Std_Id (encodeTriplet (formid.id,cntr,updval))]
, `Inp_Events if (mode == Edit && not submits) (callClean False formid.mode "" formid.lifespan) []
] ""
, setCntr (cntr+1) hst)
| mode == Display
......
......@@ -100,7 +100,7 @@ TraceInput :== False // show what kind of information is received fro
TraceOutput :== False // show what kind of information is stored when application is finished
TraceThreads :== True // show the threadtable
TraceHttp10 :== False // show what kind of information is received by the Clean http 1.0 HtmlServer
TraceHttp10 :== True // show what kind of information is received by the Clean http 1.0 HtmlServer
TraceHttp11 :== False // show what kind of information is received by the Clean http 1.1 SubServer, stored in TraceFile
// separators
......
......@@ -26,6 +26,7 @@ import EstherBackend
{ fstates :: *FStates // internal tree of states
, triplets :: [(Triplet,String)] // indicates what has changed: which form, which postion, which value
, updateid :: String // which form has changed
, focusid :: String // which input has the focus
}
:: FStates :== Tree_ (String,FormState) // each form needs a different string id
......@@ -79,7 +80,7 @@ where
(<) _ _ = True
emptyFormStates :: *FormStates
emptyFormStates = { fstates = Leaf_ , triplets = [], updateid = ""}
emptyFormStates = { fstates = Leaf_ , triplets = [], updateid = "", focusid = ""}
getTriplets :: !String !*FormStates -> (Triplets,!*FormStates)
getTriplets id formstates=:{triplets} = ([mytrips \\ mytrips=:((tripid,_,_),_) <- triplets | id == tripid] ,formstates)
......@@ -304,7 +305,7 @@ where
retrieveFormStates :: (Maybe [(String, String)]) *NWorld -> (*FormStates,*NWorld) // retrieves all form states hidden in the html page
retrieveFormStates args world
= ({ fstates = retrieveFStates, triplets = triplets, updateid = calc_updateid triplets},world)
= ({ fstates = retrieveFStates, triplets = triplets, updateid = calc_updateid triplets, focusid = focus},world)
where
retrieveFStates
= Balance (sort [(sid,OldState {format = toExistval storageformat state, life = lifespan})
......@@ -315,7 +316,7 @@ where
toExistval PlainString string = PlainStr string // string that has to be parsed in the context where the type is known
toExistval StaticDynamic string = StatDyn (string_to_dynamic` string) // recover the dynamic
(htmlStates,triplets) = DecodeHtmlStatesAndUpdate args
(htmlStates,triplets,focus) = DecodeHtmlStatesAndUpdate args
calc_updateid [] = ""
calc_updateid [(triplet,upd):_] = case triplet of
......@@ -327,11 +328,12 @@ where
// or store them in a persistent file, all depending on the kind of states
storeFormStates :: !FormStates *NWorld -> (BodyTag,*NWorld)
storeFormStates {fstates = allFormStates} world
storeFormStates {fstates = allFormStates, focusid = focus} world
# world = writeAllTxtFileStates allFormStates world // first write all persistens states
= (BodyTag
[ IF_Ajax EmptyBody submitscript // submitscript defined in ajaxscript
, globalstateform (SV encodedglobalstate)
[ IF_Ajax EmptyBody submitscript // submitscript defined in ajaxscript
, initscript // initscript does page initialization in javascript
, globalstateform (SV encodedglobalstate) (SV focus)
],world)
where
encodedglobalstate = EncodeHtmlStates (FStateToHtmlState allFormStates [])
......@@ -467,11 +469,11 @@ derive gMap Tree_
initTestFormStates :: *NWorld -> (*FormStates,*NWorld) // retrieves all form states hidden in the html page
initTestFormStates world
= ({ fstates = Leaf_, triplets = [], updateid = ""},world)
= ({ fstates = Leaf_, triplets = [], updateid = "", focusid = ""},world)
setTestFormStates :: [(Triplet,String)] String String *FormStates *NWorld -> (*FormStates,*NWorld) // retrieves all form states hidden in the html page
setTestFormStates triplets updateid update states world
= ({ fstates = gMap{|*->*|} toOldState states.fstates, triplets = triplets, updateid = updateid},world)
= ({ fstates = gMap{|*->*|} toOldState states.fstates, triplets = triplets, updateid = updateid, focusid = ""},world)
where
toOldState (s,NewState fstate) = (s,OldState fstate)
toOldState else = else
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment