improved focus handling for todoapp example

This commit is contained in:
Andreas Rumpf 2017-04-05 10:04:02 +02:00
commit 11e4f355e7
3 changed files with 26 additions and 26 deletions

View file

@ -26,6 +26,10 @@ type
var
document* {.importc.}: Document
toFocus: Element
toFocusV: VNode
proc setFocus*(n: VNode) =
toFocusV = n
proc vnodeToDom(n: VNode): Element =
if n.kind == VNodeKind.text:
@ -52,7 +56,7 @@ proc vnodeToDom(n: VNode): Element =
assert myn != nil
hh(ev, myn)
result.addEventListener(toEventName[e], wrapper())
if n.kind == VNodeKind.input and toFocus.isNil:
if n == toFocusV and toFocus.isNil:
toFocus = result
proc same(n: VNode, e: Element): bool =
@ -91,8 +95,8 @@ proc replaceById(id: cstring; newTree: Node) =
proc equals(a, b: VNode): bool =
if a.kind != b.kind: return false
if a.id != b.id: return false
#if a.kind == VNodeKind.text:
if a.text != b.text: return false
if a.kind == VNodeKind.text:
if a.text != b.text: return false
if not sameAttrs(a, b): return false
if a.class != b.class: return false
# XXX test event listeners here?
@ -316,17 +320,19 @@ proc getAttr(e: Element; key: cstring): cstring {.
template nativeValue(ev): cstring = cast[Element](ev.target).value
template setNativeValue(ev, val) = cast[Element](ev.target).value = val
proc realtimeInput*(val: cstring; changed: EventHandler): VNode =
template keyeventBody() =
n.value = nativeValue(ev)
action(ev, n)
setNativeValue(ev, n.value)
redraw()
proc realtimeInput*(val: cstring; action: EventHandler): VNode =
#let oldElem = getElementById(id)
#if oldElem != nil: return oldElem
#let newVal = if oldElem.isNil: val else: $oldElem.value
var timer: Timeout
proc onkeyup(ev: Event; n: VNode) =
proc wrapper() =
n.value = nativeValue(ev)
changed(ev, n)
setNativeValue(ev, n.value)
redraw()
proc wrapper() = keyeventBody()
if timer != nil: clearTimeout(timer)
timer = setTimeout(wrapper, 400)
@ -334,29 +340,21 @@ proc realtimeInput*(val: cstring; changed: EventHandler): VNode =
result.value = val
result.addEventListener(EventKind.onkeyup, onkeyup)
proc enterInput*(id, val: cstring; onenter: EventHandler): VNode =
proc enterInput*(id, val: cstring; action: EventHandler): VNode =
#let oldElem = getElementById(id)
#if oldElem != nil: return oldElem
#let newVal = if oldElem.isNil: val else: $oldElem.value
proc onkeyup(ev: Event; n: VNode) =
if ev.keyCode == 13:
n.value = nativeValue(ev)
onenter(ev, n)
setNativeValue(ev, n.value)
redraw()
if ev.keyCode == 13: keyeventBody()
result = tree(VNodeKind.input, [(cstring"type", cstring"text")])
result.id = id
result.value = val
result.addEventListener(EventKind.onkeyup, onkeyup)
proc setOnEnter*(n: VNode; onenter: EventHandler) =
proc setOnEnter*(n: VNode; action: EventHandler) =
proc onkeyup(ev: Event; n: VNode) =
if ev.keyCode == 13:
n.value = nativeValue(ev)
onenter(ev, n)
setNativeValue(ev, n.value)
redraw()
if ev.keyCode == 13: keyeventBody()
n.addEventListener(EventKind.onkeyup, onkeyup)
proc ajax(meth, url: cstring; headers: openarray[(cstring, cstring)];

View file

@ -3,7 +3,7 @@ import macros, karax, vdom
from strutils import startsWith, toLowerAscii
const
StmtContext = ["kout", "inc", "echo", "dec"]
StmtContext = ["kout", "inc", "echo", "dec", "!"]
proc getName(n: NimNode): string =
case n.kind
@ -76,16 +76,18 @@ proc tcall2(n, tmpContext: NimNode): NimNode =
result.add newDotAsgn(tmp, key, x[1])
else:
result.add newCall(bindSym"setAttr", tmp, newLit(key), x[1])
elif x.kind == nnkIdent:
result.add newCall(x, tmp)
else:
result.add tcall2(x, tmp)
#if tag == "link":
# result.add newCall(bindSym"setAttr", tmp, newLit"href", newLit"#")
if tmpContext == nil:
result.add tmp
else:
result.add newCall(bindSym"add", tmpContext, tmp)
elif tmpContext != nil and op notin StmtContext:
result = newCall(bindSym"add", tmpContext, n)
elif op == "!" and n.len == 2:
result = n[1]
else:
result = n
else:

View file

@ -63,7 +63,7 @@ proc createEntry(id: int; d: cstring; completed, selected: bool): VNode =
else:
input(class = "edit", name = "title", id = "todo-edit:" & &id,
onfocusLost = focusLost,
onenter = editEntry, value = d)
onenter = editEntry, value = d, setFocus)
proc createDom(): VNode =
result = buildHtml(tdiv(class="todomvc-wrapper")):
@ -72,7 +72,7 @@ proc createDom(): VNode =
h1:
text "todos"
input(class = "new-todo", placeholder="What needs to be done?", name = "newTodo",
onenter = onTodoEnter)
onenter = onTodoEnter, setFocus)
section(class = "main"):
input(class = "toggle-all", `type` = "checkbox", name = "toggle")
label(`for` = "toggle-all", onclick = onAllDone):