Re: [Lift] Signup validation

2010-02-25 Thread Adam Warski
Hello,

ticket created: http://www.assembla.com/spaces/liftweb/tickets/368

On Feb 24, 2010, at 6:28 PM, David Pollak wrote:

 
 
 On Wed, Feb 24, 2010 at 7:33 AM, Adam Warski a...@warski.org wrote:
 Hello,
 
 I'm integrating recaptcha into a Lift app that uses MegaProtoUser, and 
 there's one small thing that I think can be improved.
 
 There is currently no good place to put the captcha-verifying code. After the 
 signup form is submitted the user if validated using theUser.validate 
 (ProtoUser.scala:386, testSignup method). However I can't put captcha 
 validation into User.validate, as there won't be any captcha when e.g. 
 editing a user.
 
 So I would propose adding a method to MetaMegaProtoUser, e.g.:
 
 protected def validateSignup(user: User) = user.validate
 
 which could be then overridden in concrete user classes.
 
 Sounds like a great addition.  Please open a ticket on it.  I'll get to it 
 tomorrow (unless someone beats me to the punch.)
  
 
 --
 Adam Warski
 http://www.warski.org
 http://www.softwaremill.eu
 
 
 
 
 --
 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.
 
 
 
 
 -- 
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://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.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] Signup validation

2010-02-24 Thread Adam Warski
Hello,

I'm integrating recaptcha into a Lift app that uses MegaProtoUser, and there's 
one small thing that I think can be improved.

There is currently no good place to put the captcha-verifying code. After the 
signup form is submitted the user if validated using theUser.validate 
(ProtoUser.scala:386, testSignup method). However I can't put captcha 
validation into User.validate, as there won't be any captcha when e.g. editing 
a user.

So I would propose adding a method to MetaMegaProtoUser, e.g.:

protected def validateSignup(user: User) = user.validate

which could be then overridden in concrete user classes.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Signup validation

2010-02-24 Thread Adam Warski
Hello,

 Can't you just override actionAfterSignup and don't call super if
 captcha check fails?


But that already assumes that signup was successfull and in the end redirects 
to the homepage instead of going back to the singup form.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Can I test Lift 2.0-M2 with Scala 2.0 Beta 1 now?

2010-02-16 Thread Adam Warski
Hello,

 Question  - Can I test Lift 2.0-M2 with Scala 2.0 Beta 1 now?

you need to use code from the 280_port_refresh branch 
(http://github.com/dpp/liftweb).
The milestones are for 2.7.7 still.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Comet shutdown?

2010-02-10 Thread Adam Warski
Hello,

 Yes, in fact there is a timespan method in CometActor.  You should be using 
 Lift 2.0-M1 or 2.0-SNAPSHOT.

I'm using 2.0-SNAPSHOT:

class Test extends CometActor {
  def render = NodeSeq.Empty
  override def timespan = 0
}

error: method timespan overrides nothing
  override def timespan = 0
   ^
one error found

same for timeSpan.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Snippet with no reflection an no massive case statement

2010-02-10 Thread Adam Warski
 
 All i would like is some clarification if this statement is in fact true, if 
 not i will go on with my project happily using reflection snippets. If it is 
 true i then would be looking for a better alternative.
 
 It is much better practice in my opinion to use an explicit dispatch.  But 
 you do whatever you want.  If it becomes a performance problem for you and 
 you're on a production site, then we'll look at it.
 
 More broadly, we like to help newbies and folks with live production sites.  
 But, we also expect that newbies will bring us real issues that they 
 themselves are facing, not premature optimizations.  We have limited time to 
 help people and wasting (and this thread has crossed seriously into 
 time-wasting land) time with stuff that doesn't really impact you means that 
 (1) you will get a lot less attention in the future (think the boy who cried 
 wolf) and (2) it lowers the quality of discussion for the rest of the folks 
 on the list.

I really don't get your response, as Hugo just asked about a statement on the 
wikipage, which very clearly says that using reflection snippets brings a 
performance hit and is discouraged to be used in production. Now, it may very 
well be that this statement shouldn't be there as it's not true - which is your 
opinion I think.

Maybe it would be better to write something like:
If you are experiencing performance problems because of too many reflection 
calls, the cause may be using reflection snippets. Consider using dispatch 
snippets.

But why do you say to new users who just ask about statements from the wiki 
that their posts are time-wasting and that they can get less attention in the 
future I really don't understand.

Peace :)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Deploying Lift app

2010-02-10 Thread Adam Warski
 I can't quite figure out how to deploy my lift app and was hoping one
 of you could point me in the right direction. For  fun i uploaded my
 entire project (uncompiled) to the server and ran mvn jetty:run - this
 worked fine but as soon as i killed my ssh connection the jetty server
 stopped.

I think it should be enough to run mvn jetty:run in the background.

My start-server.sh script:

#!/bin/bash
mvn jetty:run log.out 21 

(puts all logs in log.out for further inspection)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Snippet with no reflection an no massive case statement

2010-02-10 Thread Adam Warski

 Please read the entire thread and the other threads that Hugo has started.  
 Hugo is pushing on this issue (without any real basis, measurement, problems, 
 statistics) and not letting it go.  I've answered his question a number of 
 times (using dispatch snippets is best practices [more from a code 
 readability standpoint, but also there is a minor performance penalty]) and 
 he keeps harping on the issue.

I think that the statement on the wiki may sound too authoritative and that may 
be the source of misunderstanding - I'll edit the wiki to clear this up. I 
remember I've also wondered about this sentence when I was starting to get to 
know lift.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Comet shutdown?

2010-02-10 Thread Adam Warski
 As mentioned earlier, please try *lifespan* instead.
 
 def lifespan: Box[TimeSpan] is what you probably want.

Ah :D I thought you were correcting the type parameter in David's email, didn't 
notice the function name.

Thanks a lot! :)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Error messages are not displayed - 2.0-M1

2010-02-08 Thread Adam Warski
Hello,

 If you are using an Ajax form lift:msgs showAll=true/ did not show
 the messages associated with ID's ... messages coming from FieldError.
 This is a defect I fixed about a week ago. Please use the latest lift
 build.


Ah, I didn't realize that this ticket got closed.
Anyway, I checked with snapshot and it works.

Thanks Marius :)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Error messages are not displayed - 2.0-M1

2010-02-06 Thread Adam Warski
Hello,

are you submitting the form with ajax?
If so, see this thread:

http://groups.google.com/group/liftweb/browse_thread/thread/e25d86a24a5266a2/9fdcf9f2ce022618

In short, check if doing:

xs.map {i = S.error(i.msg) }; 

instead of:

S.error(xs); 

works.

 Hi Jeppe,
 lift:Msgs showAll=true does not work. Always the same result.
 
 If the form does not contain errors the data are saved well and the
 browser display S.notice(saved) correctly.
 The S.error method returns a List[FieldError]. I receive a List with
 the format of List(Full(tablename_field) : message)
 
 this is a field of my database class:
 [code]
 object description extends MappedTextarea(this, 255) {
override def displayName = Description
override def validations =  valMinLen(1, S.??(description must
 not be empty)) _ :: super.validations
  }
 
 [/code]
 
 thanks,
 wibble
 
 On Feb 6, 12:19 pm, Jeppe Nejsum Madsen je...@ingolfs.dk wrote:
 wibblecp wibbl...@gmail.com writes:
 it does not work even in the case of a single error on the form.
 
 the result is always a List(Full(entries_code) : Description must not
 be empty)
 
 Try adding showAll:
 
 lift:Msgs showAll=true
 
 But default, Msgs doesnøt show field-level errors
 
 /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.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.
 

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] ProtoUser i18n

2010-02-02 Thread Adam Warski
Hmm right, although e.g. password already exists as a key and it wouldn't be 
good to duplicate it as Password.
Same about Email.

On Feb 2, 2010, at 1:08 PM, Jeppe Nejsum Madsen wrote:

 Adam Warski a...@warski.org writes:
 
 We'll accept a patch for this issue.  
 
 Here's the patch.
 
 Note that this will break all existing translations. While having a
 complete list of keys that can be translated is great, I don't really
 think there's a reason to change the keys. E.g.
 
 First\ Name is, while maybe not common, a valid key.
 
 /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.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.
 

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] ProtoUser i18n

2010-02-02 Thread Adam Warski

 Hmm right, although e.g. password already exists as a key and it wouldn't 
 be good to duplicate it as Password.
 Same about Email.
 
 Good point. Also, the spaces in keys seem to confuse people, so maybe
 this is breakage that is worth it


I guess I'll leave the decision up to David ;)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] ProtoUser i18n

2010-02-02 Thread Adam Warski
Sure:

(a) http://github.com/dpp/liftweb/issues/issue/320
(b) http://gist.github.com/293435

I've also updated the wiki.

On Feb 2, 2010, at 8:10 PM, Indrajit Raychaudhuri wrote:

 Adam, can you please (a) open a ticket and (b) create a gist 
 (http://gist.github.com/) of the patch and refer to it from the ticket? We'll 
 take it up from there.
 
 Tim, +1 on not having spaces in properties.
 
 Cheers, Indrajit
 
 On 02/02/10 10:41 PM, Timothy Perrett wrote:
 Sure - one of us will take this up... its minor.
 
 I propose we agree a policy, and use that going forward... should keys have 
 spaces? no would be my default response... (i tend to separate with full 
 stops) if thats so, lets just clear that out now, and do a breaking changes 
 ann.
 
 Cheers, Tim
 
 On 2 Feb 2010, at 17:06, David Pollak wrote:
 
 I'm okay with breakage here.  Jeppe, Indrajit, or Tim, can you guys handle 
 this issue going forward (making sure the patch is good, putting it on a 
 branch, opening a ticket, putting it on review board, and sending out any 
 breaking changes email)?
 
 
 -- 
 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.
 

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] ProtoUser i18n

2010-02-01 Thread Adam Warski
Hello,

I'm using ProtoUser and all strings in the user menu, login, forgot password 
forms are localized except the Sign Up and Edit user forms. The problem is 
that in ProtoUser, the display names are defined as:

def firstNameDisplayName = ??(First Name)

instead using e.g. first.name. Sometimes the strings are in the resource 
bundles already (e.g. email, password), so it's just a matter of changing the 
keys. For others, new keys have to be added. I'd be of course happy to provide 
a patch with english  polish translations, but I read that you don't accept 
patches for some reason (although I can transfer all the IP for this big change 
to you ;) ).

Another thing is could the localForm method in ProtoUser stop being private 
(now it's private def localForm, line 628)? I just wanted to change the 
edit/signup forms decoration and for now had to copy the localForm into my code.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] NPE in MappedTextarea

2010-02-01 Thread Adam Warski
Hello,

if the value of a MappedTextarea field is null, an NPE is thrown. The problem 
is in the _toForm method. For example in MappedString, the method does:

value={is match {case null =  case s = s.toString}}

while in MappedTextarea, the value is simply {is.toString}, which causes the 
NPE.
So the fixed version should be, at line 29 of MappedTextarea:

override def _toForm: Box[Elem] = {
S.fmapFunc({s: List[String] = this.setFromAny(s)}){funcName =
Full(textarea name={funcName}
 rows={textareaRows.toString}
 cols={textareaCols.toString} id={fieldId}{is match {case null =  
case s = s.toString}}/textarea)}
  }

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Passing attributes to bound elements

2010-01-31 Thread Adam Warski
Hello,

  This was considered later on a defect, and not a feature. To preserve
  markup attributes in your bind use -% instead of -
 
 thanks, although the -% is missing support for the .toForm, as it returns a 
 Box[NodeSeq]. And for % you need an Elem. Any ideas how to deal with that? :)
 
 What are you applying toForm to?

In this case it is a MappedDate.
But I've worked around the problem using jquery (all I wanted to do is add the 
datepicker anyway): I can wrap the bound element using a span 
class=datePicker.../span, and then lookup all elements with that class, 
and for each get the child and apply the datepicker creation.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Passing attributes to bound elements

