David, et al, i pushed my little experiments back up to github<http://github.com/leithaus/pixillion/tree/master>. Any thoughts or suggestions would be greatly appreciated.
Best wishes, --greg On Thu, Aug 20, 2009 at 11:23 AM, Meredith Gregory <[email protected] > wrote: > David, > > Thanks. i'll pop the recent changes up to github in a bit. i think it might > be easier to look at this as a whole. > > Best wishes, > > --greg > > > On Thu, Aug 20, 2009 at 11:19 AM, David Pollak < > [email protected]> wrote: > >> >> >> On Thu, Aug 20, 2009 at 11:13 AM, Meredith Gregory < >> [email protected]> wrote: >> >>> Everybody, >>> >>> Thanks for the replies. The browser source is the same as from the chat >>> example, but i've included it below. The element in which the name space is >>> not bound is the first element with the chat name space. >> >> >> Greg, >> >> This means that none of the page was processed by Lift. What URL are you >> using to get to this page? >> >> Thanks, >> >> David >> >> >>> >>> >>> Best wishes, >>> >>> --greg >>> >>> <lift:surround with="default" at="content"> >>> <div class="widget sidebar"> >>> <center><b>Group Chat</b></center><br /> >>> <lift:comet type="Chat" name="Other"> >>> <chat:body> >>> Hello <chat:name/> >>> <ul chat:id="na"> >>> <chat:list> >>> <li><list:when/> <list:who/>: <i><list:msg/></i></li> >>> </chat:list> >>> </ul> >>> </chat:body> >>> <chat:input> >>> <chat:input/> <input type="submit" value="Post It" /> >>> </chat:input> >>> </lift:comet> >>> </div> >>> <p> >>> The total chat app, including the ask/answer component for soliciting >>> a >>> name >>> comments, etc. is listed on this page. >>> There is no special code to support AJAX/Comet >>> (all the wrapping is done automatically by <i>Lift</i>). >>> </p> >>> >>> <p> >>> When the Chat comet widget is added to the page, it needs to solict >>> the >>> user for a "chat name". It asks the "AskName" comet widget for the >>> name. >>> Until the AskName comet widget provides a name, all rendering >>> messages >>> are forwarded to AskName. >>> Here's the code for the "AskName":</p> >>> >>> <style type="text/css"> >>> /* <![CDATA[ */ >>> .comment { >>> /* font-lock-comment-face */ >>> color: #b22222; >>> } >>> .comment-delimiter { >>> /* font-lock-comment-delimiter-face */ >>> color: #b22222; >>> } >>> .constant { >>> /* font-lock-constant-face */ >>> color: #5f9ea0; >>> } >>> .function-name { >>> /* font-lock-function-name-face */ >>> color: #0000ff; >>> } >>> .keyword { >>> /* font-lock-keyword-face */ >>> color: #a020f0; >>> } >>> .string { >>> /* font-lock-string-face */ >>> color: #bc8f8f; >>> } >>> .type { >>> /* font-lock-type-face */ >>> color: #228b22; >>> } >>> .variable-name { >>> /* font-lock-variable-name-face */ >>> color: #b8860b; >>> } >>> >>> /* ]]> */ >>> </style> >>> >>> <pre> >>> <span class="keyword">class</span> <span class="type">AskName</span> >>> <span class="keyword">extends</span> <span class="type">CometActor</span> { >>> <span class="keyword">def</span> <span >>> class="function-name">render</span> = >>> ajaxForm(<div>What is your username?</div> ++ >>> text(<span class="string">""</span>,name => >>> answer(name.trim)) ++ >>> <input <span class="keyword">type</span>=<span >>> class="string">"submit"</span> value=<span >>> class="string">"Enter"</span>/>) >>> } >>> </pre> >>> >>> <p> >>> When the user submits the form, the question asked by the Chat comet >>> widget >>> is answered with the value the user submitted. This is >>> similar to the ask/answer paradigm in Seaside, except that there's >>> no need for continuations. >>> </p> >>> >>> <p>Now, onto the heart of the chat app:</p> >>> >>> <pre> >>> <span class="keyword">class</span> <span class="type">Chat</span> <span >>> class="keyword">extends</span> <span class="type">CometActor</span> <span >>> class="keyword">with</span> <span class="type">CometListener</span> { >>> <span class="keyword">private</span> <span class="keyword">var</span> >>> <span class="variable-name">userName</span> = <span class="string">""</span> >>> <span class="keyword">private</span> <span class="keyword">var</span> >>> <span class="variable-name">chats</span>: <span >>> class="type">List[ChatLine]</span> = Nil >>> <span class="keyword">private</span> <span class="keyword">lazy</span> >>> <span class="keyword">val</span> <span class="variable-name">infoId</span> = >>> uniqueId + <span class="string">"_info"</span> >>> <span class="keyword">private</span> <span class="keyword">lazy</span> >>> <span class="keyword">val</span> <span class="variable-name">infoIn</span> = >>> uniqueId + <span class="string">"_in"</span> >>> <span class="keyword">private</span> <span class="keyword">lazy</span> >>> <span class="keyword">val</span> <span >>> class="variable-name">inputArea</span> = findKids(defaultXml, <span >>> class="string">"chat"</span>, <span class="string">"input"</span>) >>> <span class="keyword">private</span> <span class="keyword">lazy</span> >>> <span class="keyword">val</span> <span class="variable-name">bodyArea</span> >>> = findKids(defaultXml, <span class="string">"chat"</span>, <span >>> class="string">"body"</span>) >>> <span class="keyword">private</span> <span class="keyword">lazy</span> >>> <span class="keyword">val</span> <span >>> class="variable-name">singleLine</span> = deepFindKids(bodyArea, <span >>> class="string">"chat"</span>, <span class="string">"list"</span>) >>> >>> <span class="comment-delimiter">// </span><span class="comment">handle >>> an update to the chat lists >>> </span> <span class="comment-delimiter">// </span><span >>> class="comment">by diffing the lists and then sending a partial update >>> </span> <span class="comment-delimiter">// </span><span >>> class="comment">to the browser >>> </span> <span class="keyword">override</span> <span >>> class="keyword">def</span> <span class="function-name">lowPriority</span> = >>> { >>> <span class="keyword">case</span> <span >>> class="type">ChatServerUpdate</span>(<span >>> class="variable-name">value</span>) => >>> <span class="keyword">val</span> <span >>> class="variable-name">update</span> = (value -- chats).reverse.map(b => >>> AppendHtml(infoId, line(b))) >>> partialUpdate(update) >>> chats = value >>> } >>> >>> <span class="comment-delimiter">// </span><span class="comment">render >>> the input area by binding the >>> </span> <span class="comment-delimiter">// </span><span >>> class="comment">appropriate dynamically generated code to the >>> </span> <span class="comment-delimiter">// </span><span >>> class="comment">view supplied by the template >>> </span> <span class="keyword">override</span> <span >>> class="keyword">lazy</span> <span class="keyword">val</span> <span >>> class="variable-name">fixedRender</span>: <span >>> class="type">Box[NodeSeq]</span> = >>> ajaxForm(After(100, SetValueAndFocus(infoIn, <span >>> class="string">""</span>)), >>> bind(<span class="string">"chat"</span>, inputArea, >>> <span class="string">"input"</span> -> text(<span >>> class="string">""</span>, sendMessage _, <span class="string">"id"</span> >>> -> infoIn))) >>> >>> <span class="comment-delimiter">// </span><span class="comment">send a >>> message to the chat server >>> </span> <span class="keyword">private</span> <span >>> class="keyword">def</span> <span >>> class="function-name">sendMessage</span>(<span >>> class="variable-name">msg</span>: <span class="type">String</span>) = >>> ChatServer ! ChatServerMsg(userName, msg.trim) >>> >>> <span class="comment-delimiter">// </span><span class="comment">display >>> a line >>> </span> <span class="keyword">private</span> <span >>> class="keyword">def</span> <span class="function-name">line</span>(<span >>> class="variable-name">c</span>: <span class="type">ChatLine</span>) = >>> bind(<span class="string">"list"</span>, singleLine, >>> <span class="string">"when"</span> >>> -> hourFormat(c.when), >>> <span class="string">"who"</span> >>> -> c.user, >>> <span class="string">"msg"</span> >>> -> c.msg) >>> >>> <span class="comment-delimiter">// </span><span class="comment">display >>> a list of chats >>> </span> <span class="keyword">private</span> <span >>> class="keyword">def</span> <span >>> class="function-name">displayList</span>(<span >>> class="variable-name">in</span>: <span class="type">NodeSeq</span>): <span >>> class="type">NodeSeq </span>= chats.reverse.flatMap(line) >>> >>> <span class="comment-delimiter">// </span><span class="comment">render >>> the whole list of chats >>> </span> <span class="keyword">override</span> <span >>> class="keyword">def</span> <span class="function-name">render</span> = >>> bind(<span class="string">"chat"</span>, bodyArea, >>> <span class="string">"name"</span> -> userName, >>> AttrBindParam(<span class="string">"id"</span>, Text(infoId), >>> <span class="string">"id"</span>), >>> <span class="string">"list"</span> -> displayList _) >>> >>> <span class="comment-delimiter">// </span><span class="comment">setup >>> the component >>> </span> <span class="keyword">override</span> <span >>> class="keyword">def</span> <span class="function-name">localSetup</span> { >>> askForName >>> <span class="keyword">super</span>.localSetup >>> } >>> >>> <span class="comment-delimiter">// </span><span >>> class="comment">register as a listener >>> </span> <span class="keyword">def</span> <span >>> class="function-name">registerWith</span> = ChatServer >>> >>> <span class="comment-delimiter">// </span><span class="comment">ask for >>> the user's name >>> </span> <span class="keyword">private</span> <span >>> class="keyword">def</span> <span class="function-name">askForName</span> { >>> <span class="keyword">if</span> (userName.length == 0) { >>> ask(<span class="keyword">new</span> AskName, <span >>> class="string">"what's your username"</span>) { >>> <span class="keyword">case</span> <span >>> class="variable-name">s</span>: <span class="type">String </span><span >>> class="keyword">if</span> (s.trim.length > 2) => >>> userName = s.trim >>> reRender(<span class="constant">true</span>) >>> >>> <span class="keyword">case</span> <span >>> class="variable-name">_</span> => >>> askForName >>> reRender(<span class="constant">false</span>) >>> } >>> } >>> } >>> >>> } >>> </pre> >>> >>> <p> >>> This example demonstrates the power of Scala's Actors and >>> <i>Lift</i>. >>> With very few lines of code, we've got a complete AJAX/Comet app that >>> has Seaside style Ask/Answer for building modal dialogs. >>> </p> >>> </lift:surround> >>> >>> >>> >>> On Wed, Aug 19, 2009 at 4:58 PM, Naftoli Gugenheim <[email protected] >>> > wrote: >>> >>>> >>>> That's probably a Firefox XML error - look at view source and see what >>>> the Elem label is that's not being bound. >>>> >>>> ------------------------------------- >>>> Meredith Gregory<[email protected]> wrote: >>>> >>>> Lifted, >>>> >>>> i readily confess to being a total idiot. i'm always running into this >>>> problem of not knowing when the namespace binding is in effect. i've >>>> cribbed >>>> Chat.scala and other files from liftweb/site/example and added it whole >>>> sale >>>> to my project. When i add >>>> >>>> val entries = >>>> ( Menu(Loc("Home", List("index"), "Home")) >>>> ... >>>> :: Menu(Loc("Chat.1", List("chat"), "Chat", If(User.loggedIn_? _, "x"))) >>>> ... >>>> :: User.sitemap ) >>>> >>>> to my site menu and fire things up i get 'namespace chat undefined'. >>>> This >>>> is despite >>>> >>>> override def render = >>>> bind("chat", bodyArea, >>>> "name" -> userName, >>>> AttrBindParam("id", Text(infoId), "id"), >>>> "list" -> displayList _) >>>> >>>> being defined in the chat class. Any body have a clue for the clueless? >>>> >>>> Best wishes, >>>> >>>> --greg >>>> >>>> -- >>>> L.G. Meredith >>>> Managing Partner >>>> Biosimilarity LLC >>>> 1219 NW 83rd St >>>> Seattle, WA 98117 >>>> >>>> +1 206.650.3740 >>>> >>>> http://biosimilarity.blogspot.com >>>> >>>> >>>> >>>> >>>> >>> >>> >>> -- >>> L.G. Meredith >>> Managing Partner >>> Biosimilarity LLC >>> 1219 NW 83rd St >>> Seattle, WA 98117 >>> >>> +1 206.650.3740 >>> >>> http://biosimilarity.blogspot.com >>> >>> >>> >> >> >> -- >> Lift, the simply functional web framework http://liftweb.net >> Beginning Scala http://www.apress.com/book/view/1430219890 >> Follow me: http://twitter.com/dpp >> Git some: http://github.com/dpp >> >> >> >> > > > -- > L.G. Meredith > Managing Partner > Biosimilarity LLC > 1219 NW 83rd St > Seattle, WA 98117 > > +1 206.650.3740 > > http://biosimilarity.blogspot.com > -- L.G. Meredith Managing Partner Biosimilarity LLC 1219 NW 83rd St Seattle, WA 98117 +1 206.650.3740 http://biosimilarity.blogspot.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~----------~----~----~----~------~----~------~--~---
