I have a trait called TabbedSnippet (needs a better name..) which snippets which need to respond to "hashChanged"-events extend, which looks like this:
trait TabbedSnippet {
final val pairRegex = "([^?=&]+)(=([^&]*))?".r
final val tabContainerId = nextFuncName
val uri = S.uri
def hashParams: Map[String, String]
def hashParams_=(newVal: Map[String, String])
def setDefaultHashIfMissing(): JsCmd = {
val hash = TabbedSnippet.hashParamsToUri(hashParams)
JsIf(JsRaw("Object.isUndefined(window.location.hash) || window.location.hash.length == 0"),
SetExp(JsVar("window.location.hash"), Str("#" + hash))
)
}
def handleHashChangeEvent(hashValue: String): JsCmd = {
val fisk = pairRegex.findAllIn(hashValue)
if (fisk.hasNext) {
hashParams = fisk.map(v => v.split("=")).map(pair => URLDecoder.decode(pair(0), "UTF-8") -> URLDecoder.decode(pair(1), "UTF-8")).toMap
processHashChanged()
} else {
Noop
}
}
def processHashChanged(): JsCmd
}
Here's the OnEvent and OnHashChange classes:
case class OnEvent(query: JsExp, event: String, func: AnonFunc) extends JsCmd {
override val toJsCmd = (Jq(query) ~> new JsMember {
override val toJsCmd = "on(" + event.encJs + ", " + func.toJsCmd + ")"
}).cmd.toJsCmd
}
case class OnHashChange(func: String => JsCmd) extends JsCmd {
override val toJsCmd = OnEvent(JsRaw("window"), "hashchange",
AnonFunc("eventObj",
Call("ORIGO.Util.hashChanged", JsVar("eventObj"), AnonFunc("hashValue", SHtml.ajaxCall(JsVar("hashValue"), func))))
).toJsCmd
}
Use like this from a snippet:
".tabChangeHook" #> Script(OnHashChange(handleHashChangeEvent) & // Install the eventhandler
OnLoad(setDefaultHashIfMissing()))
override def processHashChanged(): JsCmd = {
hashParams.get("tab") match {
case Some(CalendarViewTab(tab)) => processTab(tab)
case e => Alert("Invalid tab-value: " + e)
}
}
Here's the hashChanged JS-function:
hashChanged: function(eventObj, func) {
if (Object.isString(location.hash) && location.hash.indexOf("#") != -1 && Object.isFunction(func)) {
func(location.hash.substr(location.hash.indexOf("#") + 1));
}
}
Hope this helps.