2010-01-29 Thread Adam Warski
Hello,

 This was considered later on a defect, and not a feature. To preserve
 markup attributes in your bind use -% instead of -

thanks, although the -% is missing support for the .toForm, as it returns a 
Box[NodeSeq]. And for % you need an Elem. Any ideas how to deal with that? :)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] Lift + UTF-8

2010-01-29 Thread Adam Warski
Hello,

maybe you have some ideas. I'm trying to make my lift app able to store polish 
characters, and I'm slowly running out of ideas.
I think it's something with mapper configuration, but I'm not sure.

When I submit a form with an ą character, I get the following exception:

Message: java.sql.SQLException: Incorrect string value: '\xC4\x85' for column 
'title' at row 1
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

What I did so far:
- the mysql table encoding is utf-8
- the connection string contains useUnicode=truecharacterEncoding=UTF-8
- LiftRules.early.append(_.setCharacterEncoding(UTF-8))

When the String is set on the model field it still is correct, so something 
happens when trying to persist the value. Is there a way in lift to configure 
jdbc so that it accepts utf-8 characters? Or am I missing something else?

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Lift + UTF-8

2010-01-29 Thread Adam Warski
Heh, sorry, I knew the moment I write a post here I'll find the answer ;)

Forgot that when converting a table in mysql you not only need to set the 
character encoding for the table but also for the individual columns.

Sorry again for the spam.

On Jan 29, 2010, at 3:01 PM, Adam Warski wrote:

 Hello,
 
 maybe you have some ideas. I'm trying to make my lift app able to store 
 polish characters, and I'm slowly running out of ideas.
 I think it's something with mapper configuration, but I'm not sure.
 
 When I submit a form with an ą character, I get the following exception:
 
 Message: java.sql.SQLException: Incorrect string value: '\xC4\x85' for column 
 'title' at row 1
   com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
 
 What I did so far:
 - the mysql table encoding is utf-8
 - the connection string contains useUnicode=truecharacterEncoding=UTF-8
 - LiftRules.early.append(_.setCharacterEncoding(UTF-8))
 
 When the String is set on the model field it still is correct, so something 
 happens when trying to persist the value. Is there a way in lift to configure 
 jdbc so that it accepts utf-8 characters? Or am I missing something else?
 
 -- 
 Adam Warski
 http://www.warski.org
 http://www.softwaremill.eu
 
 
 
 
 -- 
 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.
 

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Re: Lift logging improvements

2010-01-28 Thread Adam Warski
Also another logging-related problem that I sometimes have is that if an ajax 
call throws an exception, nothing is shown in the container logs. I can only 
see the stacktrace when I open up the ajax call's response in firebug. This 
sometimes takes time to figure out as at first it seems that clicking the 
button/link does nothing :).

Although I haven't yet searched Boot to see where I can set ajax logging, I 
think that by default such exceptions should be logged.

Adam

On Jan 28, 2010, at 12:19 PM, Jeppe Nejsum Madsen wrote:

 aw anth...@whitford.com writes:
 
 One thing that bugs me is how all the logging comes from one logger:
 lift [Slf4jLogger.scala:110]
 As a result, you don't have the granularity to adjust just
 org.liftweb.http or org.liftweb.mapper, for example.
 
 Indeed. That is one of the things I would try to remedy
 
 http://github.com/dpp/liftweb/issues/#issue/310
 
 
 I liked your suggestion about adding a Logging trait:
 http://groups.google.com/group/liftweb/browse_thread/thread/6aa012b673946242/b51747a0009ebae2?lnk=gstq=LOGGER#b51747a0009ebae2I'm
  thinking this would be a nice addition to the framework.
 
 I agree. I've created a ticket to track these changes:
 
 http://github.com/dpp/liftweb/issues/#issue/309
 
 /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.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.
 

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] Loc hidden if type parameter is Unit and default value is Empty

2010-01-28 Thread Adam Warski
Hello,

I just found something very strange. I have my own loc, which extends Loc[Unit].
If the default value is empty (def defaultValue = Empty), then the loc won't be 
shown in the menu (I don't have any LocParams). If the default value is 
Full(()), then it is shown.

I have other locs with other type params (that is, not Unit), where the default 
value is Empty, and they are shown normally.

Is this a bug, or expected behaviour for some reason?

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] Passing attributes to bound elements

2010-01-28 Thread Adam Warski
When trying to use datepicker on a form, I found a post (by Derek Chen-Becker) 
from august which says:

OK, the key there is the entrydate id. If you look at 
src/main/webapp/index.html, you'll see the markup in the Add Entry form: 

   tde:dateOf e:id=entrydate e:maxlength=10//td 

That e:id attribute gets merged so that the resulting element has the 
attribute id=entrydate set (likewise for maxlength). This is a convenient 
way of setting attributes on templates that will be bound in your snippets. 

And I wanted to use this way of setting attributes on elements, but it doesn't 
seem to work - no attributes get rendered on the resulting element. Is this 
still supported? (the only difference from the example is that I don't use 
e:id but my own prefix which I then bind to in my snippet)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Creating a path from a Loc

2010-01-27 Thread Adam Warski
Hello,

 If you need a String:
 
 (for {
   loc - SiteMap.findLoc(Login)
   path - loc.createDefaultPath
  } yield path.text) openOr /
 

right, I could just convert it to text. That works, thanks :).

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] What is purpose of RequestVar/StatefulSnipplet for forms?

2010-01-27 Thread Adam Warski
Hello,

 What's the purpose of RequestVars and StatefulSnippet? I thought the
 values were retained anyway through POST. That is, on submit, the
 functions desc = _ and amount = _ were executed and the so the
 state was kept...
 
 Are those functions only executed after the bind is complete? There
 must be something I'm missing here.


The functions are called after form submission, and the variable desc and 
amount will be updated. However those variables will belong to the original 
method call. So when the page is re-rendered (e.g. because of validation 
errors), the add method will be called again, and fresh variables will be 
created. So the values won't be retained. If you want to keep the values 
between updating and re-rendering, you need something more global, like a 
RequestVar or a StatefulSnippet.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Creating a path from a Loc

2010-01-27 Thread Adam Warski
Hello,

 Instead of building your Loc inline in the SiteMap declaration and
 using findLoc, simply declare the loc as a val (with the appropriate
 type parameter) in Boot or a similar object of your choosing.


yes, that looks quite nice, although I'm just using User.sitemap for now :).

But looking at MetaMegaProtoUser trait I now see that there's for example a 
loginPath val which I can simply use instead of lookuing up the loc. As well 
as some other useful functions :)

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



[Lift] Creating a path from a Loc

2010-01-26 Thread Adam Warski
Hello,

I'm having some trouble generating a link basing on a Loc.
My original use-case is to redirect the user to a  login page if the user is 
not logged in. I found a wiki on this and it says there to simply redirect to 
/user_mgt/login, however I think it would be much nicer if I could generate 
the link basing on looking up the right Loc.

However having the Loc I can only generate a NodeSeq, not a plain String.

So the solution would be to add a method into the Loc trait parallel to this 
one:

def createDefaultLink: Option[NodeSeq] = currentValue.flatMap(p = 
link.createLink(p)).toOption

which would be:

def createDefaultPath: Option[String] = currentValue.flatMap(p = 
link.createPath(p)).toOption

(btw., why is it Option here, not Box?)

Then generating a link to the login page would simply be:

SiteMap.findLoc(Login).open_!.createDefaultPath

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] Creating a path from a Loc

2010-01-26 Thread Adam Warski
Hello,

 For this you can use loc.link.createPath. I use something similar in
 my codebase. This has a little cruft you may not be precisely
 interested in, but if you look at the link and flink methods, you
 should be able to get an idea of how to use the Loc.Link:


I'm using Link in a similar way to, but here I can't use createPath, as 
SiteMap.findLoc(...) returns a Loc[_], so the type parameter is unknown, so 
without some casts I won't be able to pass the parameter.

I tried:

val loc = SiteMap.findLoc(Login).open_!
val link = loc.link.createPath(loc.currentValue.open_!)

but unfortunately the compiler doesn't seem to recognize the fact that the type 
parameter for loc is the same as the one returned for loc.currentValue.

-- 
Adam Warski
http://www.warski.org
http://www.softwaremill.eu




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



Re: [Lift] HTML table links

2010-01-25 Thread Adam Warski
Hello,

   table cellpadding=7px title=User summary
   thFirst Name/th
   thLast Name/th
   thHours Summary/th
   thWage/th
   lift:Users.list
   tr onmouseover=this.bgColor='#ee';
 onmouseout=this.bgColor='#FF';
   onclick=window.location 
 ='URL_TO_USER_DETAILS';
   tdu:fname //td
   tdu:lname //td
   tdu:hours //td
   tdu:money //td
   /tr
   /lift:Users.list
   /table
 
 What I want to achieve is that users clicks on table row and gets
 redirected to details about selected row (user in this case). I would
 like to implement this in View First pattern so i thought about
 replacing 'onclick' attribute inside Users.list method but I don't
 know the easy way to do this. The naive way would be using regular
 expressions, but i've got feeling that i'm reinventing wheel here.
 Please help.

There are several ways to do it.

I think the easiest one is to bind the view link to a SHtml.link, something 
like:

users.flatMap { user =
bind(..., ..., view - link(view.html, () = SelectedUser(user), 
Text(View user)) }

where view.html is a template where you can view the user, SelectedUser is a 
RequestVar that holds the selection after you've clicked.
You will also need to add the view.html to your sitemap.

If you want a persistent URL for viewing users, you can add a rewrite rule.

The use-case you are writing about is quite well described in the lift book 
(available in pdf for free), so I would also recommend looking there.

-- 
Adam

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



Re: [Lift] Re: HTML table links

2010-01-25 Thread Adam Warski
Hello,

 Could you please point me, I can't find it.

if you mean the lift book, it's here:
http://groups.google.com/group/the-lift-book

-- 
Adam

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



Re: [Lift] Re: Ajax forms and (multiple) submit buttons

2010-01-18 Thread Adam Warski
Hello,

 Right ... and it's not even a hack ... css is the right way of
 building layout not really the html. Putting buttons in the form ar
 giving this perception in the page doesn't mean that the button has to
 be physically in the form element (at least that's the way I see
 it.).

actually I think I'll take back the doable with CSS as it's quite easy for an 
add element button, but per-element operations, like delete, move up, 
move down would take really some more time to layout properly, if they were 
placed outside the form :).

But as I said, I'll make the whole form AJAX :).

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




Re: [Lift] Re: Ajax forms and (multiple) submit buttons

2010-01-16 Thread Adam Warski
Hello,

 Hmm yes I wondered if the order in which the functions are bound is 
 significant, but my experiments showed that it's not simply a first bound, 
 first called principle. So I don't quite get it yet why it doesn't work.
 
 We rely on JQuery (or other underlying library) to send the actual
 ajax request. We feed in the correct sequence but if your button is in
 the middle of the form (as fields were added after the button's
 location in the form) the sequence of the function id-s is not sent
 right via ajax even if onclick for the ajax button we first serialize
 the for and then add the function ID of the ajax button. Personally I
 don't see why this is an impediment

ah, clear now. Thanks a lot for the explanation. This is a small impediment if 
the button logically belongs inside the form (if I want the user to see the 
button inside the form), but then, as I wrote, I can use css to correctly 
position it, although I would consider it a small hack :)

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




Re: [Lift] Re: Ajax forms and (multiple) submit buttons

2010-01-15 Thread Adam Warski
Hello,

I tried the trunk version and again it almost works :)

1. the RequestVars aren't preserved for the ajax request. I think this can be 
fixed by replacing in SHtml:692 the NFuncHolder with a call to 
contextFuncBuilder, so the method would look like this:

def doit = makeFormElementWithName(submit, contextFuncBuilder(func), attrs: 
_*){
  case (funcName, elem) = 
   elem % 
   new UnprefixedAttribute(value, Text(value), Null) %
   (onclick - (liftAjax.lift_uriSuffix = '+funcName+=_'; return 
true;))
}

