Verified Commit 32eea856 authored by Camil Staps's avatar Camil Staps 🙂

Add withSelect2 Editor modifier to use the Select2 jQuery plugin instead of plain select tags

parent 19b9e825
definition module BasicAPIExamples.Extensions.Select2
import iTasks
from iTasks.Extensions.Admin.WorkflowAdmin import :: Workflow
wf :: String -> Workflow
main :: Task ()
implementation module BasicAPIExamples.Extensions.Select2
import iTasks
import iTasks.Extensions.Editors.Select2
wf :: String -> Workflow
wf a = workflow a "Enter an expression using Select2 input fields" enter
main :: Task ()
main = enter @! ()
:: Expr
= Literal Int
| Add Expr Expr
| Sum [Expr]
derive class iTask Expr
enter :: Task Expr
enter =
Hint "Enter an expression:" @>>
enterInformation [EnterUsing id (withSelect2 gEditor{|*|})] >>! \expr ->
Hint "You entered:" @>>
viewInformation [] expr
Version: 1.4
Global
ProjectRoot: ...
Target: iTasks
Exec: {Project}/BasicAPIExamples/Extensions/Select2
ByteCode: {Project}/BasicAPIExamples/Extensions/Select2.bc
CodeGen
CheckStacks: False
CheckIndexes: True
OptimiseABC: True
GenerateByteCode: True
Application
HeapSize: 209715200
StackSize: 20971520
ExtraMemory: 8192
IntialHeapSize: 204800
HeapSizeMultiplier: 4096
ShowExecutionTime: False
ShowGC: False
ShowStackSize: False
MarkingCollector: False
DisableRTSFlags: False
StandardRuntimeEnv: True
Profile
Memory: False
MemoryMinimumHeapSize: 0
Time: False
Stack: False
Dynamics: True
GenericFusion: False
DescExL: True
Output
Output: ShowConstructors
Font: Monaco
FontSize: 9
WriteStdErr: False
Link
LinkMethod: Static
GenerateRelocations: False
GenerateSymbolTable: False
GenerateLinkMap: False
LinkResources: False
ResourceSource:
GenerateDLL: False
ExportedNames:
StripByteCode: True
KeepByteCodeSymbols: True
PrelinkByteCode: True
Paths
Path: {Project}
Precompile:
Postlink:
MainModule
Name: BasicAPIExamples.Extensions.Select2Main
Dir: {Project}
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
StrictnessAnalysis: True
ListTypes: StrictExportTypes
ListAttributes: True
Warnings: True
Verbose: True
ReadableABC: False
ReuseUniqueNodes: True
Fusion: False
module BasicAPIExamples.Extensions.Select2Main
import BasicAPIExamples.Extensions.Select2
Start :: *World -> *World
Start world = doTasks main world
definition module iTasks.Extensions.Editors.Select2
from iTasks.UI.Editor import :: Editor
withSelect2 :: !(Editor a) -> Editor a
implementation module iTasks.Extensions.Editors.Select2
import StdEnv
import StdMaybe
import Data.Func
import ABC.Interpreter.JavaScript
import iTasks.UI.Editor
JQUERY_JS :== "/select2/jquery-3.5.1.slim.min.js"
SELECT2_JS :== "/select2/select2.min.js"
SELECT2_CSS :== "/select2/select2.min.css"
jQuery :== jsGlobal "jQuery"
withSelect2 :: !(Editor a) -> Editor a
withSelect2 editor=:{Editor | genUI} =
{ Editor
| editor
& genUI = withClientSideInit initUI genUI
}
where
initUI :: !JSVal !*JSWorld -> *JSWorld
initUI me world
# world = addCSSFromUrl SELECT2_CSS world
# (fun,world) = jsWrapFun (initDOMEl me) me world
= (me .# "initDOMEl" .= fun) world
initDOMEl me _ world
# (fun,world) = jsWrapFun (initDOMEl` me) me world
= addJSFromUrl JQUERY_JS (Just fun) world
initDOMEl` me _ world
# (fun,world) = jsWrapFun (initDOMEl`` me) me world
= addJSFromUrl SELECT2_JS (Just fun) world
initDOMEl`` me _ world
# (onSelect,world) = jsWrapFun onSelect me world
// Install select2 on the currently present select fields
# world = installSelect2 onSelect (me .# "domEl") world
// Install a MutationObserver to also install select fields added later
# (onDOMMutation,world) = jsWrapFun (onDOMMutation onSelect) me world
# (observer,world) = jsNew "MutationObserver" onDOMMutation world
# config = jsRecord ["childList" :> True, "subtree" :> True]
= (observer .# "observe" .$! (me .# "domEl", config)) world
installSelect2 onSelect elem world
# (elem,world) = (jQuery .$ elem) world
# (elems,world) = (elem .# "find" .$ "select") world
# (elems,world) = jsValToList` elems id world
= seqSt initSelect2 elems world
where
initSelect2 elem world
# (jelem,world) = (jQuery .$ elem) world
// Don't reinitialize; https://select2.org/programmatic-control/methods#checking-if-the-plugin-is-initialized
# (initialized,world) = (jelem .# "hasClass" .$ "select2-hidden-accessible") world
| jsValToBool` False initialized
= world
// Initialize
# (select2,world) = (jelem .# "select2" .$ ()) world
# world = (select2 .# "on" .$! ("select2:select", onSelect)) world
// Move original select tag to inside the select2 div, so that node list indices computed by iTasks still work
= (elem .# "nextElementSibling" .# "appendChild" .$! elem) world
onSelect {[0]=ev} world
# target = ev .# "target"
# world = (target .# "value" .= ev .# "params" .# "data" .# "id") world
# (ev,world) = jsNew "Event" "change" world
= (target .# "dispatchEvent" .$! ev) world
onDOMMutation onSelect {[0]=mutations} world
# (mutations,world) = jsValToList` mutations id world
= seqSt handleMutation mutations world
where
handleMutation mutation world
# (addedNodes,world) = jsValToList` (mutation .# "addedNodes") id world
= seqSt (installSelect2 onSelect) addedNodes world
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