David, Thanks a bunch. Your solution is one I was trying to implement but wasn't quite sure how until you showed me that I can create an AnonFunc using Shtml.ajaxCall. It certainly does simplify things.
One of the issues that stymied me - and still does, frankly - is how the ajaxCall wraps the edit function with the correct parameter for the callback to work. I updated the code in http://github.com/glennSilverman/treeview and refactored it into a MetaMegaTreeItem trait to easily add these features to any Mapper object. Maybe some Lift committer might find the ideas involved here usefull enough to include something similar in a future release of Lift. Glenn . On Nov 24, 5:53 pm, David Pollak <feeder.of.the.be...@gmail.com> wrote: > Glenn, > > The issue is that you were creating call-back functions during an API call > (rather than as part of Lift's HTML/Ajax/Comet pipeline). > > In general, I think this is very bad design. I'd strongly recommend using > the Ajax/Json call facilities built into Lift. You get a pile of things for > free including securing calls (you don't need to keep a lot of state > client-side). > > So, your code looks like: > > def buildTree(in:NodeSeq):NodeSeq = { > val func = AnonFunc( SHtml.ajaxCall(JsRaw("this.id"), (id: String) => > SetHtml("role_edit", Role.find(id).map(edit) openOr > NodeSeq.Empty))._2 ) > > TreeView("tree", JsObj(("persist", "location"), ("toggle", func)), > loadTree, loadNode) > } > > Also, you might want to look at S.hostAndPort for calculating the current > server. Also, think about using the map() call rather than pattern matching > on Full/_. > > Also, there's no need to register API calls in SiteMap > > I'll update your app and push code tohttp://github.com/dpp/treeview > > Thanks, > > David > > > > On Tue, Nov 24, 2009 at 8:02 AM, glenn <gl...@exmbly.com> wrote: > > David, > > > The statement that all functions are bound to the current state in the > > scope that the function > > was created may be true for functions submitted via SHtml, but doesn't > > seem to hold true > > for those from LiftResponse, otherwise, the edit function in my > > example would work for editing, > > just as it does for creating. > > > In any case, I'm still at a loss on how to fix this. > > > Glenn > > > On Nov 20, 5:40 pm, glenn <gl...@exmbly.com> wrote: > > > David, > > > > I was able to put together a simplified application to demo the > > > problem. > > > It's just a basic lift archetype with a Role.scala added to the mapper > > > package that > > > contains all the relevant code. > > > > Here is the link to the application: > > > >http://github.com/glennSilverman/treeview > > > > If you run it as-is, you can add new roles to the db but you can't > > > edit them. > > > > Glenn > > > > On Nov 20, 10:28 am, David Pollak <feeder.of.the.be...@gmail.com> > > > wrote: > > > > > On Fri, Nov 20, 2009 at 10:14 AM, glenn <gl...@exmbly.com> wrote: > > > > > David, > > > > > > That's what I thought. All I needed to do was create the > > Mapper.toForm > > > > > like so: > > > > > > item.toForm(Full("Save"), { _.save }) > > > > > > and the item would be saved on submit. But it doesn't work in my > > case. > > > > > Please put together a complete runnable example of it not working for > > you > > > > and we'll debug it. > > > > > > Glenn > > > > > > On Nov 20, 10:05 am, David Pollak <feeder.of.the.be...@gmail.com> > > > > > wrote: > > > > > > Glenn, > > > > > > > All functions are bound to the current state in the scope that the > > > > > function > > > > > > was created. There's no need to do weird RequestVar things with > > Hidden > > > > > > fields or anything else. If you've got a function passed to > > SHtml.text, > > > > > > submit, etc. that function closes over its local scope: it captures > > all > > > > > the > > > > > > variables it refers to. > > > > > > > So: > > > > > > > def mySnippet = { > > > > > > val myInstance = MyTable.find(whatever) > > > > > > > SHtml.ajaxCheckbox(..., bool => {myInstance.boolField(bool).save; > > > > > Noop}) > > > > > > > } > > > > > > > In the above code, you've captured the instance in the val > > myInstance... > > > > > > that's kept around for the lifespan of the function that you passed > > to > > > > > > ajaxCheckbox. > > > > > > > Thanks, > > > > > > > David > > > > > > > On Fri, Nov 20, 2009 at 9:45 AM, glenn <gl...@exmbly.com> wrote: > > > > > > > I've been following this thread as lately I'm having difficulty > > with > > > > > > > an ajax-submitted > > > > > > > request in my app. Here's the scenario (There's no simple way to > > > > > > > describe this, so bear with me): > > > > > > > > I create a JQuery tree of my data (Mapper object with just an > > item > > > > > > > name and a parent Mapper object as it's fields) as follows: > > > > > > > > def buildTree(in:NodeSeq):NodeSeq = { > > > > > > > > object MyJqLoad { > > > > > > > def apply(content: JsExp) = new JsExp with JQueryRight with > > > > > > > JQueryLeft { > > > > > > > def toJsCmd = JqId("json_result").toJsCmd + ".load(" + > > > > > > > content.toJsCmd + JsRaw("""+this.id""") + ")" > > > > > > > } > > > > > > > } > > > > > > > > val host = "http://" + S.hostName > > > > > > > val link = host + ":8080" + S.contextPath + "/api/json/" + > > > > > > > dbTableName.toLowerCase + "/" > > > > > > > > val func = AnonFunc( MyJqLoad(link)) > > > > > > > > TreeView("tree", JsObj(("persist", "location"), ("toggle", > > func)), > > > > > > > loadTree, loadNode) > > > > > > > } > > > > > > > > The functions, loadTree and loadNode, are used to asynchronously > > > > > > > build the tree of item names from the Mapper instances. > > > > > > > The link val creates a URL, for example, > > > > >http://localhost:8080/api/json/ > > > > > > > <dbTableName>/, > > > > > > > where dbTableName is just the Mapper object name. > > > > > > > > On the client, the user clicks on a tree item, which, as you can > > see > > > > > > > from the above code, submits the Mapper id selected to the > > server, > > > > > > > which then > > > > > > > pulls the Mapper.toForm html from the Mapper instance and returns > > it > > > > > > > to the client at <div id="json_result"/>, which is in my > > template. > > > > > > > This all works great. > > > > > > > > Where this all breaks down, is in submitting the returned > > > > > > > Mapper.toForm back to the server when I click on the "Save" > > button, > > > > > > > because no Mapper instance > > > > > > > exists at that point in the request or session for the save > > button to > > > > > > > act on. > > > > > > > > Somewhere, I'm thinking I have to modify the Mapper.toForm html > > so the > > > > > > > submit button runs another JavaScript function on the client to > > return > > > > > > > the Mapper id > > > > > > > to the server for processing. But I haven't yet been able to do > > this. > > > > > > > One of the problems is that I don't even have an id on the client > > > > > > > (none is returned with Mapper.toForm > > > > > > > html) to work with. And, it seems to me that to make this > > scenario > > > > > > > work, I'm forced to become a JavaScript guru and work outside of > > Lift. > > > > > > > In other words, if there isn't > > > > > > > a mechanism in Lift to handle this situation directly, there > > should > > > > > > > be. > > > > > > > > One of the things I've tried is to add a hidden form field to the > > > > > > > Mapper.toForm html, > > > > > > > > SHtml.hidden(() => itemIdVar(id.toString)), > > > > > > > > where itemIdVar extends RequestVar[String]. > > > > > > > > But I couldn't make that work either. The hidden form field is > > suppose > > > > > > > to run the ()=Any function, and it may do that, but not in the > > correct > > > > > > > sequence to do any good > > > > > > > when the form is submitted. > > > > > > > > Glenn > > > > > > > > On Nov 19, 11:35 pm, Jeppe Nejsum Madsen <je...@ingolfs.dk> > > wrote: > > > > > > > > Chris Lewis <burningodzi...@gmail.com> writes: > > > > > > > > > Thanks for the feedback Jeppe. I can't completely infer the > > context > > > > > of > > > > > > > > > your example, > > > > > > > > > Seems to happen a lot to me lately. :-) This was just a quick > > paste > > > > > from > > > > > > > > our codebase.... > > > > > > > > > > but I get the idea (and I hadn't known about TemplateFinder). > > > > > Here's > > > > > > > > > what I've hacked together so far. > > > > > > > > > /Jeppe > > > > > > > > -- > > > > > > > > You received this message because you are subscribed to the > > Google > > > > > Groups > > > > > > > "Lift" group. > > > > > > > To post to this group, send email to lift...@googlegroups.com. > > > > > > > To unsubscribe from this group, send email to > > > > > > > liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com> > > <liftweb%2bunsubscr...@googlegroups.com<liftweb%252bunsubscr...@googlegroups.com> > > > > > > <liftweb%2bunsubscr...@googlegroups.com<liftweb%252bunsubscr...@googlegroups.com> > > <liftweb%252bunsubscr...@googlegroups.com<liftweb%25252bunsubscr...@googlegroups.com> > > > > > > > > . > > > > > > > For more options, visit this group at > > > > > > >http://groups.google.com/group/liftweb?hl=. > > > > > > > -- > > > > > > Lift, the simply functional web frameworkhttp://liftweb.net > > > > > > Beginning Scalahttp://www.apress.com/book/view/1430219890 > > > > > > Follow me:http://twitter.com/dpp > > > > > > Surf the harmonics > > > > > > -- > > > > > > You received this message because you are subscribed to the Google > > Groups > > > > > "Lift" group. > > > > > To post to this group, send email to lift...@googlegroups.com. > > > > > To unsubscribe from this group, send email to > > > > > liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com> > > <liftweb%2bunsubscr...@googlegroups.com<liftweb%252bunsubscr...@googlegroups.com> > > > > > > . > > > > > For more options, visit this group at > > > > >http://groups.google.com/group/liftweb?hl=. > > > > > -- > > > > Lift, the simply functional web frameworkhttp://liftweb.net > > > > Beginning Scalahttp://www.apress.com/book/view/1430219890 > > > > Follow me:http://twitter.com/dpp > > > > Surf the harmonics > > > -- > > > You received this message because you are subscribed to the Google Groups > > "Lift" group. > > To post to this group, send email to lift...@googlegroups.com. > > To unsubscribe from this group, send email to > > liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com> > > . > > For more options, visit this group at > >http://groups.google.com/group/liftweb?hl=en. > > -- > Lift, the simply functional web frameworkhttp://liftweb.net > Beginning Scala ... > > read more » -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.