I tested it on my example application 
(http://github.com/adamw/lift-ajax-submit-test) and it works.

2. The button will work only with full ajax-forms right? So forms wrapped with 
ajaxForm(...)? My initial use-case was for adding some ajax buttons to normal 
forms (submitted with a normal http request), but I guess I can make the whole 
form submitted with ajax.

Thanks!
Adam

 Most likely I'll commit it today in master as it was approved by
 review board.
 
 Br's,
 Marius
 
 On Jan 14, 9:53 am, Adam Warski a...@warski.org wrote:
 I would of course be very +1 to include the ajaxSubmit :). Thanks for the 
 work.
 
 This looks a bit different to the button I tried before, maybe you have a 
 patch so that I can try it out on the test app?
 
 Adam
 
 On Jan 12, 2010, at 8:39 PM, Marius wrote:
 
 Dear all,
 
 Recently (and not only) there have been discussions about ajax forms
 and their submit Scala functions not being called and that's because
 JQuery's form serialization doesn't serialize  the input submits (for
 pertinent reasons). The workaround is as you know to use hidden
 fields.
 
 Adam also wanted an ajax form with multiple submit buttons taking
 different actions depending on which button is being called. This is
 also *doable* using hidden fields  but not quite from elegant.
 
 I've experimented a way to allow ajax form submission but after all
 form field functions are being called your own ajax Scala function is
 being called (with no hidden fields).  the idea is this:
 
 1. I added an SHtml.ajaxSubmit which has the same signature with
 SHtml.submit
 2. At js level I added a liftAjax.lift_uriSuffix
 3. When clicking the ajaxSubmit button we set the
 liftAjax.lift_uriSuffix with the function name value. This is the
 function name of your scala function. Hence your scala function for
 ajaxSubmit will be called after form field functions are called.
 
 In short we piggy back the Scala function info on top of the
 serialized form info.
 
 I tested it and it works just fine for me:
 
 Using it looks something like like:
 
  ajaxForm(bind(hello, xhtml,
   field1 - text(, (s) = {println(field1 =  + s)}),
   field2 - text(, (s) = {println(field2 =  + s)}),
   field3 - text(, (s) = {println(field3 =  + s)}),
   submit - ajaxSubmit(Press me, () = {
  println(my ajax func called.)
  Noop
}))
 
 ... you got the idea.
 
 This of course allows putting virtually any number of ajax submit
 buttons and the right function will be called on server side.
 
 I'm thinking to add this to Lift but first I'd like to know your
 thoughts.
 
 Br's,
 Marius
 --
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 -- 
 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.
 
 

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




Re: [Lift] Re: Ajax forms and (multiple) submit buttons

2010-01-15 Thread Adam Warski
Hello,

 Oh yeah contextFuncBuider ... good catch. I'll update today.

thanks :)

 
 2. The button will work only with full ajax-forms right? So forms wrapped 
 with ajaxForm(...)? My initial use-case was for adding some ajax buttons to 
 normal forms (submitted with a normal http request), but I guess I can make 
 the whole form submitted with ajax.
 
 Yes it is meant to work for ajaxForm. But for normal forms you can use
 submitAjaxForm you could use the ajaxButton I sent on a different
 thread. Not sure what the issue was with that as in my tests it worked
 fine.

well I guess you were just lucky because with the modified ajax button some 
form fields where update before, and some after the associated function was 
called. So in your tests all form fields feel into the before category. But 
in my test case on github some field elements are updated after the function, 
so they loose their value (it's very simple btw., just one form with a list of 
elements).

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




Re: [Lift] Re: Ajax forms and (multiple) submit buttons

2010-01-15 Thread Adam Warski

 I kinda doubt that as I tested with a bunch of form fields. In the
 ajax request the function ID of the ajax function was always the last
 in the parameters and functions are evaluated in canonical order (for
 the same owner). But I think you sent me your source code location and
 I need to look what's in there this weekend. I Hope your code that
 works as you described is still there :)

Yep, it's still there: http://github.com/adamw/lift-ajax-submit-test
Just run it, add one element, fill in the two input fields, and click add 
again, you should see the input disappearing.

Thanks a lot :)

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-13 Thread Adam Warski
Hello,

the problem is that some form elements are updated, then the function is 
called, and then the rest of the form elements are updated.
My code is more or less something like this:

def editElement(elementTemplate: NodeSeq): NodeSeq = {
  container.elements.flatMap { element: Element =
  bind(element, elementTemplate,
name - { println(bind element name  + element.name); 
SHtml.text(element.name.is,
  (s: String) = {println(set element name  + s); 
element.name(s); }) }
)
  }
}

bind(cont, containerTemplate,
  name - { println(bind container name  + conf.name); 
SHtml.text(cont.name.is,
  (s: String) = {println(set container name  + s); cont.name(s); 
}) },
  elements - editElement _,
  addElement - ajaxButton(Text(Add), edit_formid, () = { 
println(executing function); cont.addElement; reDraw })
  )

And the output, when I submit a form where 1 element is already added is:

09:04:23,450 INFO  [STDOUT] set container name a
09:04:23,474 INFO  [STDOUT] executing function
09:04:23,474 INFO  [STDOUT] bind container name a
09:04:23,475 INFO  [STDOUT] bind element name 0
09:04:23,476 INFO  [STDOUT] bind element name 1
09:04:23,478 INFO  [STDOUT] set element name 0a

So as you can see first cont.name is set, then the button function is executed, 
and later the element.names are set.

I can try creating a small lift app which would demo this if you'd like.
Also, I'm using 1.1-M8. Maybe I should try some newer version? (2.0-SNAPSHOT? 
1.1-SNAPSHOT?)

Adam

On Jan 12, 2010, at 6:03 PM, Marius wrote:

 I must have misread your post. I did test the ajaxButton above (with
 your corrections) and the behaviour is correct. Form field functions
 are invoked first and then your ajax function provided to ajaxButton.
 Thus this is a good way for adding submit functions for ajax form
 without the need of using hidden fields and I'll promote this for
 addition in Shtml (probably with slight modifications). I think the
 method name should be ajaxSubmit
 
 I don't quite get why you're saying this is a problem. What does step
 3 needs to accomplish? . all form fields functions are called (except
 if you have a Shtml.submit because form serialization does not include
 submits). Then you function is invoked and the response is sent to
 client.
 
 You mentioned that you just need to add multiple buttons for a ajax
 form ... this version of ajaxButton does just that. Can you please
 clarify your used case for for for those 3 steps? ...
 
 Br's,
 Marius
 
 On Jan 12, 4:20 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 this *almost* works :).
 
 I modified your code a bit and now I have:
 
 def ajaxButton(text: NodeSeq, formId: String, func: () = JsCmd, attrs: 
 (String, String)*): Elem = {
 attrs.foldLeft(fmapFunc(contextFuncBuilder(func))(name =
 button onclick={makeAjaxCall(JsRaw(
   LiftRules.jsArtifacts.serialize(formId).toJsCmd +  +  + 
 Str( + name + =true).toJsCmd)).toJsCmd +
 ; return false;}{text}/button))(_ % _)
   }
 
 Now the form submits and the right function is executed on the server, and 
 the form is redrawn in the browser.
 
 However, the problem is in the ordering of operations.
 The sequence basically is:
 (1) update some elements of the form
 (2) execute the function
 (3) update the rest of the elements of the form
 
 The problem of course is that (2) returns the new content of the form (a 
 SetHtml JsCmd), generated basing on state without all fields updated.
 I don't quite yet get the rule deciding which fields get updated before 
 calling the function, and which after.
 One thing I noticed is that if I move the field that is bound first (in 
 bind(...)) to be the last field, it gets moved from group (1) to (3).
 
 Also, I thought that maybe the ordering of POST values matters, but swapping 
 Str( + name + =true).toJsCmd and 
 LiftRules.jsArtifacts.serialize(formId).toJsCmd doesn't have any effect.
 
 I tried the form many times and always get the same behaviour, so the (1) 
 vs. (3) division seems to be deterministic :)
 
 Adam
 
 On Jan 11, 2010, at 10:58 PM, Marius wrote:
 
 Adam I was thinking of a slightly different approach that does not
 involve hidden fields:
 
 Say you have your current form with SHtml.text, checkboxes or whatever
 have you:
 
 then your ajax buttons (outside the form) like:
 
  def ajaxButton(text: NodeSeq, formId: String, func: () = JsCmd,
 attrs: (String, String)*): Elem = {
attrs.foldLeft(fmapFunc(contextFuncBuilder(SFuncHolder(func)))
 (name =
button onclick={makeAjaxCall(JsRaw
 (LiftRules.jsArtifacts.serialize(formId) +  + name.encJs +
 =_)).toJsCmd +
; return false;}{text}/button))(_ % _)
  }
 
 I haven't tested though but you get the idea ... When we do the ajax
 call, we serialize the form and add the name parameter as well. This
 will cause your field functions to be called, and at the end you

Re: [Lift] Re: Ajax button + submitting a form

2010-01-13 Thread Adam Warski
Hello,

 Yes please a small app would be best. Please use 2.0-SNAPSHOT.

Here it is:
http://github.com/adamw/lift-ajax-submit-test/

Steps to reproduce:
1. checkout from git :)
2. run mvn jetty:run
3. go to http://localhost:8080
4. click add once
5. fill in the two fields with some values e.g. container, room
6. click add again
7. the container value will stay, while the room value will disappear. In 
the logs, you can see:

set container name cont
executing funtion
bind container name cont
bind room name 
bind room name 
set room name room

 Also please see this thread: 
 http://groups.google.com/group/liftweb/browse_thread/thread/75750c42ec3a2d7d?hl=en#
Yeah, I saw it, as far as I understand the ajaxSubmit is more or less the same 
as the ajaxButton you did (and I corrected)?

Thanks,
Adam-- 
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.




Re: [Lift] Re: Ajax button + submitting a form

2010-01-13 Thread Adam Warski
Also, interestingly, if you change the order of binding from:

bind(cont, containerTemplate,
  name - { println(bind container name  + cont.name); 
SHtml.text(cont.name,
  (s: String) = {println(set container name  + s); cont.name = 
s; }) },
  rooms - editRoom _,
  addRoom - ajaxButton(Text(Add), cont_edit,
() = { println(executing funtion); cont.rooms += new Room; reDraw })
  )

to:

bind(cont, containerTemplate,
  rooms - editRoom _,
  addRoom - ajaxButton(Text(Add), cont_edit,
() = { println(executing funtion); cont.rooms += new Room; reDraw }),
  name - { println(bind container name  + cont.name); 
SHtml.text(cont.name,
  (s: String) = {println(set container name  + s); cont.name = 
s; }) }
  )

then the container name is also lost on submit. The log output is then:

executing funtion
bind container name 
bind room name 
bind room name 
set container name container
set room name room

Adam

On Jan 13, 2010, at 10:13 AM, Adam Warski wrote:

 Hello,
 
 Yes please a small app would be best. Please use 2.0-SNAPSHOT.
 
 Here it is:
 http://github.com/adamw/lift-ajax-submit-test/
 
 Steps to reproduce:
 1. checkout from git :)
 2. run mvn jetty:run
 3. go to http://localhost:8080
 4. click add once
 5. fill in the two fields with some values e.g. container, room
 6. click add again
 7. the container value will stay, while the room value will disappear. In 
 the logs, you can see:
 
 set container name cont
 executing funtion
 bind container name cont
 bind room name 
 bind room name 
 set room name room
 
 Also please see this thread: 
 http://groups.google.com/group/liftweb/browse_thread/thread/75750c42ec3a2d7d?hl=en#
 Yeah, I saw it, as far as I understand the ajaxSubmit is more or less the 
 same as the ajaxButton you did (and I corrected)?
 
 Thanks,
 Adam-- 
 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.
 
 

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




