better input element handling
This commit is contained in:
parent
8e777a0c19
commit
ea7eee7564
2 changed files with 48 additions and 8 deletions
|
|
@ -54,9 +54,11 @@ template nativeValue(ev): cstring = cast[Element](ev.target).value
|
||||||
template setNativeValue(ev, val) = cast[Element](ev.target).value = val
|
template setNativeValue(ev, val) = cast[Element](ev.target).value = val
|
||||||
|
|
||||||
template keyeventBody() =
|
template keyeventBody() =
|
||||||
n.value = nativeValue(ev)
|
let v = nativeValue(ev)
|
||||||
|
n.value = v
|
||||||
action(ev, n)
|
action(ev, n)
|
||||||
setNativeValue(ev, n.value)
|
if n.value != v:
|
||||||
|
setNativeValue(ev, n.value)
|
||||||
# Do not call redraw() here! That is already done
|
# Do not call redraw() here! That is already done
|
||||||
# by ``karax.addEventHandler``.
|
# by ``karax.addEventHandler``.
|
||||||
|
|
||||||
|
|
@ -276,12 +278,13 @@ proc diff(newNode, oldNode: VNode; parent, current: Node; kxi: KaraxInstance): E
|
||||||
case result
|
case result
|
||||||
of identical, similar:
|
of identical, similar:
|
||||||
newNode.dom = oldNode.dom
|
newNode.dom = oldNode.dom
|
||||||
assert oldNode.dom != nil
|
|
||||||
if result == similar: updateStyles(newNode, oldNode)
|
if result == similar: updateStyles(newNode, oldNode)
|
||||||
if newNode.events.len != 0 or oldNode.events.len != 0:
|
if newNode.events.len != 0 or oldNode.events.len != 0:
|
||||||
mergeEvents(newNode, oldNode, kxi)
|
mergeEvents(newNode, oldNode, kxi)
|
||||||
#if newNode.kind == VNodeKind.input or newNode.kind == VNodeKind.textarea:
|
if oldNode.kind == VNodeKind.input or oldNode.kind == VNodeKind.textarea:
|
||||||
# oldNode.dom.value = newNode.text
|
if oldNode.text != newNode.text:
|
||||||
|
oldNode.text = newNode.text
|
||||||
|
oldNode.dom.value = newNode.text
|
||||||
|
|
||||||
let newLength = newNode.len
|
let newLength = newNode.len
|
||||||
let oldLength = oldNode.len
|
let oldLength = oldNode.len
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import vdom, kdom, vstyles, karax, karaxdsl, jdict, jstrutils
|
||||||
type TextInput* = ref object of VComponent
|
type TextInput* = ref object of VComponent
|
||||||
value: cstring
|
value: cstring
|
||||||
isActive: bool
|
isActive: bool
|
||||||
|
onchange: proc (value: cstring)
|
||||||
|
|
||||||
proc render(x: VComponent): VNode =
|
proc render(x: VComponent): VNode =
|
||||||
let self = TextInput(x)
|
let self = TextInput(x)
|
||||||
|
|
@ -38,15 +39,23 @@ proc render(x: VComponent): VNode =
|
||||||
markDirty(self)
|
markDirty(self)
|
||||||
|
|
||||||
proc onchanged(ev: Event; n: VNode) =
|
proc onchanged(ev: Event; n: VNode) =
|
||||||
kout cstring"onchanged", n.value
|
if self.onchange != nil and self.value != n.value:
|
||||||
|
self.onchange n.value
|
||||||
|
self.value = n.value
|
||||||
|
|
||||||
result = buildHtml(tdiv(style=style)):
|
result = buildHtml(tdiv(style=style)):
|
||||||
input(style=inputStyle, value=self.value, onblur=flip, onfocus=flip, onkeyup=onchanged)
|
input(style=inputStyle, value=self.value, onblur=flip, onfocus=flip, onkeyup=onchanged)
|
||||||
|
|
||||||
proc newTextInput*(style: VStyle = VStyle(); value: cstring = cstring""): TextInput =
|
proc setValue(x: TextInput; value: cstring) =
|
||||||
|
x.value = value
|
||||||
|
markDirty(x)
|
||||||
|
|
||||||
|
proc newTextInput*(style: VStyle = VStyle(); value: cstring = cstring"",
|
||||||
|
onchange: proc(v: cstring) = nil): TextInput =
|
||||||
result = newComponent(TextInput, render)
|
result = newComponent(TextInput, render)
|
||||||
result.style = style
|
result.style = style
|
||||||
result.value = value
|
result.value = value
|
||||||
|
result.onchange = onchange
|
||||||
|
|
||||||
type
|
type
|
||||||
Combined = ref object of VComponent
|
Combined = ref object of VComponent
|
||||||
|
|
@ -76,8 +85,36 @@ proc newCombined*(style: VStyle = VStyle()): Combined =
|
||||||
result.a = newTextInput(style, "AAA")
|
result.a = newTextInput(style, "AAA")
|
||||||
result.b = newTextInput(style, "BBB")
|
result.b = newTextInput(style, "BBB")
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
persons: seq[cstring] = @[cstring"Karax", "Abathur", "Fenix"]
|
||||||
|
selected = -1
|
||||||
|
errmsg = cstring""
|
||||||
|
ti = newTextInput(VStyle(), "", proc (v: cstring) =
|
||||||
|
if v.len > 0:
|
||||||
|
if selected >= 0: persons[selected] = v
|
||||||
|
errmsg = ""
|
||||||
|
else:
|
||||||
|
errmsg = "name must not be empty"
|
||||||
|
)
|
||||||
|
|
||||||
|
proc renderPerson(text: cstring, index: int): VNode =
|
||||||
|
proc select(ev: Event, n: VNode) =
|
||||||
|
selected = index
|
||||||
|
ti.setValue(persons[selected])
|
||||||
|
|
||||||
|
result = buildHtml():
|
||||||
|
tdiv(onClick=select):
|
||||||
|
text text
|
||||||
|
|
||||||
proc createDom(): VNode =
|
proc createDom(): VNode =
|
||||||
result = buildHtml(tdiv):
|
result = buildHtml(tdiv):
|
||||||
newCombined()
|
tdiv:
|
||||||
|
for index, text in persons.pairs:
|
||||||
|
renderPerson(text, index)
|
||||||
|
tdiv:
|
||||||
|
ti
|
||||||
|
tdiv:
|
||||||
|
text errmsg
|
||||||
|
|
||||||
setRenderer createDom
|
setRenderer createDom
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue