1
+ struct Automatic; end
2
+ const automatic = Automatic ()
3
+
1
4
function _js_array (x:: AbstractDict ; process= string, placeholder= nothing )
2
5
v = OrderedDict[OrderedDict (" key" => key, " val" => i, " id" => " id" * randstring ()) for (i, (key, val)) in enumerate (x)]
3
6
placeholder != = nothing && pushfirst! (v, OrderedDict (" key" => placeholder, " val" => 0 , " id" => " id" * randstring ()))
52
55
function initvalueindex (value, index, vals2idxs;
53
56
multiple = false , default = multiple ? eltype (vals2idxs[])[] : first (vals2idxs[]), rev = false )
54
57
55
- if value === Some ( nothing )
58
+ if value === automatic
56
59
value = (index === nothing ) ? default : vals2idxs[][Observables. _val (index)]
57
60
end
58
61
(value isa AbstractObservable) || (value = Observable {Any} (value))
@@ -117,7 +120,7 @@ function dropdown(::WidgetTheme, options::AbstractObservable;
117
120
placeholder = nothing ,
118
121
label = nothing ,
119
122
multiple = false ,
120
- value = Some ( nothing ) ,
123
+ value = automatic ,
121
124
index = nothing ,
122
125
className = " " ,
123
126
style = PropDict (),
@@ -159,8 +162,7 @@ multiselect(T::WidgetTheme, options; kwargs...) =
159
162
160
163
function multiselect (T:: WidgetTheme , options:: AbstractObservable ; container= node (:div , className= :field ), wrap= identity,
161
164
label = nothing , typ= " radio" , wdgtyp= typ, stack= true , skip= 1 em, hskip= skip, vskip= skip,
162
- value = Some (nothing ), index = nothing , kwargs... )
163
- attributes = merge (get (props (container), :attributes , Dict ()), Dict (" data-bind" => " foreach : options_js" ))
165
+ value = automatic, index = nothing , kwargs... )
164
166
vals2idxs = map (Vals2Idxs, options)
165
167
p = initvalueindex (value, index, vals2idxs, multiple = (typ != " radio" ))
166
168
value, index = p. first, p. second
@@ -169,7 +171,7 @@ function multiselect(T::WidgetTheme, options::AbstractObservable; container=node
169
171
option_array = _js_array (options)
170
172
entry = wrap (InteractBase. entry (s; typ= typ, wdgtyp= wdgtyp, stack= stack, kwargs... ))
171
173
(entry isa Tuple )|| (entry = (entry,))
172
- template = container (attributes = attributes )(
174
+ template = container (attributes = Dict ( " data-bind " => " foreach : options_js " ) )(
173
175
entry...
174
176
)
175
177
ui = knockout (template, [" index" => index, " options_js" => option_array])
@@ -306,45 +308,8 @@ wdg[:options][] = ["c", "d", "e"]
306
308
toggles (T:: WidgetTheme , options; kwargs... ) =
307
309
Widget {:toggles} (multiselect (T, options; typ= " checkbox" , wdgtyp= " toggle" , kwargs... ))
308
310
309
- for (wdg, tag, singlewdg, div, process) in zip ([:togglebuttons , :tabs ], [:button , :li ], [:button , :tab ], [:div , :ul ], [:string , :identity ])
310
- @eval begin
311
- $ wdg (T:: WidgetTheme , options; kwargs... ) = $ wdg (T:: WidgetTheme , Observable (options); kwargs... )
312
-
313
- function $wdg (T:: WidgetTheme , options:: AbstractObservable ; tag = $ (Expr (:quote , tag)),
314
- className = getclass ($ (Expr (:quote , singlewdg)), " fullwidth" ),
315
- activeclass = getclass ($ (Expr (:quote , singlewdg)), " active" ),
316
- index = nothing , value = Some (nothing ),
317
- label = nothing , readout = false , vskip = 1 em, kwargs... )
318
-
319
- vals2idxs = map (Vals2Idxs, options)
320
- p = initvalueindex (value, index, vals2idxs; default = first (vals2idxs[]))
321
- value, index = p. first, p. second
322
-
323
- className = mergeclasses (getclass ($ (Expr (:quote , singlewdg))), className)
324
- updateSelected = js_lambda (" \$ root.index(val)" )
325
- btn = node (tag,
326
- node (:label , attributes = Dict (" data-bind" => " text : key" )),
327
- attributes= Dict (" data-bind" =>
328
- " click: $updateSelected , css: {'$activeclass ' : \$ root.index() == val, '$className ' : true}" ),
329
- )
330
- option_array = _js_array (options; process = $ process)
331
- template = node ($ (Expr (:quote , div)), className = getclass ($ (Expr (:quote , wdg))), attributes = " data-bind" => " foreach : options_js" )(
332
- btn
333
- )
334
-
335
- label != nothing && (template = flex_row (wdglabel (label), template))
336
- ui = knockout (template, [" index" => index, " options_js" => option_array])
337
- slap_design! (ui)
338
-
339
- w = Widget {$(Expr(:quote, wdg))} ([" options" => options, " index" => ui[" index" ], " vals2idxs" => vals2idxs];
340
- scope = ui, output = value, layout = node (:div , className = " field interact-widget" )∘ Widgets. scope)
341
- if readout
342
- w[:display ] = mask (map (parent, vals2idxs); index = index)
343
- w. layout = t -> div (dom " div.field" (Widgets. scope (t)), CSSUtil. vskip (vskip), t[:display ], className = " interact-widget" )
344
- end
345
- w
346
- end
347
- end
311
+ for wdg in [:togglebuttons , :tabs ]
312
+ @eval $ wdg (T:: WidgetTheme , options; kwargs... ) = $ wdg (T:: WidgetTheme , Observable (options); kwargs... )
348
313
end
349
314
350
315
"""
@@ -378,7 +343,39 @@ Note that the `options` can be modified from the widget directly:
378
343
wdg[:options][] = ["c", "d", "e"]
379
344
```
380
345
"""
381
- function togglebuttons end
346
+ function togglebuttons (T:: WidgetTheme , options:: AbstractObservable ;
347
+ className = " " ,
348
+ activeclass = getclass (:button , " active" ),
349
+ index = nothing , value = automatic,
350
+ container = node (:div , className = getclass (:togglebuttons )), wrap= identity,
351
+ label = nothing , readout = false , vskip = 1 em, kwargs... )
352
+
353
+ vals2idxs = map (Vals2Idxs, options)
354
+ p = initvalueindex (value, index, vals2idxs; default = first (vals2idxs[]))
355
+ value, index = p. first, p. second
356
+
357
+ className = mergeclasses (" interact-widget" , getclass (:button ), className)
358
+ updateSelected = js_lambda (" \$ root.index(val)" )
359
+ btn = node (:span ,
360
+ node (:label , attributes = Dict (" data-bind" => " text : key" )),
361
+ attributes= Dict (" data-bind" =>
362
+ " click: $updateSelected , css: {'$activeclass ' : \$ root.index() == val, '$className ' : true}" ),
363
+ )
364
+ option_array = _js_array (options)
365
+ template = container (attributes = " data-bind" => " foreach : options_js" )(wrap (btn))
366
+
367
+ label != nothing && (template = flex_row (wdglabel (label), template))
368
+ ui = knockout (template, [" index" => index, " options_js" => option_array])
369
+ slap_design! (ui)
370
+
371
+ w = Widget {:togglebuttons} ([" options" => options, " index" => ui[" index" ], " vals2idxs" => vals2idxs];
372
+ scope = ui, output = value, layout = Widgets. scope)
373
+ if readout
374
+ w[:display ] = mask (map (parent, vals2idxs); index = index)
375
+ w. layout = t -> div (Widgets. scope (t), CSSUtil. vskip (vskip), t[:display ], className = " interact-widget" )
376
+ end
377
+ w
378
+ end
382
379
383
380
"""
384
381
`tabs(options::AbstractDict; value::Union{T, Observable})`
@@ -411,4 +408,38 @@ Note that the `options` can be modified from the widget directly:
411
408
wdg[:options][] = ["c", "d", "e"]
412
409
```
413
410
"""
414
- function tabs end
411
+ function tabs (T:: WidgetTheme , options:: AbstractObservable ;
412
+ className = " " ,
413
+ activeclass = getclass (:tab , " active" ),
414
+ index = nothing , value = automatic,
415
+ container= node (:div , className = getclass (:tabs )), wrap= identity,
416
+ label = nothing , readout = false , vskip = 1 em, kwargs... )
417
+
418
+ vals2idxs = map (Vals2Idxs, options)
419
+ p = initvalueindex (value, index, vals2idxs; default = first (vals2idxs[]))
420
+ value, index = p. first, p. second
421
+
422
+ className = mergeclasses (" interact-widget" , getclass (:tab ), className)
423
+ updateSelected = js_lambda (" \$ root.index(val)" )
424
+ tab = node (:li ,
425
+ wrap (node (:a , attributes = Dict (" data-bind" => " text: key" ))),
426
+ attributes= Dict (" data-bind" =>
427
+ " click: $updateSelected , css: {'$activeclass ' : \$ root.index() == val, '$className ' : true}" ),
428
+ )
429
+ option_array = _js_array (options)
430
+ template = container (
431
+ node (:ul , attributes = " data-bind" => " foreach : options_js" )(tab)
432
+ )
433
+
434
+ label != nothing && (template = flex_row (wdglabel (label), template))
435
+ ui = knockout (template, [" index" => index, " options_js" => option_array])
436
+ slap_design! (ui)
437
+
438
+ w = Widget {:tabs} ([" options" => options, " index" => ui[" index" ], " vals2idxs" => vals2idxs];
439
+ scope = ui, output = value, layout = Widgets. scope)
440
+ if readout
441
+ w[:display ] = mask (map (parent, vals2idxs); index = index)
442
+ w. layout = t -> div (Widgets. scope (t), CSSUtil. vskip (vskip), t[:display ], className = " interact-widget" )
443
+ end
444
+ w
445
+ end
0 commit comments