Re: [Lift] Ajax forms and (multiple) submit buttons

2010-01-13 Thread Adam Warski
I would of course be very +1 to include the ajaxSubmit :). Thanks for the work.

This looks a bit different to the button I tried before, maybe you have a patch 
so that I can try it out on the test app?

Adam

On Jan 12, 2010, at 8:39 PM, Marius wrote:

 Dear all,
 
 Recently (and not only) there have been discussions about ajax forms
 and their submit Scala functions not being called and that's because
 JQuery's form serialization doesn't serialize  the input submits (for
 pertinent reasons). The workaround is as you know to use hidden
 fields.
 
 Adam also wanted an ajax form with multiple submit buttons taking
 different actions depending on which button is being called. This is
 also *doable* using hidden fields  but not quite from elegant.
 
 I've experimented a way to allow ajax form submission but after all
 form field functions are being called your own ajax Scala function is
 being called (with no hidden fields).  the idea is this:
 
 1. I added an SHtml.ajaxSubmit which has the same signature with
 SHtml.submit
 2. At js level I added a liftAjax.lift_uriSuffix
 3. When clicking the ajaxSubmit button we set the
 liftAjax.lift_uriSuffix with the function name value. This is the
 function name of your scala function. Hence your scala function for
 ajaxSubmit will be called after form field functions are called.
 
 In short we piggy back the Scala function info on top of the
 serialized form info.
 
 I tested it and it works just fine for me:
 
 Using it looks something like like:
 
  ajaxForm(bind(hello, xhtml,
   field1 - text(, (s) = {println(field1 =  + s)}),
   field2 - text(, (s) = {println(field2 =  + s)}),
   field3 - text(, (s) = {println(field3 =  + s)}),
   submit - ajaxSubmit(Press me, () = {
  println(my ajax func called.)
  Noop
}))
 
 ... you got the idea.
 
 This of course allows putting virtually any number of ajax submit
 buttons and the right function will be called on server side.
 
 I'm thinking to add this to Lift but first I'd like to know your
 thoughts.
 
 Br's,
 Marius
 -- 
 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.
 
 

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-12 Thread Adam Warski
Hello,

this *almost* works :).

I modified your code a bit and now I have:

def ajaxButton(text: NodeSeq, formId: String, func: () = JsCmd, attrs: 
(String, String)*): Elem = {
attrs.foldLeft(fmapFunc(contextFuncBuilder(func))(name =
button onclick={makeAjaxCall(JsRaw(
  LiftRules.jsArtifacts.serialize(formId).toJsCmd +  +  + Str( 
+ name + =true).toJsCmd)).toJsCmd +
; return false;}{text}/button))(_ % _)
  }

Now the form submits and the right function is executed on the server, and the 
form is redrawn in the browser.

However, the problem is in the ordering of operations.
The sequence basically is:
(1) update some elements of the form
(2) execute the function
(3) update the rest of the elements of the form

The problem of course is that (2) returns the new content of the form (a 
SetHtml JsCmd), generated basing on state without all fields updated.
I don't quite yet get the rule deciding which fields get updated before calling 
the function, and which after.
One thing I noticed is that if I move the field that is bound first (in 
bind(...)) to be the last field, it gets moved from group (1) to (3).

Also, I thought that maybe the ordering of POST values matters, but swapping 
Str( + name + =true).toJsCmd and 
LiftRules.jsArtifacts.serialize(formId).toJsCmd doesn't have any effect.

I tried the form many times and always get the same behaviour, so the (1) vs. 
(3) division seems to be deterministic :)

Adam

On Jan 11, 2010, at 10:58 PM, Marius wrote:

 Adam I was thinking of a slightly different approach that does not
 involve hidden fields:
 
 Say you have your current form with SHtml.text, checkboxes or whatever
 have you:
 
 then your ajax buttons (outside the form) like:
 
 
  def ajaxButton(text: NodeSeq, formId: String, func: () = JsCmd,
 attrs: (String, String)*): Elem = {
attrs.foldLeft(fmapFunc(contextFuncBuilder(SFuncHolder(func)))
 (name =
button onclick={makeAjaxCall(JsRaw
 (LiftRules.jsArtifacts.serialize(formId) +  + name.encJs +
 =_)).toJsCmd +
; return false;}{text}/button))(_ % _)
  }
 
 I haven't tested though but you get the idea ... When we do the ajax
 call, we serialize the form and add the name parameter as well. This
 will cause your field functions to be called, and at the end you
 ajaxButton function to be called. Inside func function your RequestVar
 should be preserved due to contextFuncBuilde call.
 
 
 Please let me know if this works. If it does we should probably add it
 to SHtml.
 
 Br's,
 Marius
 
 On Jan 11, 10:54 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 trying the solution a bit more I came into another problem which I can't 
 solve elegantly.
 
 The solution below works nicely for an add button, but a delete button 
 causes more problems: the problem is that with delete, you must know which 
 element should get deleted.
 
 In a no-ajax solution, it is enough to do:
 
 elements.flatMap { element: Element =
bind(element, element Template,
   name - element.name.toForm,
   delete - submit(Delete, () = { elements -= element })
)
 
 }
 
 which is very nice and easy, as the element to delete gets captured in a 
 closure.
 But with ajax, and a hidden field used to hold the name of the operation to 
 dispatch, this gets pretty complex: I now need to somehow encode the element 
 to delete (or create a map from some unique identifier to closures which 
 hold the delete methods), so that I can set this as a value of the hidden 
 field. Then in the function passed to SHtml.hidden, I need to decode it back 
 to find the right element. Isn't it a bit of what Lift already does when 
 creating forms?
 
 But I still have the feeling that maybe I'm approaching the whole problem 
 from the wrong end, after all, I just want to create an ajax-enabled list of 
 input fields with add and delete operations :)
 
 Adam
 
 
 
 On Jan 11, 1:09 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 this almost works :).
 
 Right now in my form I have a hidden element where the type of the 
 operation to execute will be set:
 input type=hidden id=operation_id name=operation_id value= /
 (the name is needed for jquery to set the value, and the id so that I can 
 later read the value using S).
 
 I bind the button as following:
 
 addElement - button onclick={((JqId(Str(operation_id))  
 JqAttr(value, Str(add)))
SHtml.submitAjaxForm(elements_edit)).toJsCmd+ return 
 false;}{Text(Add element)}/button,
 
 and add a hidden field to the whole form to do the processing:
 
 bind(
 ...
 )  ++ SHtml.hidden(() = {
   val operationId = S.param(operation_id)
   operationId.map { opId = opId match {
 case add = elements += new Element
 case _ = println(Unknown operation:  + opId)
   } }
   reDraw
 })
 
 where elements is a RequestVar object.
 
 However for some reason, when I click the button, in the callback I get a 
 new elements RequestVar (so it's

Re: [Lift] Re: Ajax button + submitting a form

2010-01-11 Thread Adam Warski
Hello,

this almost works :).

Right now in my form I have a hidden element where the type of the operation to 
execute will be set:
input type=hidden id=operation_id name=operation_id value= /
(the name is needed for jquery to set the value, and the id so that I can later 
read the value using S).

I bind the button as following:

addElement - button onclick={((JqId(Str(operation_id))  JqAttr(value, 
Str(add)))
   SHtml.submitAjaxForm(elements_edit)).toJsCmd+ return 
false;}{Text(Add element)}/button,

and add a hidden field to the whole form to do the processing:

bind(
...
)  ++ SHtml.hidden(() = {
  val operationId = S.param(operation_id)
  operationId.map { opId = opId match {
case add = elements += new Element
case _ = println(Unknown operation:  + opId)
  } }
  reDraw
})

where elements is a RequestVar object.

However for some reason, when I click the button, in the callback I get a new 
elements RequestVar (so it's initialized to an initial value) and moreover, 
nothing gets redrawn on the page. What is also quite weird is that the 
RequestVar is re-initialized, but the snippet instance stays the same. Any 
ideas? :)

I thought that my use-case would be quite common in lift: I just want to add a 
couple of buttons to my form which execute different actions.

Thanks for the help!
Adam

On Jan 10, 2010, at 6:03 PM, Marius wrote:

 
 Sorry I think the syntax would be (I haven't tested it though):
 
 button onclick={((JqId(hidden_field_id)  JqAttr(value, add))
  SHtml.submitAjaxForm(form_ID)).toJsCmd}add/button
 button onclick={((JqId(hidden_field_id)  JqAttr(value,
 edit))  SHtml.submitAjaxForm(form_ID)).toJsCmd}edit/button
 button onclick={((JqId(hidden_field_id)  JqAttr(value,
 delete))  SHtml.submitAjaxForm(form_ID)).toJsCmd}delete/button
 
 Br's,
 Marius
 
 On Jan 10, 6:58 pm, Marius marius.dan...@gmail.com wrote:
 On Jan 10, 5:20 pm, Adam Warski a...@warski.org wrote:
 
 Hello,
 
 ajaxButton(Press me would ya'?, SHtml.submitAjaxForm
 (form_ID).toJsCmd, (some) = {
 
 do your stuff here
 
 })
 
 Looking at the source code I think this might work, but I'm having trouble 
 constructing the correct expression to pass to ajaxButton. The method 
 signature requires a Call instance, and SHtml.submitAjaxForm results in a 
 command (JsCmd). Is it possible to somehow combine the two?
 
 I was referring to this signature:
 
 def ajaxButton(text: NodeSeq, jsExp: JsExp, func: String = JsCmd,
 attrs: (String, String)*): Elem
 
 and not
 
 def ajaxButton(text: NodeSeq, jsFunc: Call, func: () = JsCmd, attrs:
 (String, String)*): Elem
 
 jsExp will be called before sending the actual ajax. But this may be a
 bit problematic if your jsExp sends the ajaxForm the ajax request is
 processed asynchronously at js level meaning the the button ajax
 request may be send before the actual ajax form processing is done.
 I'm not sure if this fits your needs
 
 
 
 Or maybe there is some other, lift-idomatic way to solve my problem?
 I want to create a form with a list of elements, with three ajax buttons: 
 add, remove and save (adding/removing a row and persisting the list)
 
 The first solution I described involving hidden fields will definitely
 work. I don't think you need to do 2 ajax calls (one for the form and
 one for the button) but piggy back the button information into a
 hidden field and only submit the form:
 
 Perhaps something like:
 
 button onclick={(JqId(hidden_field_id)  JqAttr(value, add)) +
 + SHtml.submitAjaxForm(form_ID).toJsCmd}blah/button
 
 
 
 By the way, I think there's a small inconsistency; there are 7 overloaded 
 variants for ajaxButton:
 
 ajaxButton(text: NodeSeq, func: () = JsCmd, attrs: (String, String)*): Elem
 ajaxButton(text: String, func: () = JsCmd, attrs: (String, String)*): Elem
 
 ajaxButton(text: NodeSeq, jsFunc: Call, func: () = JsCmd, attrs: (String, 
 String)*): Elem
 ajaxButton(text: String, jsFunc: Call, func: () = JsCmd, attrs: (String, 
 String)*): Elem
 
 ajaxButton(text: NodeSeq, jsExp: JsExp, func: String = JsCmd, attrs: 
 (String, String)*): Elem
 
 and the last one doesn't have a text: String counterpart. Also the javadoc 
 for the last variant is missing information on what's jsExp and what's 
 the argument passed to func. My guess would be that jsExp is evaluated 
 and the result passed to func on the server?
 
 Yes jsExp is being evaluated and its result is being sent to server.
 Please open a defect for this inconsistency.
 
 
 
 --
 Adam
 -- 
 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.
 
 

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift

Re: [Lift] Re: Ajax button + submitting a form

