Still a semi-newbie, but so far I''ve managed to solve most things with a bit of help from the Agile book, some googling around, and a bit of trial-and-error, but I''m really stuck with this one (very much an Ajax newbie): I know how to gracefully degrade an AJAX newpost type call so it can appear inline or (for those without JS support) go to a new page (put an ":href => url_for" in the link_to_remote). I also know how to DRY up two (non-AJAX) actions so that you use the same newpost for both the original call and processing the form info (if request.get? ... elsif request.post?). I even know how to have it so the same newpost action can handle the original request and tell if it''s an AJAX request or not, so I can use just one action for AJAX and none AJAX requests (request..xml_http_request?). What I can''t work out to do is how to have it so the processing of the AJAX a form info is done in the same action as the original AJAX call (they are both posts, right?), and it''s forcing me to have a createpost action, just for the AJAX route. If I could work this out, I could then have one neat action that wrapped the whole thing up in a nice DRY, gracefully degrading way. Can anyone help? Thanks Chris T
Rob Biedenharn
2006-Apr-01  15:52 UTC
[Rails] Gracefully degrading Ajax AND Drying up actions
On Apr 1, 2006, at 5:34 AM, Chris T wrote:> Still a semi-newbie, but so far I''ve managed to solve most things > with a bit of help from the Agile book, some googling around, and a > bit of trial-and-error, but I''m really stuck with this one (very > much an Ajax newbie): > > I know how to gracefully degrade an AJAX newpost type call so it > can appear inline or (for those without JS support) go to a new > page (put an ":href => url_for" in the link_to_remote). > > I also know how to DRY up two (non-AJAX) actions so that you use > the same newpost for both the original call and processing the form > info (if request.get? ... elsif request.post?). > > I even know how to have it so the same newpost action can handle > the original request and tell if it''s an AJAX request or not, so I > can use just one action for AJAX and none AJAX requests > (request..xml_http_request?). > > What I can''t work out to do is how to have it so the processing of > the AJAX a form info is done in the same action as the original > AJAX call (they are both posts, right?), and it''s forcing me to > have a createpost action, just for the AJAX route.Are you testing request.xhr? *before* you test for request.post? If not, switch them around (or say "request.post? && ! request.xhr?") since all xhr? posts are, of course, posts! -Rob Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com> If I could work this out, I could then have one neat action that > wrapped the whole thing up in a nice DRY, gracefully degrading way. > > Can anyone help? > > Thanks > Chris T
Rob Biedenharn wrote:> On Apr 1, 2006, at 5:34 AM, Chris T wrote: > >> Still a semi-newbie, but so far I''ve managed to solve most things >> with a bit of help from the Agile book, some googling around, and a >> bit of trial-and-error, but I''m really stuck with this one (very much >> an Ajax newbie): >> >> I know how to gracefully degrade an AJAX newpost type call so it can >> appear inline or (for those without JS support) go to a new page (put >> an ":href => url_for" in the link_to_remote). >> >> I also know how to DRY up two (non-AJAX) actions so that you use the >> same newpost for both the original call and processing the form info >> (if request.get? ... elsif request.post?). >> >> I even know how to have it so the same newpost action can handle the >> original request and tell if it''s an AJAX request or not, so I can >> use just one action for AJAX and none AJAX requests >> (request..xml_http_request?). >> >> What I can''t work out to do is how to have it so the processing of >> the AJAX a form info is done in the same action as the original AJAX >> call (they are both posts, right?), and it''s forcing me to have a >> createpost action, just for the AJAX route. > > Are you testing request.xhr? *before* you test for request.post? > > If not, switch them around (or say "request.post? && ! request.xhr?") > since all xhr? posts are, of course, posts! > > -Rob > > Rob Biedenharn http://agileconsultingllc.com > Rob@AgileConsultingLLC.com >The problem is not differentiating between the non-xhr posts and xhr posts (the order I''ve got it currently is: test for gets, else test for xhr, else test for post, which I *think* has the same effect) but testing between the xhr posts that are the original call (i.e. the equivalent of the non-Ajax GET) and those that are returning form values. I suspect I''m being dense here, but can''t figure it out. It''s simple if I have a new post and create post action -- then on each I only need to test xhr? -- and this avoids duplicating the codes for xhr and non-xhr, but does mean two actions. Not the end of the world, but would be nice to know if it''s easy to do (and therefore I am being dense). Cheers Chris
Solved this -- of a fashion, though the code is somewhat ugly at the 
moment so I''m not convinced I''m doing it the best way:
def newpost  # NB somewhat simplified to remove some of the non-logic bits
    if request.get? # tests if non-Ajax GET request in which case...
    ...... # generate new object
    return
    elsif request.xml_http_request? # tests if Ajax request
      if not params[:post] # could prob bundle this up in Ajax test above
        .... # generate new object for Ajax calls
      end
    end
   @post=Post.new(params[:post]) #get the params, whether they came from 
Ajax or non-Ajax call
    if @post.save
        flash[:notice] = "New post submitted successfully"
        if not request.xml_http_request? # plain old vanilla non-Ajax
           redirect_to :action => ''index'' and return
        else
              render(:partial => ''post'', :object =>
@post, :layout =>
false) # show the new item for Ajax
        end
    elsif request.xml_http_request? # if we haven''t saved successfully 
and it was an Ajax call
      render :action => ''newpost'', :id => params[:id],
:layout => false
and return # re-show form
    else
      render :action => ''newpost'', :id => params[:id]
and return # ditto
for non-Ajax call
    end
end
Comments or suggestions for improving this?
Thanks
Chris T
Rob Biedenharn wrote:> On Apr 1, 2006, at 5:34 AM, Chris T wrote:
>
>> Still a semi-newbie, but so far I''ve managed to solve most
things
>> with a bit of help from the Agile book, some googling around, and a 
>> bit of trial-and-error, but I''m really stuck with this one
(very much
>> an Ajax newbie):
>>
>> I know how to gracefully degrade an AJAX newpost type call so it can 
>> appear inline or (for those without JS support) go to a new page (put 
>> an ":href => url_for" in the link_to_remote).
>>
>> I also know how to DRY up two (non-AJAX) actions so that you use the 
>> same newpost for both the original call and processing the form info 
>> (if request.get? ... elsif request.post?).
>>
>> I even know how to have it so the same newpost action can handle the 
>> original request and tell if it''s an AJAX request or not, so I
can
>> use just one action for AJAX and none AJAX requests 
>> (request..xml_http_request?).
>>
>> What I can''t work out to do is how to have it so the
processing of
>> the AJAX a form info is done in the same action as the original AJAX 
>> call (they are both posts, right?), and it''s forcing me to
have a
>> createpost action, just for the AJAX route.
>
> Are you testing request.xhr? *before* you test for request.post?
>
> If not, switch them around (or say "request.post? && !
request.xhr?")
> since all xhr? posts are, of course, posts!
>
> -Rob
>
> Rob Biedenharn        http://agileconsultingllc.com
> Rob@AgileConsultingLLC.com
>
>> If I could work this out, I could then have one neat action that 
>> wrapped the whole thing up in a nice DRY, gracefully degrading way.
>>
>> Can anyone help?
>>
>> Thanks
>> Chris T
>
>