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.
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
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---