2010-01-11 Thread Adam Warski
Hello,

 However for some reason, when I click the button, in the callback I get a 
 new elements RequestVar (so it's initialized to an initial value) and 
 moreover, nothing gets redrawn on the page. What is also quite weird is that 
 the RequestVar is re-initialized, but the snippet instance stays the same. 
 Any ideas? :)
 
 Yes I think so. You have a regular form with fields like: (SHtml.text.
 SHtml.hidden etc. right? RequestVars are kept around into a snapshot-
 restorer only for ajax functions (like for ajaxText etc) and not for
 regular fields forms. Thus in the Scala function of a SHtml.ajaxText
 you'll see the RequestVar set when the page was rendered because its
 state is preserved on purpose by lift. However for regular fields this
 is not happening. So there is a difference between an ajax-form and
 ajax fields. Even your form is sent via ajax, the fields are regular
 fields not ajax fields (... ajax fields do not even need to live
 inside a form). Therefore for your case the RequestVar's are not
 preserved and they are renewed when the request comes in. You can keep
 around that state using a SessionVar.

Ah, clear now. And it even works, thanks a lot for the help! :)

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-11 Thread Adam Warski
Hello,

 I don't think you need a SessionVar. You can just capture the RequestVar's 
 value in a local val and refer to that in the closure.
 Basically if I understand correctly, this is a typical scenario where you 
 output a form and associate functions with its fields which are to be 
 executed on the *next* request when it's submitted. That request will use a 
 new snippet instance for its output, but first it executes your functions, 
 which have captured references to whatever they refer to.

yes, what I'm doing is I capture the value in a function and later in that 
function I update the request variable with the captured value so that the form 
is rendered correctly.

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-11 Thread Adam Warski
Hello,

trying the solution a bit more I came into another problem which I can't solve 
elegantly.

The solution below works nicely for an add button, but a delete button 
causes more problems: the problem is that with delete, you must know which 
element should get deleted.

In a no-ajax solution, it is enough to do:

elements.flatMap { element: Element =
   bind(element, element Template,
  name - element.name.toForm,
  delete - submit(Delete, () = { elements -= element })
   )
}

which is very nice and easy, as the element to delete gets captured in a 
closure.
But with ajax, and a hidden field used to hold the name of the operation to 
dispatch, this gets pretty complex: I now need to somehow encode the element to 
delete (or create a map from some unique identifier to closures which hold the 
delete methods), so that I can set this as a value of the hidden field. Then in 
the function passed to SHtml.hidden, I need to decode it back to find the right 
element. Isn't it a bit of what Lift already does when creating forms?

But I still have the feeling that maybe I'm approaching the whole problem from 
the wrong end, after all, I just want to create an ajax-enabled list of input 
fields with add and delete operations :)

Adam

 
 
 On Jan 11, 1:09 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 this almost works :).
 
 Right now in my form I have a hidden element where the type of the operation 
 to execute will be set:
 input type=hidden id=operation_id name=operation_id value= /
 (the name is needed for jquery to set the value, and the id so that I can 
 later read the value using S).
 
 I bind the button as following:
 
 addElement - button onclick={((JqId(Str(operation_id))  
 JqAttr(value, Str(add)))
SHtml.submitAjaxForm(elements_edit)).toJsCmd+ return 
 false;}{Text(Add element)}/button,
 
 and add a hidden field to the whole form to do the processing:
 
 bind(
 ...
 )  ++ SHtml.hidden(() = {
   val operationId = S.param(operation_id)
   operationId.map { opId = opId match {
 case add = elements += new Element
 case _ = println(Unknown operation:  + opId)
   } }
   reDraw
 })
 
 where elements is a RequestVar object.
 
 However for some reason, when I click the button, in the callback I get a 
 new elements RequestVar (so it's initialized to an initial value) and 
 moreover, nothing gets redrawn on the page. What is also quite weird is that 
 the RequestVar is re-initialized, but the snippet instance stays the same. 
 Any ideas? :)
 
 Yes I think so. You have a regular form with fields like: (SHtml.text.
 SHtml.hidden etc. right? RequestVars are kept around into a snapshot-
 restorer only for ajax functions (like for ajaxText etc) and not for
 regular fields forms. Thus in the Scala function of a SHtml.ajaxText
 you'll see the RequestVar set when the page was rendered because its
 state is preserved on purpose by lift. However for regular fields this
 is not happening. So there is a difference between an ajax-form and
 ajax fields. Even your form is sent via ajax, the fields are regular
 fields not ajax fields (... ajax fields do not even need to live
 inside a form). Therefore for your case the RequestVar's are not
 preserved and they are renewed when the request comes in. You can keep
 around that state using a SessionVar.
 
 
 I thought that my use-case would be quite common in lift: I just want to add 
 a couple of buttons to my form which execute different actions.
 
 Which is very easy to do. But your problem not is how you maintain
 your specific state (the elements)
 
 
 Thanks for the help!
 Adam
 
 On Jan 10, 2010, at 6:03 PM, Marius wrote:
 
 
 
 Sorry I think the syntax would be (I haven't tested it though):
 
 button onclick={((JqId(hidden_field_id)  JqAttr(value, add))
  SHtml.submitAjaxForm(form_ID)).toJsCmd}add/button
 button onclick={((JqId(hidden_field_id)  JqAttr(value,
 edit))  SHtml.submitAjaxForm(form_ID)).toJsCmd}edit/button
 button onclick={((JqId(hidden_field_id)  JqAttr(value,
 delete))  SHtml.submitAjaxForm(form_ID)).toJsCmd}delete/button
 
 Br's,
 Marius
 
 On Jan 10, 6:58 pm, Marius marius.dan...@gmail.com wrote:
 On Jan 10, 5:20 pm, Adam Warski a...@warski.org wrote:
 
 Hello,
 
 ajaxButton(Press me would ya'?, SHtml.submitAjaxForm
 (form_ID).toJsCmd, (some) = {
 
 do your stuff here
 
 })
 
 Looking at the source code I think this might work, but I'm having 
 trouble constructing the correct expression to pass to ajaxButton. The 
 method signature requires a Call instance, and SHtml.submitAjaxForm 
 results in a command (JsCmd). Is it possible to somehow combine the two?
 
 I was referring to this signature:
 
 def ajaxButton(text: NodeSeq, jsExp: JsExp, func: String = JsCmd,
 attrs: (String, String)*): Elem
 
 and not
 
 def ajaxButton(text: NodeSeq, jsFunc: Call, func: () = JsCmd, attrs:
 (String, String)*): Elem
 
 jsExp will be called before sending the actual ajax. But this may be a
 bit problematic

Re: [Lift] Re: Ajax button + submitting a form

2010-01-10 Thread Adam Warski
Hello,

thanks, but my use-case is a bit different.

I want the whole form to be still submitted using a POST (the normal way), 
and only use ajax for a small fragment of the page (the element editor). So I 
can't use ajaxForm(...), as this would make all submit buttons use ajax.

Adam

On Jan 9, 2010, at 3:55 PM, greekscala wrote:

 Hello,
 
 I have a similar use case. For an AjaxForm you have to write:
  SHtml.ajaxForm(
  bind(mytags, xml,
   // binding to your tags ...
 
submit - SHtml.submit(do it, save),
  ) ++ SHtml.hidden(save)
)
 
 You dont need to have a form element in your templates for this to
 work
 because ajaxForm will wrap the result of the bind method.
 
 For my listelements checkbox, I attach to the checkbox a function,
 that adds an Id and the
 checkbox value to a ListBuffer[(Boolean, String)]. (checked and not
 checked boxes are submittet)
 
 Then I filter the List for the selected values a do what I have to do
 with them.
 I the above code example, my save method does some db stuff and then
 returning
 a JsCmds.SetHtml(an html id, some html/snippet nodeseq) for a
 redraw.
 
 Hope this helps a little
 
 with best regards
 
 On 9 Jan., 10:48, Adam Warski a...@warski.org wrote:
 Hello,
 
 I have a regular form, which is submitted with a POST (no AJAX here yet). 
 The form contains a list, to which you can add and remove elements using 
 AJAX. So the add and remove buttons are:
 
 add - ajaxButton(Add element, () = { elements += new Element; reDraw })
 
 The reDraw method is a SetHtml for the whole form. Now this almost works, 
 with the exception that when I press the add button all other changes in 
 the form are discarded, as the form is not submitted. So, when the button is 
 pressed, I would need to submit the form using ajax and execute a given 
 function on the server. In the archives I found SHtml.submitAjaxForm(formId) 
 method, which I guess does what I need, but I don't know how to combine it 
 with an ajaxButton?
 
 --
 Thanks,
 Adam
 -- 
 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.
 
 

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-10 Thread Adam Warski
There is also a related problem:
how can I have two ajax buttons on one form which submit the form and execute 
different functions on the server?

Using the standard trick:
SHtml.ajaxForm(bind(...) ++ SHtml.hidden(submitFunction)) 
won't work, as I want different functions executed for different buttons.

Adam

On Jan 10, 2010, at 10:42 AM, Adam Warski wrote:

 Hello,
 
 thanks, but my use-case is a bit different.
 
 I want the whole form to be still submitted using a POST (the normal way), 
 and only use ajax for a small fragment of the page (the element editor). So I 
 can't use ajaxForm(...), as this would make all submit buttons use ajax.
 
 Adam
 
 On Jan 9, 2010, at 3:55 PM, greekscala wrote:
 
 Hello,
 
 I have a similar use case. For an AjaxForm you have to write:
 SHtml.ajaxForm(
 bind(mytags, xml,
  // binding to your tags ...
 
   submit - SHtml.submit(do it, save),
 ) ++ SHtml.hidden(save)
   )
 
 You dont need to have a form element in your templates for this to
 work
 because ajaxForm will wrap the result of the bind method.
 
 For my listelements checkbox, I attach to the checkbox a function,
 that adds an Id and the
 checkbox value to a ListBuffer[(Boolean, String)]. (checked and not
 checked boxes are submittet)
 
 Then I filter the List for the selected values a do what I have to do
 with them.
 I the above code example, my save method does some db stuff and then
 returning
 a JsCmds.SetHtml(an html id, some html/snippet nodeseq) for a
 redraw.
 
 Hope this helps a little
 
 with best regards
 
 On 9 Jan., 10:48, Adam Warski a...@warski.org wrote:
 Hello,
 
 I have a regular form, which is submitted with a POST (no AJAX here yet). 
 The form contains a list, to which you can add and remove elements using 
 AJAX. So the add and remove buttons are:
 
 add - ajaxButton(Add element, () = { elements += new Element; reDraw 
 })
 
 The reDraw method is a SetHtml for the whole form. Now this almost works, 
 with the exception that when I press the add button all other changes in 
 the form are discarded, as the form is not submitted. So, when the button 
 is pressed, I would need to submit the form using ajax and execute a given 
 function on the server. In the archives I found 
 SHtml.submitAjaxForm(formId) method, which I guess does what I need, but I 
 don't know how to combine it with an ajaxButton?
 
 --
 Thanks,
 Adam
 -- 
 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.
 
 
 
 -- 
 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.
 
 

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-10 Thread Adam Warski
right, I wrote about that in my original post, but how can I execute a 
button-specific method on the server-side?

Thanks,
Adam

On Jan 10, 2010, at 12:15 PM, Marius wrote:

 The ajax buttons doesn't have to be inside the form if you use
 SHtml.submitAjaxForm(form_ID)
 
 button onclick={SHtml.submitAjaxForm(form_ID).toJsCmd}blah/button
 
 Br's,
 Marius
 
 On Jan 10, 1:08 pm, Adam Warski a...@warski.org wrote:
 There is also a related problem:
 how can I have two ajax buttons on one form which submit the form and 
 execute different functions on the server?
 
 Using the standard trick:
 SHtml.ajaxForm(bind(...) ++ SHtml.hidden(submitFunction))
 won't work, as I want different functions executed for different buttons.
 
 Adam
 
 On Jan 10, 2010, at 10:42 AM, Adam Warski wrote:
 
 Hello,
 
 thanks, but my use-case is a bit different.
 
 I want the whole form to be still submitted using a POST (the normal 
 way), and only use ajax for a small fragment of the page (the element 
 editor). So I can't use ajaxForm(...), as this would make all submit 
 buttons use ajax.
 
 Adam
 
 On Jan 9, 2010, at 3:55 PM, greekscala wrote:
 
 Hello,
 
 I have a similar use case. For an AjaxForm you have to write:
 SHtml.ajaxForm(
 bind(mytags, xml,
  // binding to your tags ...
 
   submit - SHtml.submit(do it, save),
 ) ++ SHtml.hidden(save)
   )
 
 You dont need to have a form element in your templates for this to
 work
 because ajaxForm will wrap the result of the bind method.
 
 For my listelements checkbox, I attach to the checkbox a function,
 that adds an Id and the
 checkbox value to a ListBuffer[(Boolean, String)]. (checked and not
 checked boxes are submittet)
 
 Then I filter the List for the selected values a do what I have to do
 with them.
 I the above code example, my save method does some db stuff and then
 returning
 a JsCmds.SetHtml(an html id, some html/snippet nodeseq) for a
 redraw.
 
 Hope this helps a little
 
 with best regards
 
 On 9 Jan., 10:48, Adam Warski a...@warski.org wrote:
 Hello,
 
 I have a regular form, which is submitted with a POST (no AJAX here yet). 
 The form contains a list, to which you can add and remove elements using 
 AJAX. So the add and remove buttons are:
 
 add - ajaxButton(Add element, () = { elements += new Element; 
 reDraw })
 
 The reDraw method is a SetHtml for the whole form. Now this almost 
 works, with the exception that when I press the add button all other 
 changes in the form are discarded, as the form is not submitted. So, when 
 the button is pressed, I would need to submit the form using ajax and 
 execute a given function on the server. In the archives I found 
 SHtml.submitAjaxForm(formId) method, which I guess does what I need, but 
 I don't know how to combine it with an ajaxButton?
 
 --
 Thanks,
 Adam
 --
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 
 --
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 -- 
 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.
 
 

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




Re: [Lift] Re: Ajax button + submitting a form

2010-01-10 Thread Adam Warski
Hello,

 ajaxButton(Press me would ya'?, SHtml.submitAjaxForm
 (form_ID).toJsCmd, (some) = {
 
 do your stuff here
 
 })

Looking at the source code I think this might work, but I'm having trouble 
constructing the correct expression to pass to ajaxButton. The method signature 
requires a Call instance, and SHtml.submitAjaxForm results in a command 
(JsCmd). Is it possible to somehow combine the two?

Or maybe there is some other, lift-idomatic way to solve my problem?
I want to create a form with a list of elements, with three ajax buttons: add, 
remove and save (adding/removing a row and persisting the list).

By the way, I think there's a small inconsistency; there are 7 overloaded 
variants for ajaxButton:

ajaxButton(text: NodeSeq, func: () = JsCmd, attrs: (String, String)*): Elem
ajaxButton(text: String, func: () = JsCmd, attrs: (String, String)*): Elem

ajaxButton(text: NodeSeq, jsFunc: Call, func: () = JsCmd, attrs: (String, 
String)*): Elem
ajaxButton(text: String, jsFunc: Call, func: () = JsCmd, attrs: (String, 
String)*): Elem

ajaxButton(text: NodeSeq, jsExp: JsExp, func: String = JsCmd, attrs: (String, 
String)*): Elem

and the last one doesn't have a text: String counterpart. Also the javadoc for 
the last variant is missing information on what's jsExp and what's the 
argument passed to func. My guess would be that jsExp is evaluated and the 
result passed to func on the server?

-- 
Adam

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




[Lift] Ajax button + submitting a form

2010-01-09 Thread Adam Warski
Hello,

I have a regular form, which is submitted with a POST (no AJAX here yet). The 
form contains a list, to which you can add and remove elements using AJAX. So 
the add and remove buttons are:

add - ajaxButton(Add element, () = { elements += new Element; reDraw })

The reDraw method is a SetHtml for the whole form. Now this almost works, 
with the exception that when I press the add button all other changes in the 
form are discarded, as the form is not submitted. So, when the button is 
pressed, I would need to submit the form using ajax and execute a given 
function on the server. In the archives I found SHtml.submitAjaxForm(formId) 
method, which I guess does what I need, but I don't know how to combine it with 
an ajaxButton?

-- 
Thanks,
Adam-- 
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.




Re: [Lift] Re: Errors not shown after AJAX form submit

2010-01-05 Thread Adam Warski
Hello,

 I think the difference is in showAll scope. It was implemented for non
 Ajax context (just for msgs snippet) but it wasn't implemented for
 Ajax (as far as I can tell).
 
 Ajax notices (if there are any) are appended to user's JsCmd response.
 But this code has no idea about the showAll snippet attribute.
 Therefore ajax notices that are associates with an ID will not be
 shown in lift:Msgs showAll=true/ 's real estate.
 
 Please open a defect for this.
I think I more or less understand :)
Here's the defect: http://github.com/dpp/liftweb/issues/#issue/271

By the way, do you have any idea why my example application produces such weird 
results?
I looked in the RequestVar code and didn't find anything there that would make 
it behave differently in the two scenarios.

Adam


 Br's,
 Marius
 
 On Jan 5, 9:37 am, Adam Warski a...@warski.org wrote:
 Hello,
 
 Ah, I didn't spot this. I only have:
 
 lift:Msgs showAll=true/
 
 which would suggest that it should show all errors.
 And anyway, why does it work then with normal form submit, and doesn't with 
 ajax form submit?
 
 Adam
 
 On Jan 4, 2010, at 9:14 PM, Ross Mellgren wrote:
 
 S.error(NodeSeq) and S.error(List[FieldError]) differ in that the  
 latter registers errors against particular fields, and the former is a  
 page-wide error. The latter is more like S.error(String, NodeSeq). Do  
 you have Msg snippets for each field, like this?
 
 ... field ... lift:msg id=my_field_id /
 
 (see net.liftweb.builtin.snippet.Msg for a better example)
 
 Hope that helps,
 -Ross
 
 On Jan 4, 2010, at 3:10 PM, Adam Warski wrote:
 
 Hello,
 
 investigating further making the tutorial form submittable with  
 ajax, I found some weird behavior; I'm using 1.1-M8.
 
 It seems that when the form is submitted with ajax, and there are  
 form validation errors, the error is not shown. However, the notices  
 work fine. So:
 - S.notice(Added +todo.desc); shows the notice after the ajax form  
 submit
 - S.error(xs); doesn't, only if the form is submitted in the regular  
 way
 
 I didn't manage to find the problem yet, but if instead of calling  
 S.error(xs); I do:
 xs.map {i = S.error(i.msg) };
 the error is shown.
 
 The error(n: NodeSeq)  and error(vi: List[FieldError]) don't seem to  
 differ a lot, but there must be something special about the second.
 
 I tried to reproduce the problem using a simple application, but  
 there I found  another strange thing.
 The app is:
 
 object Test {
 def main(args: Array[String]) {
   val z = new ListBuffer[String]
   object x extends RequestVar(z)
   x += a
 
   object y extends RequestVar(new ListBuffer[String])
   y += b
 
   println(x.is)
   println(y.is)
 }
 }
 
 and prints out:
 ListBuffer(a)
 ListBuffer()
 
 so for some reason, if the initial value of the RequestVar is passed  
 without an intermediate val, the list content isn't modified.
 But it could be that I'm using the RequestVar outside of it's  
 intended environment which may be the cause ;).
 
 --
 Adam
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en
 .
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 
 --
 
 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.
 
 

