Scala.js event handling -
i'm writing little scala.js app uses 2 event handlers: 1 input field's onkeyup
event , button's onclick
event.
the 2 event handlers share quite bit of common coding, try optimise event handler coding single function returns event handler function, compiles correctly, events no longer trapped in browser.
in following code in function main
, event handler btn.onclick
works fine, event handler citynameinput.onkeyup
no longer works. did copy coding assigned directly event handler, , put in function called keystrokehandler
returns function1[dom.event, _]
. compiles ok, onkeyup
event no longer trapped in browser.
def keystrokehandler(userinput: string, responsediv: dom.element): function1[dom.event,_] = (e: dom.event) => { // city name must @ least 4 characters long if (userinput.length > 3) { responsediv.innerhtml = "" val xhr = buildxhrrequest(userinput, searchendpoint) xhr.onload = (e: dom.event) => { val data: js.dynamic = js.json.parse(xhr.responsetext) // can cities found? if (data.count == 0) // nope, show error message responsediv.appendchild(p(s"cannot find city names starting ${userinput}").render) else { // build list of weather reports buildsearchlist(data, responsediv) } } // send xhr request openweather xhr.send() } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // main program // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @jsexport def main(container: dom.html.div): unit = { container.innerhtml = "" val citynameinput = input.render val btn = button.render val weatherdiv = div.render citynameinput.defaultvalue = owmqueryparams.get("q").get btn.textcontent = "go" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // button onclick event handler // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - btn.onclick = (e: dom.event) => { if (citynameinput.value.length > 3) { weatherdiv.innerhtml = "" val xhr = buildxhrrequest(citynameinput.value, weatherendpoint) xhr.onload = (e: dom.event) => { val data = js.json.parse(xhr.responsetext) // can city found? if (data.cod == "404") // nope, show error message weatherdiv.appendchild(p(s"city ${citynameinput.value} not found").render) else { // first add div containing both weather information // , empty div hold slippy map. // needed because leaflet writes map information // existing dom element val report = new weatherreportbuilder(data) weatherdiv.appendchild(buildweatherreport(report, 0)) buildslippymap("mapdiv0", report) } } // send xhr request openweather xhr.send() } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // input field onkeyup event handler // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - citynameinput.onkeyup = keystrokehandler(citynameinput.value, weatherdiv) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // write html screen // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - container.appendchild( div( h1("weather report"), table( tr(td("enter city name (min 4 characters)"), td(citynameinput)), tr(td(), td(style := "text-align: right", btn)) ), weatherdiv ).render ) }
what's problem here?
should keystrokehandler
function return special scala.js event handler type? or else?
thanks
chris w
i think problem here:
citynameinput.onkeyup = keystrokehandler(citynameinput.value, weatherdiv)
the event handler is triggered, userinput
frozen citynameinput.value
at time handler created, instead of varying current value of citynameinput.value
. indeed, line equivalent to
val userinput = citynameinput.value citynameinput.onkeyup = keystrokehandler(userinput, weatherdiv)
which makes obvious citynameinput.value
evaluated once.
instead, should give citynameinput
parameter keystrokehandler
, , access citynameinput.value
inside anonymous function, evaluated every time function (handler) called.
Comments
Post a Comment