I have some Scala.js code which works fine when the target-browser is Chrome but not when it is Firefox. I have been told that I should not use srcElement
but instead target
. However I can't work out how to access target
.
private def TD(locId: Location, personId: Person): HTMLTableCellElement = {
val res = td(style := myPeopleTable_td).render
res.onclick = { (e: dom.Event) => c.clickTD(e.srcElement)}
res.id = Id(locId, personId).toString
cells += (Id(locId, personId) -> res)
res
}
def clickTD(element: Element): Unit = {
val idOption = Id.parse(element.id)
idOption.foreach(id => {
locIdx = Location.indexOf(id.locId)
personIdx = Person.indexOf(id.personId)
localSync()
v.personValueBox.focus()
})
}
By way of explanation c
is the Controller and v
is the View. The first method is in the View and and second is in the Controller. The first method is setting up a cell in an HTML table, including what happens when the user clicks on the cell. In clickTD()
the code needs to know what has been clicked - it needs to somehow get at the HTML element's 'id' which has been pre-set so that model objects can be looked up.
If I try to replace e.srcElement
with e.target
this is the result:
[info] Compiling 1 Scala source to C:\dev\v2\atmosphere\js\target\scala2.11\classes...
[error] C:\dev\v2\atmosphere\js\src\main\scala\simple\View.scala:145: type mismatch;
[error] found : org.scalajs.dom.raw.EventTarget
[error] required: org.scalajs.dom.Element
[error] (which expands to) org.scalajs.dom.raw.Element
[error] res.onclick = { (e: dom.Event) => c.clickTD(e.target)}
[error] ^
[error] one error found
[error] (atmosphereJS/compile:compile) Compilation failed
[error] Total time: 1 s, completed 15-Jun-2015 02:14:41
Thanks @ochrons, your suggestion of putting res
instead of e.target
works. Unfortunately with the other controls I'm having an 'order of instantiation' problem. In the following I am trying to move the commented-out line to where it can see res
:
private def button_TD_Tog(idT: Row): HTMLTableCellElement = {
val idsStr: String = idT.toString
val buttonWidget = button(
style := myToggleButton,
name := "button",
id := idsStr
//onclick := { (e: dom.Event) => c.clickToggleButton(e.srcElement)}
)
val res = td(style := myToggleButtonCol, buttonWidget).render
buttonWidget.onclick = { (e: dom.Event) => c.clickToggleButton(res)}
res.id = idsStr
buttonTDs += (idT -> res)
res
}
I (think I) need both res
and buttonWidget
to exist before assigning to onclick, but the compiler does not recognize onclick. I found myself searching for some API documentation to help me out here. I doubt that it exists (I've found Scala.js documentation to be excellent, but not comprehensive). Perhaps I should be looking to the DOM itself...
And so now to an example of a simple general solution that seems to work for all cases, as per your advice to force types:
c.clickPushButton(e.target.asInstanceOf[dom.Element])}