--

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.




Re: [Lift] Re: Errors not shown after AJAX form submit

2010-01-05 Thread Adam Warski
Ah so it's treated as a new request each time.
Clear now, thanks :)

Adam

On Jan 5, 2010, at 3:31 PM, Naftoli Gugenheim wrote:

 I don't know the exact reason, but the parameter to the RequestVar 
 constructor is a call by name, which means it's a function that can be 
 re-evaluated. Normally this value is recalculated at the start of each 
 request. In any case its seems that in your case they're being recalculated 
 and restored to before you modified them. However in the first case that 
 means referencing a variable that holds the change.
 
 -
 Adam Warskia...@warski.org wrote:
 
 Hello,
 
 I think the difference is in showAll scope. It was implemented for non
 Ajax context (just for msgs snippet) but it wasn't implemented for
 Ajax (as far as I can tell).
 
 Ajax notices (if there are any) are appended to user's JsCmd response.
 But this code has no idea about the showAll snippet attribute.
 Therefore ajax notices that are associates with an ID will not be
 shown in lift:Msgs showAll=true/ 's real estate.
 
 Please open a defect for this.
 I think I more or less understand :)
 Here's the defect: http://github.com/dpp/liftweb/issues/#issue/271
 
 By the way, do you have any idea why my example application produces such 
 weird results?
 I looked in the RequestVar code and didn't find anything there that would 
 make it behave differently in the two scenarios.
 
 Adam
 
 
 Br's,
 Marius
 
 On Jan 5, 9:37 am, Adam Warski a...@warski.org wrote:
 Hello,
 
 Ah, I didn't spot this. I only have:
 
 lift:Msgs showAll=true/
 
 which would suggest that it should show all errors.
 And anyway, why does it work then with normal form submit, and doesn't with 
 ajax form submit?
 
 Adam
 
 On Jan 4, 2010, at 9:14 PM, Ross Mellgren wrote:
 
 S.error(NodeSeq) and S.error(List[FieldError]) differ in that the  
 latter registers errors against particular fields, and the former is a  
 page-wide error. The latter is more like S.error(String, NodeSeq). Do  
 you have Msg snippets for each field, like this?
 
 ... field ... lift:msg id=my_field_id /
 
 (see net.liftweb.builtin.snippet.Msg for a better example)
 
 Hope that helps,
 -Ross
 
 On Jan 4, 2010, at 3:10 PM, Adam Warski wrote:
 
 Hello,
 
 investigating further making the tutorial form submittable with  
 ajax, I found some weird behavior; I'm using 1.1-M8.
 
 It seems that when the form is submitted with ajax, and there are  
 form validation errors, the error is not shown. However, the notices  
 work fine. So:
 - S.notice(Added +todo.desc); shows the notice after the ajax form  
 submit
 - S.error(xs); doesn't, only if the form is submitted in the regular  
 way
 
 I didn't manage to find the problem yet, but if instead of calling  
 S.error(xs); I do:
 xs.map {i = S.error(i.msg) };
 the error is shown.
 
 The error(n: NodeSeq)  and error(vi: List[FieldError]) don't seem to  
 differ a lot, but there must be something special about the second.
 
 I tried to reproduce the problem using a simple application, but  
 there I found  another strange thing.
 The app is:
 
 object Test {
 def main(args: Array[String]) {
  val z = new ListBuffer[String]
  object x extends RequestVar(z)
  x += a
 
  object y extends RequestVar(new ListBuffer[String])
  y += b
 
  println(x.is)
  println(y.is)
 }
 }
 
 and prints out:
 ListBuffer(a)
 ListBuffer()
 
 so for some reason, if the initial value of the RequestVar is passed  
 without an intermediate val, the list content isn't modified.
 But it could be that I'm using the RequestVar outside of it's  
 intended environment which may be the cause ;).
 
 --
 Adam
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en
 .
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 
 --
 
 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.
 
 
 
 --
 
 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

[Lift] Errors not shown after AJAX form submit

2010-01-04 Thread Adam Warski
Hello,

investigating further making the tutorial form submittable with ajax, I found 
some weird behavior; I'm using 1.1-M8.

It seems that when the form is submitted with ajax, and there are form 
validation errors, the error is not shown. However, the notices work fine. So:
- S.notice(Added +todo.desc); shows the notice after the ajax form submit
- S.error(xs); doesn't, only if the form is submitted in the regular way

I didn't manage to find the problem yet, but if instead of calling S.error(xs); 
I do:
xs.map {i = S.error(i.msg) };
the error is shown.

