Lift: How to pass data from JavaScript back to the server
What I have so far:
I'm currently working on a Lift-based project for work. Within the "Browse" section of our site, we have a list of links that cause a "Details" pane to update to display the contents of that link (and Frames are out of the question). The links are generated by
<li>{SHtml.a(() => {currentItem.set(itemID); Noop}, itemShortText)}</li>
My task is to make it seem like clicking these links changes the page without actually reloading the page. For example, you start out at /browse
, then click a link numbered 123
. I'm using History.js to change the displayed URL to browse/123
. The idea is that the URL displayed is a permalink: I use URL rewriting of the form
LiftRules开发者_如何学编程.statelessRewrite.append {
case RewriteRequest(ParsePath("browse" :: id :: Nil, _, _, _),_,_) =>
RewriteResponse("browse"::Nil, Map("id"->id))
}
so that users can bookmark the page and come back later without having to click a link from the browse page.
What's missing:
This is all well and good, but I run into trouble when using the Back and Forward buttons to navigate around the history. The URL properly displays the address that I visited, but the contents of the details area doesn't update. I have a JavaScript function that looks for an onpopstate
event:
window.onpopstate = function(event){
if(event.state){
//this triggers when you navigate back and forward, except when navigating
//back to the initial page (/browse)
//figure out the id from the event.state
alert("popped to id " + id);
//Want to pass this id back to the server somehow
} else {
//this triggers on a normal page load, or when you navigate via a link
alert("popped with 'false' state");
}
}
In the case that event.state is not false, I figure out the id of the item that the page should show. Now what I want to do is send that id back to the server somehow so that the Lift side of things can update the page accordingly. Any help would be greatly appreciated!
tl;dr - How can I pass a variable generated in JavaScript back to the Lift side of things for later use?
Another option to call server via AJAX, pass some JSON data as parameters and make server invoke your callback is to use JsonHandler class as shown in Demo Lift Web App.
Here is the source code
I use this helper method:
def ajaxLink(in: NodeSeq, clientSideQuery: JsExp, serverAction: String => JsCmd) =
<a href="javascript://" onclick={
JsRaw(ajaxCall(clientSideQuery, serverAction)._2.toJsCmd + "; return false;")
}>{ in }</a>
where clientSideQuery
can be, e.g., a function call: Call("someJSFunction")
. But I'm a Lift newbie, so feel free to leave this question open until someone more knowledgeable gives their input.
精彩评论