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

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.