The error(n: NodeSeq)  and error(vi: List[FieldError]) don't seem to differ a 
lot, but there must be something special about the second.

I tried to reproduce the problem using a simple application, but there I found  
another strange thing.
The app is:

object Test {
  def main(args: Array[String]) {
val z = new ListBuffer[String]
object x extends RequestVar(z)
x += a

object y extends RequestVar(new ListBuffer[String])
y += b

println(x.is)
println(y.is)
  }
}

and prints out:
ListBuffer(a)
ListBuffer()

so for some reason, if the initial value of the RequestVar is passed without an 
intermediate val, the list content isn't modified.
But it could be that I'm using the RequestVar outside of it's intended 
environment which may be the cause ;).

-- 
Adam

--

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.




Re: [Lift] Errors not shown after AJAX form submit

2010-01-04 Thread Adam Warski
Hello,

Ah, I didn't spot this. I only have:

lift:Msgs showAll=true/

which would suggest that it should show all errors. 
And anyway, why does it work then with normal form submit, and doesn't with 
ajax form submit?

Adam

On Jan 4, 2010, at 9:14 PM, Ross Mellgren wrote:

 S.error(NodeSeq) and S.error(List[FieldError]) differ in that the  
 latter registers errors against particular fields, and the former is a  
 page-wide error. The latter is more like S.error(String, NodeSeq). Do  
 you have Msg snippets for each field, like this?
 
 ... field ... lift:msg id=my_field_id /
 
 (see net.liftweb.builtin.snippet.Msg for a better example)
 
 Hope that helps,
 -Ross
 
 On Jan 4, 2010, at 3:10 PM, Adam Warski wrote:
 
 Hello,
 
 investigating further making the tutorial form submittable with  
 ajax, I found some weird behavior; I'm using 1.1-M8.
 
 It seems that when the form is submitted with ajax, and there are  
 form validation errors, the error is not shown. However, the notices  
 work fine. So:
 - S.notice(Added +todo.desc); shows the notice after the ajax form  
 submit
 - S.error(xs); doesn't, only if the form is submitted in the regular  
 way
 
 I didn't manage to find the problem yet, but if instead of calling  
 S.error(xs); I do:
 xs.map {i = S.error(i.msg) };
 the error is shown.
 
 The error(n: NodeSeq)  and error(vi: List[FieldError]) don't seem to  
 differ a lot, but there must be something special about the second.
 
 I tried to reproduce the problem using a simple application, but  
 there I found  another strange thing.
 The app is:
 
 object Test {
 def main(args: Array[String]) {
   val z = new ListBuffer[String]
   object x extends RequestVar(z)
   x += a
 
   object y extends RequestVar(new ListBuffer[String])
   y += b
 
   println(x.is)
   println(y.is)
 }
 }
 
 and prints out:
 ListBuffer(a)
 ListBuffer()
 
 so for some reason, if the initial value of the RequestVar is passed  
 without an intermediate val, the list content isn't modified.
 But it could be that I'm using the RequestVar outside of it's  
 intended environment which may be the cause ;).
 
 -- 
 Adam
 
 --
 
 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 
 .
 
 
 
 --
 
 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.
 
 

--

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.




Re: [Lift] Re: Snippet lifetime

2009-12-29 Thread Adam Warski
Hello,

 Well for changing the tutorial form into an ajax form I guess the best 
 solution is to store the model instance in a RequestVar and simply set it to 
 a new instance after saving. So I don't have any immediate use-cases.
 
 But in other (Seam) projects I remember that I used the event scope 
 (corresponding to TransientRequestVar) quite often, for example to have a 
 single-request cache (things which may be invalidated even on the next ajax 
 request).
 
 Also, I suppose that you need to hold a reference to all RequestVars as long 
 as the user doesn't request another page, or as long as his session doesn't 
 time out. You don't know if the page will make ajax callbacks or not, right?
 
 Sure we know since Lift's ajax functions that have bound Scala
 functions are inherently kept on the LiftSession. RequestVar's are
 preserved (and not only them) by a mechanism that we call snaphot-
 restorer which simply based on Scala's reference capturing.

Right, but still, you don't know which variables are going to be used, so you 
need to keep them all. So if a page doesn't use ajax RequestVars are 
dereferenced right after the http request finishes?

 And even if you knew, you wouldn't know if the callbacks are going to use 
 the vars. So potentially there may be a memory problem. I would expect 
 request vars to be a bit lighter (a TransientRequestVar can be discarded 
 right after the request processing finished).
 
 I really doubt the memory is an issue here. The amount of RequestVars
 used is typically quite low.

Typically - yes, but I can bet there will be usages which will require a lot of 
them. I would not close the possibility for developers to decide if they want 
to store a variable in the real/transient request scope or in the page/request 
scope just because typically users want page/request scope variables. Maybe 
this should be the default, but certainly not the only option.

 Keep in mind that bound functions are subject to a garbage collection
 mechanism built in Lift. You may have noticed periodical __lift_GC__
 Ajax request being sent from browser. This is a lease mechanism. So if
 bound functions are not revitalized they will expire and will be
 removed.

I'll have to read up on how Lift handles this, I guess there was a chapter in 
the book :)

-- 
Adam

--

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.




Re: [Lift] Re: Snippet lifetime

2009-12-29 Thread Adam Warski
Hello,

 That's true in practice. The implementation of those methods however are 
 equivalent to the S and SHtml versions except for the call to 
 registerThisSnippet. But if Lift will sometimes remember even ordinary class 
 instances as reusable snippets then why should the API for managing reused 
 snippets be  exclusive to StatefulSnippets?
 Why was this changed made, first of all? Why take away the flexibility to 
 choose to use multiple instances of a class on the same page? And was a 
 Breaking Change email sent out?
 If all snippets get placed in a RequestVar is there still a purpose in using 
 RequestVars within a snippet?
 Another question I never got around to asking: Why does StatefulSnippet 
 extend DispatchSnippet?

I can only agree here. I'm quite new to Lift, but properties like if a snippet 
uses dispatch instead of reflection (= provides a dispatch methods) or if its 
instances can survive longer than a single http request (like StatefulSnippets 
or reflection snipptes right now) look like perfect candidates for traits. The 
developer would just then decide which traits to mix into his snippet, and then 
he would have exact control on how the snippets behave and what is their 
lifecycle.

By the way, I find the names RequestVar and TransientRequestVar confusing also, 
but maybe that's because I come from a JEE/Seam background, where normally the 
Page/Request terminology is used. I don't know what names are used e.g. in RoR?

-- 
Adam

--

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.




Re: [Lift] Snippet lifetime

2009-12-29 Thread Adam Warski
Hello,

 Yes, the article is out of date now... Lift now makes sure that multiple 
 references to a single snippet in the same request context use the same 
 instance of that snippet.

I've updated the wiki page a bit: 
http://wiki.github.com/dpp/liftweb/about-snippets, if some lift gurus would 
want to review.
So far it lists the following snippet kinds:
* reflection
* dispatch
* singleton dispatch
* stateful

I'm not sure if there are any other, but if there are, maybe somebody could 
mention them there, so that people would be at least aware of their existence 
and look up in the source code later.

-- 
Adam

--

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.




Re: [Lift] Re: Snippet lifetime

2009-12-29 Thread Adam Warski
Hello,

 These are the names we use in Lift - appreciate what your saying, but its not 
 confusing IMHO, just different to other things you are used to. Lift is Lift, 
 not RoR, or Seam, or any other framework ;-)

Sure, it's just a simple terminology switch, I don't really mind if they are 
named one way or the other. The only objection I would have is that I would 
make TransientRequestVar public, and, as Naftoli wrote, 
statefullness/dispatching a trait.

-- 
Adam

--

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.




[Lift] Snippet lifetime

2009-12-28 Thread Adam Warski
Hello,

on the wiki page about reflection snippets 
(http://wiki.github.com/dpp/liftweb/about-snippets), it is written:

Every time you call the reflection snippet in your markup code, a new instance 
is instantiated and the appropriate method invoked

However this doesn't seem to be true (I'm using 1.1-M8). I have modified the 
example in the tutorial to use ajax to submit the form (as Marius and others 
advised me in another thread), and I discovered that after I add an item, then 
try to add another one, the first one is modified, which would mean that the 
same snippet instance is used (the snippet - TD - is a reflection snippet, as 
far as I understand the terminology).

That would mean that reflection snippets have the same scope as RequestVars, 
that is that there's at most one instance per rendered page. Marius wrote that 
this changes recently, so maybe it's a side-effect?

Also, do you think that RequestVar is a good name? For me it suggests a 
variable which has a lifecycle only for one http request. In the Seam 
framework, for example, there are two scopes: request and page (and many 
others), the first one being a true request scope, the second having 
essentially the same scope as RequestVar. So maybe it should be called PageVar?

-- 
Adam

--

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.




Re: [Lift] Snippet lifetime

2009-12-28 Thread Adam Warski
Hello,

 Yes, the article is out of date now... Lift now makes sure that multiple 
 references to a single snippet in the same request context use the same 
 instance of that snippet.
I see, so the rationale behind using dispatch snippets is out of date also. 
Except that you save one reflection call per page/request. So are there any 
reasons to use DispatchSnippets now?

 Reflection snippets do not have the same scope as request vars... rather, the 
 snippet is held in a request var.
Which essentialy makes them have the same scope as request vars :)

By the way, is there a true request-scope variable? I saw that there's 
TransientRequestVar, but it's private in the liftweb package.

Adam

 Cheers, Tim
 
 On 28 Dec 2009, at 14:33, Adam Warski wrote:
 
 Hello,
 
 on the wiki page about reflection snippets 
 (http://wiki.github.com/dpp/liftweb/about-snippets), it is written:
 
 Every time you call the reflection snippet in your markup code, a new 
 instance is instantiated and the appropriate method invoked
 
 However this doesn't seem to be true (I'm using 1.1-M8). I have modified the 
 example in the tutorial to use ajax to submit the form (as Marius and others 
 advised me in another thread), and I discovered that after I add an item, 
 then try to add another one, the first one is modified, which would mean 
 that the same snippet instance is used (the snippet - TD - is a reflection 
 snippet, as far as I understand the terminology).
 
 That would mean that reflection snippets have the same scope as RequestVars, 
 that is that there's at most one instance per rendered page. Marius wrote 
 that this changes recently, so maybe it's a side-effect?
 
 Also, do you think that RequestVar is a good name? For me it suggests a 
 variable which has a lifecycle only for one http request. In the Seam 
 framework, for example, there are two scopes: request and page (and many 
 others), the first one being a true request scope, the second having 
 essentially the same scope as RequestVar. So maybe it should be called 
 PageVar?
 
 -- 
 Adam
 
 --
 
 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.
 
 
 
 
 --
 
 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.
 
 

--

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.




Re: [Lift] Re: Snippet lifetime

2009-12-28 Thread Adam Warski
Hello,

 RequestVar-s lifetime is expanded beyond the actual request, which is
 not applicable for TransientRequestVar. For instance say you have a
 page and you set some state on a RequestVar ... then you render an
 Ajax link. After the page is rendered, when your ajax function is
 invoked, you RequestVar state set when rendering the page is still
 visible.
 
 But is there is problem you're chasing or is it just terminology?
I understand the difference; and I think the terminology is a bit misleading. 
But right now I have two questions:

1) Can I have in lift a true request variable/snippet, that is such which has 
a lifetime of one request (without any ajax callbacks)? I can't use 
TransientRequestVar because it's private. It would be useful to complete my 
ajax-form example (after an item is saved, a new one should be used; I guess I 
could just store the model instance in a RequestVar and set it to a new object 
after saving, but maybe there's a nicer way).

2) Why would one want to use DispatchSnippets? The wiki says they are better 
because they are not instantiated whenever a tag is occurred. But right now, 
reflection snippets also aren't - they are instantiated at most once per 
request.

 Br's,
 Marius
 
 On Dec 28, 6:04 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 Yes, the article is out of date now... Lift now makes sure that multiple 
 references to a single snippet in the same request context use the same 
 instance of that snippet.
 
 I see, so the rationale behind using dispatch snippets is out of date also. 
 Except that you save one reflection call per page/request. So are there any 
 reasons to use DispatchSnippets now?
 
 Reflection snippets do not have the same scope as request vars... rather, 
 the snippet is held in a request var.
 
 Which essentialy makes them have the same scope as request vars :)
 
 By the way, is there a true request-scope variable? I saw that there's 
 TransientRequestVar, but it's private in the liftweb package.
 
 Adam
 
 Cheers, Tim
 
 On 28 Dec 2009, at 14:33, Adam Warski wrote:
 
 Hello,
 
 on the wiki page about reflection snippets 
 (http://wiki.github.com/dpp/liftweb/about-snippets), it is written:
 
 Every time you call the reflection snippet in your markup code, a new 
 instance is instantiated and the appropriate method invoked
 
 However this doesn't seem to be true (I'm using 1.1-M8). I have modified 
 the example in the tutorial to use ajax to submit the form (as Marius and 
 others advised me in another thread), and I discovered that after I add an 
 item, then try to add another one, the first one is modified, which would 
 mean that the same snippet instance is used (the snippet - TD - is a 
 reflection snippet, as far as I understand the terminology).
 
 That would mean that reflection snippets have the same scope as 
 RequestVars, that is that there's at most one instance per rendered page. 
 Marius wrote that this changes recently, so maybe it's a side-effect?
 
 Also, do you think that RequestVar is a good name? For me it suggests a 
 variable which has a lifecycle only for one http request. In the Seam 
 framework, for example, there are two scopes: request and page (and many 
 others), the first one being a true request scope, the second having 
 essentially the same scope as RequestVar. So maybe it should be called 
 PageVar?
 
 --
 Adam
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 
 --
 
 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 
 athttp://groups.google.com/group/liftweb?hl=en.
 
 --
 
 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.
 
 

--

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.




Re: [Lift] Snippet lifetime

2009-12-28 Thread Adam Warski
 
  Yes, the article is out of date now... Lift now makes sure that multiple 
  references to a single snippet in the same request context use the same 
  instance of that snippet.
 I see, so the rationale behind using dispatch snippets is out of date also. 
 Except that you save one reflection call per page/request. So are there any 
 reasons to use DispatchSnippets now?
 
 DispatchSnippets support dynamic dispatch:  you can change how tags are 
 dispatched based on some state.
 
 With (reflection-based) snippets, there's a direct binding between the tag 
 and the class name + method.  Well, unless you override 
 LiftRules.snippetDispatch.
Ah right. Thanks. I'll modify the wiki once I gather all the answers :)

Adam

--

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.




Re: [Lift] Re: Snippet lifetime

2009-12-28 Thread Adam Warski
Hello,

 1) Can I have in lift a true request variable/snippet, that is such which 
 has a lifetime of one request (without any ajax callbacks)? I can't use 
 TransientRequestVar because it's private. It would be useful to complete my 
 ajax-form example (after an item is saved, a new one should be used; I guess 
 I could just store the model instance in a RequestVar and set it to a new 
 object after saving, but maybe there's a nicer way).
 
 TransientRequestVar could technically be made public but I don't see
 compelling reasons to do that (yet). Do you need to do some logic
 right before sending down the response? What is your use-case?
Well for changing the tutorial form into an ajax form I guess the best solution 
is to store the model instance in a RequestVar and simply set it to a new 
instance after saving. So I don't have any immediate use-cases.

But in other (Seam) projects I remember that I used the event scope 
(corresponding to TransientRequestVar) quite often, for example to have a 
single-request cache (things which may be invalidated even on the next ajax 
request).

Also, I suppose that you need to hold a reference to all RequestVars as long as 
the user doesn't request another page, or as long as his session doesn't time 
out. You don't know if the page will make ajax callbacks or not, right? And 
even if you knew, you wouldn't know if the callbacks are going to use the vars. 
So potentially there may be a memory problem. I would expect request vars to be 
a bit lighter (a TransientRequestVar can be discarded right after the request 
processing finished).

-- 
Adam

--

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.




Re: [Lift] Re: Duplicate divs in tutorial

2009-12-24 Thread Adam Warski
Heh, of course :)
Can you (or somebody else) fix Listing 12 in the tutorial then?

Adam

On Dec 23, 2009, at 11:19 PM, Marius wrote:

 Why not something like:
 
 div id=all_todos
 lift:TD.list all_id=all_todos
...
 /lift:TD.list
 /div
 
 
 Br's,
 Marius
 
 On Dec 23, 11:46 pm, Adam Warski a...@warski.org wrote:
 Hello,
 
 just a note to the snippets written in the tutorial. The elements of the 
 todo list, when changed (e.g. the done checkbox), submit and redraw the 
 list. The code for that is (Listing 17):
 
 def list(html: NodeSeq) = {
  val id = S.attr(all_id).open_!
 
  def inner(): NodeSeq = {
def reDraw() = SetHtml(id, inner())
 
bind(todo, html,
   exclude -
 ajaxCheckbox(QueryNotDone, v = {QueryNotDone(v); reDraw}),
   list - doList(reDraw) _)
  }
 
  inner()
 
 }
 
 And the corresponding template:
 
 lift:TD.list all_id=all_todos
  div id=all_todos
!-- proper list --
  /div
 /lift:TD.list
 
 As SetHtml sets the children of the element with the specified id, after one 
 change of the checkbox and one ajax call, there will be a div 
 id=all_todos inside the original div id=all_todos (as we set the 
 children of the original element to be the nodes passed to the snippet). So 
 you end up with:
 
 lift:TD.list all_id=all_todos
  div id=all_todos  
div id=all_todos
  !-- proper list --
/div
  /div
 /lift:TD.list
 
 Subsequent calls don't produce any more divs, as the children of the first 
 div with id all_todos get replaced. However, I think it's not too clean 
 to produce markup like that.
 The solution I think would be to (somehow) strip the outer div of the html 
 NodeSeq and use that in the ajax reDraw method, instead of capturing the 
 original html with a closure.
 But probably Lift gurus have a better solution :).
 
 --
 Adam
 
 --
 
 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.
 
 

--

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.




[Lift] Beginner Ajax question - redrawing a page fragment

2009-12-23 Thread Adam Warski
Hello,

I'm just starting with Lift, and there's one thing I can't figure out. I want 
to modify the ToDo example from the tutorial so that the Add button makes an 
ajax call, adds the element to a list and displays the modified result.

The problem is that I don't know how to redraw the list after the button has 
been pressed. More generally: how to redraw a page fragment with ajax? I could 
do that with SetHtml if I had the NodeSeq corresponding to the list, but the 
button is in an unrelated page fragment so it doesn't have it. What's the 
Lift way to solve such problems?

The page roughly is:

lift:TD.add form=post
!-- fields an submit button bound here --
/lift:TD.add

!-- some other code --

!-- the list that I want to redraw --
lift:TD.list all_id=all_todos
...
/lift:TD.list

I was looking through the list archive but didn't find anything. Sorry if it's 
a repeated question :)

-- 
Adam

--

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.




Re: [Lift] Re: Beginner Ajax question - redrawing a page fragment

2009-12-23 Thread Adam Warski
Hello,

 With SetHtml you just provide the parent element ID and the NodeSeq
 you want to render as a child of that parent. You're saying you don;t
 have the NodeSeq Corresponding to the List but I assume you do have
 the list right? So assume this Ajax function:
 
 def myCallback(): JsCmd = {
 val myList = ...
 
 val html: NodeSeq = myList.flatMap(e = td{e toString}/td)
 
 SetHtml(all_todos, html)
 
 }
But then I'm embedding view logic into the code - I wouldn't really want to do 
that. Especially once the list becomes anything more fancy then a simple table, 
I think putting the list-displaying into an html file better.

I tried doing something else, expanding your idea.
I've put the list-displaying html markup into a template (todo_list.html), so 
now I can reuse it to both display the list and pass it to the snippet which 
handles and binds the form:

Now my form looks like this:

lift:TD.add form=post
addForm:form
  !-- fields and submit button bound here --
/addForm:form
addForm:list
  lift:embed what=todo_list /
/addForm:list
/lift:TD.add

!-- some other code --

!-- the list that I want to redraw --
lift:embed what=todo_list /

In TD.add I have then:
...
def drawList() = list(chooseTemplate(addForm, list, form))
def reDraw() = SetHtml(all_todos, drawList())

bind(todo, chooseTemplate(addForm, form, form),
priority - todo.priority.toForm,
desc - todo.desc.toForm,
submit - submit(New, checkAndSave))
)
...

Is this the right way to go? And is it the lift way?

Anyway I can't test it yet because I can't get my form to be submitted with 
ajax. Both surrounding the bind with SHtml.ajaxForm(...) and replacing submit 
with ajaxButton causes the form to stop working (the values in the model aren't 
updated).

Adam

 Br's,
 Marius
 
 On Dec 23, 10:32 am, Adam Warski a...@warski.org wrote:
 Hello,
 
 I'm just starting with Lift, and there's one thing I can't figure out. I 
 want to modify the ToDo example from the tutorial so that the Add button 
 makes an ajax call, adds the element to a list and displays the modified 
 result.
 
 The problem is that I don't know how to redraw the list after the button has 
 been pressed. More generally: how to redraw a page fragment with ajax? I 
 could do that with SetHtml if I had the NodeSeq corresponding to the list, 
 but the button is in an unrelated page fragment so it doesn't have it. 
 What's the Lift way to solve such problems?
 
 The page roughly is:
 
 lift:TD.add form=post
 !-- fields an submit button bound here --
 /lift:TD.add
 
 !-- some other code --
 
 !-- the list that I want to redraw --
 lift:TD.list all_id=all_todos
 ...
 /lift:TD.list
 
 I was looking through the list archive but didn't find anything. Sorry if 
 it's a repeated question :)
 
 --
 Adam
 
 --
 
 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.
 
 

--

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.




Re: [Lift] Re: Beginner Ajax question - redrawing a page fragment

2009-12-23 Thread Adam Warski
Hello,

 object MyMarkupVar extends RequestVar[NodeSeq](NodeSeq.empty)

ah, that's much better then my solution. Thanks! :)

Maybe you could also write, how to submit a whole form using AJAX? :) So far my 
attempts are futile.
I get an ajax request, but the value of the field isn't bound to the model.

Code of my snippet, without ajax (works):
bind(todo, chooseTemplate(addForm, form, form),
  desc - todo.desc.toForm,
  submit - submit(New, checkAndSave))
)

With ajax (doesn't work):
ajaxForm(
bind(todo, chooseTemplate(addForm, form, form),
  desc - todo.desc.toForm,
  submit - submit(New, checkAndSave))
)

Or:
bind(todo, chooseTemplate(addForm, form, form),
  desc - todo.desc.toForm,
  submit - ajaxButton(New, () = {checkAndSave; reDraw()}))
)

-- 
Adam

--

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.




Re: [Lift] Re: Beginner Ajax question - redrawing a page fragment

2009-12-23 Thread Adam Warski
Hello,

 A couple of observations...
 
 First, having some XHTML in your Scala code is not a bad thing.  When the 
 XHTML declares the meaning (not the layout) of the information, it's my 
 opinion that it's okay.  This means that:
 ul{list.map(i = li{i}/li}ul
 Simply defines an unordered list.  It does not declare how to lay out that 
 list.  The layout should be controlled by CSS.
True, xhtml can also be considered as logic. You got me convinced ;).

   TemplateFinder.findAnyTemplate(List(snippets-hidden, userList)) 
 openOr NodeSeq.Empty)
Worked great; lots of Lift API to explore still :).

If you don't mind, I'll put the results of this thread in a 
tutorial-ajax-followup wiki page? I think quite a lot of people may want to 
do something similar.

-- 
Adam

--

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.