Issues implementing ajax for the config for Rails 2.0.2 and Ruby 1.8.7. Jquery/Scriptaculous/Prototy

Hello all,

I am trying to render via javascript a post and an image in my rails
app. My app has the config of Ruby 1.8.7 and Rails 2.0.2 .

With great difficulty I have found a suitable version of paperclip(
https://github.com/thoughtbot/paperclip/commit/d177c8f838458348a9f4d1fe41918c5bd99a989c
) to meet the above config requirements.

Earlier before integrating image upload feature in my app for each post,
post message where being rendered via javascript using AJAX with Jquery
1.4 . This stopped working when I had try to implement uploading images
in my app using paperclip... I request you to please look into this for
details of the same:-
http://stackoverflow.com/questions/6070510/unable-to-figure-out-why-a-photo-attribute-of-the-paperclip-plugin-is-not-being-p
.

From this experience I have been able to in a way infer I need to find
an appropriate paperclip version suiting my requirements... unless..
they could be other ways to deal with this situation.. If so.. It would
be great if you could enlighten me on the same...

Going forward I have the following options with me:-

1. Find a suitable paperclip plugin which would have support for AJAX
using Jquery. (I am really not too sure on how I would be doing this..)

2. Try using scriptaculous and/or prototype( I am unsure on whether I
need to use either or both of them ). The concern with this is , I have
to implement this from the scratch and I have to figure out from scratch
how to go about the same and also the fact that Ajax using Jquery
already works for me with post and not with post + Image.

I would like to add some details(code, other points) wrt option 1 wrt
the problem I am currently facing:-

I have used option 1 with the help of the Railscast by Ryan
Bates(http://railscasts.com/episodes/136-jquery).

I have made appropriate modifications referring to the same..
The file that I am trying to render via JS is post_message.js.erb looks
like this..

    <!--$("#new_post").before('<div id ="new_post"><%=
escape_javascript(flash.delete(:notice)) %></div>'); TO-DO the flash
messages aren't yet enabled/working completely for now.. -->
    <!--$("#latest_post").before('<div id ="latest_post"><%=
escape_javascript(flash.delete(:notice)) %></div>');-->
    $("#latest_post").prepend("<br/> <%= image_tag
@group_post.avatar.url(:thumb) %> <%= @group_post.message %> by <%=
Investor.find(@group_post.post_by).first_name %> <div
class=contentdispgrp> <%=
distance_of_time_in_words(@group_post.created_at,Time.now) %> ago</div>
<br/><br/><hr/>");
    $("#latest_post").append("<br/> <%for a in @group_all_posts %> <%=
image_tag a.avatar.url(:thumb) %> <%= a.message %> by <%=
Investor.find(a.post_by).first_name %> <div class=contentdispgrp> <%=
distance_of_time_in_words(a.created_at,Time.now) %> ago</div>
<br/><br/><hr/><%end%>");
    $('#post_msg input').val('');

I am very much a novice with Jquery and hardly have around 3-4 months of
experience with RoR, I have one doubt over here if one could help me
clarify..If you have read
http://stackoverflow.com/questions/6070510/unable-to-figure-out-why-a-photo-attribute-of-the-paperclip-plugin-is-not-being-p
, you would observe by just removing the `:id => 'new_post'` from within
the `:html` symbol stopped the .js.erb from being rendered..

My doubt is I am pretty much unclear and lack knowledge on exactly what
role is the id
"new_post" playing.. when I have actually commented the same.. in my
post_message.js.erb.. It might be that the id is used to uniquely
identlify the HTML partial that is being rendered.. in which I
currently have the part of the code taking the parameters of the image
and the message along with it... Not too sure.. Or is there any other
side to it ...If so kindly widen my horizon on the same..

The part of the file(this is a partial) which otherwise gets rendered
via HTML has the following code in it:-

    <%form_for :group_post, @group_post, :url => {:action =>
:post_message, :id => params[:id]},:html => {:multipart => true}, :id =>
'new_post' do |f| %>
        Start Discussion:<%=f.text_field :message%>
       <%= f.file_field :avatar %>
       <%=f.submit "Post" %>
      <%end%>

    <div id = "latest_post"> </div>
    <%for a in @group_all_posts %>
      <%if !a.avatar_file_name.to_s.empty? %>
      <br/><%= image_tag a.avatar.url(:thumb) %>
      <%end%>
    <br/><%= a.message %> <br/> by <%=
Investor.find(a.post_by).first_name %> <div class ="contentdispgrp"
id="style_chck"> <%= distance_of_time_in_words(a.created_at,Time.now)
%> ago </div><br/><br/> <hr/>

My post_message method in my controller looks like this:-

     def post_message
        @group_post = GroupPost.new(params[:group_post])
        #@group_comment = GroupComment.new(params[:group_comment])

        @investor_group = InvestorGroup.find(params[:id])
        @group_post.investor_group_id = @investor_group.id
        investor_id = session['investor_id']
        @group_post.post_by = investor_id
        if !@group_post.message.blank?
           @group_post.save
           flash[:notice] = 'Post was successfully created.'
        else
          flash[:notice] = 'Post was not successfully created. Post
can\'t be blank'
        end
    # @group_comment.comment_by = investor_id
    # @group_comment.group_post_id = :post_id

Hello all,

I am trying to render via javascript a post and an image in my rails
app. My app has the config of Ruby 1.8.7 and Rails 2.0.2 .

With great difficulty I have found a suitable version of paperclip(https://github.com/thoughtbot/paperclip/commit/d177c8f838458348a9f4d1
) to meet the above config requirements.

Earlier before integrating image upload feature in my app for each post,
post message where being rendered via javascript using AJAX with Jquery
1.4 . This stopped working when I had try to implement uploading images
in my app using paperclip… I request you to please look into this for
details of the same:-http://stackoverflow.com/questions/6070510/unable-to-figure-out-why-a
.

Traditionally, a straight up ajax form can't upload files: when using
ajax a piece of javascript serializes the form and sends the request
to the server and javascript running inside the browser doesn't have
access to the filesystem.

The illusion of an ajax file upload can be provided by having the file
upload happen inside a hidden iframe, there are plenty of articles
describing how this works (and probably several jquery plugins
implementing it). Other options involve using flash for the upload

The file-api specification (http://www.w3.org/TR/file-upload/) does
add the ability for javascript to access the filesystem but not all
browsers currently support this

Fred

Hello Fred,

Thanks for your enlightening inputs...

I am sorry if some part of my question made you say/infer that what I am
trying ask is upload an image via AJAX..
What I exactly meant to say..is after I am fetching an image from the
filesystem.. How can i display the same onclick of a button without
making/getting the entire page to reload.. May be it would require that
I somewhere make use of a partial.. The question here is where and
how...in case this is the right option or if it isn't... is there
another way to deal with this.. I have no issues with only that
portion/section of the file reloading in which the most recent image and
message is posted, the other images with post should be able to be
fetched and displayed without the entire page reloading is what I am
basically trying to get working for me...this is actually working for me
for each post alone.. but not post+image.. I hope your now better able
to understand what I'm exactly looking for..

[Update in ORIGINAL QUESTION]
I would like to add Paperclip and Jquery have nothing to do with each
other..(based on inputs I could gather from people on other forums).
This piece of information would really help....but..

In my case they both to work separately use something in common to the
html symbol..As a result I have been able to get them both working
separately.. but not yet together.. Please find below the details of
what exactly is common among them and what separates the two based on my
observation

Firstly in order to get posting of message to work for me with AJAX, i
had to apart from adding several change elsewhere also make sure that
within my _common.html.erb partial view I add an :id => 'with_some_name'
within my html symbol. Something like this:-
:html => { :multipart => :true , :id => 'new_post'} within my form_for
tag.. Now why exactly this works this way.. I haven't yet figured out
and I am researching on the same..

So this basically was working fine until I had integrated uploading of
images feature into my code..

Initially I was facing a roadblock in passing my image as a params.. I
observed that it was not being passed when I looked into my log file..

The reason behind this, based on what I could figure out, as a solution
to get image upload working for me was... when I make use of :html => {
:multipart => :true , :id => 'new_post'} in my _common.html.erb partial
view, originally as you can see the 'multipart' and 'id' symbol are
taken as if as params for the html symbol.. and may be for the entire
html.erb partial that is being rendered..

I observed that when I removed the id symbol from its original location
as you can see above.. to something like this:-
:html => { :multipart => :true }, :id => 'new_post' images were now
being taken as a part of params along with each message.
html was being rendered and the page reloads..displaying the image and
the post.. but this doesn't render the .js.erb file any more.. .

why exactly this contrast in behavior is what I am unable to
understand.. and how exactly to get both working is something.. I am
trying to figure out..I guess I need to first understand exactly why
each thing works as shown..

Frederick Cheung wrote in post #1000053:

With Event.preventDefault(). If in Prototype, with Event.stop(). Be sure to wrap this method in a conditional, otherwise you have just killed the button and it will never bubble to submit the form again.

Walter

Hi Walter,

Can you please elaborate on how exactly I would be able to use
Event.preventDefault() with a conditional..?. Also why would I need to
use a conditional..? I ask this as I am a newbie to Jquery and my
javascript fundas are not very good.

To make it easier for you to answer this for me.. I have included the
part of the code in the partial where you say it would be appropriate to
put the button..

<%if @current_user.is_an_existing_member_of_group(@investor_group)%>
<%form_for :group_post, @group_post, :url => {:action => :post_message,
:id => params[:id]},:html => {:multipart => true} do |f| %>
    Start Discussion:<%=f.text_field :message%>
   <%= f.file_field :avatar %>
   <%=f.submit "Post" %>
  <%end%>

<div id = "latest_post"> </div>
<%for a in @group_all_posts %>
  <%if !a.avatar_file_name.to_s.empty? %>
  <br/> <%= image_tag a.avatar.url(:thumb) %>
  <%end%>
<br/><%= a.message %> <br/> by <%= Investor.find(a.post_by).first_name
%> <div class ="contentdispgrp" id="style_chck"> <%=
distance_of_time_in_words(a.created_at,Time.now) %> ago </div><br/><br/>
<hr/>
<%end%>

I would truly appreciate you extra effort in trying to help me..

Kindly bear with my being a novice.

Many Thanks for your inputs..

Walter Davis wrote in post #1000079:

Hi Walter,

Can you please elaborate on how exactly I would be able to use
Event.preventDefault() with a conditional..?. Also why would I need to
use a conditional..? I ask this as I am a newbie to Jquery and my
javascript fundas are not very good.

To make it easier for you to answer this for me.. I have included the
part of the code in the partial where you say it would be appropriate to
put the button..

<%if @current_user.is_an_existing_member_of_group(@investor_group)%>
<%form_for :group_post, @group_post, :url => {:action => :post_message,
:id => params[:id]},:html => {:multipart => true} do |f| %>
   Start Discussion:<%=f.text_field :message%>
  <%= f.file_field :avatar %>
  <%=f.submit "Post" %>
<%end%>

<div id = "latest_post"> </div>
<%for a in @group_all_posts %>
<%if !a.avatar_file_name.to_s.empty? %>
<br/> <%= image_tag a.avatar.url(:thumb) %>
<%end%>
<br/><%= a.message %> <br/> by <%= Investor.find(a.post_by).first_name
%> <div class ="contentdispgrp" id="style_chck"> <%=
distance_of_time_in_words(a.created_at,Time.now) %> ago </div><br/><br/>
<hr/>
<%end%>

I would truly appreciate you extra effort in trying to help me..

Kindly bear with my being a novice.

Many Thanks for your inputs..

I'm looking at this code, and it appears to be a normal post to the server. Where and what do you plan to update to the page using jQuery? Are you saying you want to post to the server, but through JavaScript, and update the current page with a refresh of the list of messages? Because there's a well-worn way to do that. You stop the form.submit method, and use Ajax to send the form instead, then your server replies with the current list of messages, and you update the appropriate list DIV with those.

I don't know the jQuery idiom for this, but in Prototype, it's very simple:

$('your_form_id').observe('submit',function(evt){
  evt.stop(); //keep the default submit from happening
  this.request({ //send the form through an Ajax request
    onSuccess: function(transport){
      $('your_list_container').update(transport.responseText);
    }
  });
});

As to the conditional, it doesn't apply in this pattern. But let's say you had a form submit button, and you wanted it to stop working after the form had been submitted (sort of what :disable_with does in the regular form builder code). You want the button to be pushed once only, so you might do something like:

$('your_button').observe('click',function(evt){
  if ( this.clicked ){
    evt.stop();
  }else{
    this['clicked'] = true;
  }
});

So the first time through, the button click happens and bubbles (and the button is marked so no future clicks will work) and the second + times it is clicked, it does nothing, because Event.stop happens instead. (Event.stop is a belt-and-suspenders form of Event.preventDefault, which is built in to most browsers, and I suspect added by jQuery to those that don't have it. It just makes the current event die and never propagate beyond the current element.

Walter

Hi Walter,

Thanks for your reply

Sorry for replying in late.. I had seen your post in the morning
itself.. was just doing research from my end..

To give in something that could help my case...

Actually, if you can kindly spare some time... to best explain my case..
I am pretty much doing what has been done in the Railscast by Ryan Bates
Jquery( http://railscasts.com/episodes/136-jquery )..I am actually
overriding the the submit method.... The only difference lies in the
fact that I am trying to display a new image which comes along with each
new message posted..

After some researching I found these quotes very interesting:-

"
5.2 Dealing with Ajax
Unlike other forms making an asynchronous file upload form is not as
simple as replacing form_for with remote_form_for. With an Ajax form the
serialization is done by JavaScript running inside the browser and since
JavaScript cannot read files from your hard drive the file cannot be
uploaded. The most common workaround is to use an invisible iframe that
serves as the target for the form submission.
"

This is taken from the site:-
http://guides.rubyonrails.org/form_helpers.html#dealing-with-ajax

This actually compliments what Fred had mentioned previously..
..would like to requote that:-

[

"

Posted by Frederick Cheung (Guest)
on 2011-05-21 12:39
(Received via mailing list)

1.4 . This stopped working when I had try to implement uploading images
in my app using paperclip... I request you to please look into this for
details of the

same:-http://stackoverflow.com/questions/6070510/unable-

.

Traditionally, a straight up ajax form can't upload files: when using
ajax a piece of javascript serializes the form and sends the request
to the server and javascript running inside the browser doesn't have
access to the filesystem.

The illusion of an ajax file upload can be provided by having the file
upload happen inside a hidden iframe, there are plenty of articles
describing how this works (and probably several jquery plugins
implementing it). Other options involve using flash for the upload

The file-api specification (http://www.w3.org/TR/file-upload/) does
add the ability for javascript to access the filesystem but not all
browsers currently support this

Fred

"

]

I tried to better understand what was happening for me .. based on the
part of AJAX, that I could implement.. I found that as in my first
post.. the latest_post represents "all" the entries of all messages
posted so far along with images as shown in the partial.. the only thing
that is happening is that the "latest" message is being "prepended" or
one can say prefixed in a way to the already existing list.. so that
list is not being fetched again from the DB and its just moved a
step/level down giving place for the latest post to come.. All this is
cool..:slight_smile: but now... to get the same working with each image.. is my real
challenge going forward....

Also since your also unfamiliar with the jquery syntax..

I found this as a good substitute to start somewhere:-

http://www.williambharding.com/blog/rails/rails-ajax-image-uploading-made-simple-with-jquery/

He has have made use of the attachment-fu plugin..

Now my challenge is to somehow use them together to get it working for
me..
I am working on it...Javascript is not something that I am quite good at
though..:).. will do what best I can from my end.. would be grateful if
you could help me with the your inputs , if you get time checking out
the above urls..

Thanks again Walter..:slight_smile:

Walter Davis wrote in post #1000100:

So is your question then how to go about uploading the file through "faux Ajax" methods, like a hidden iframe? Have a quick search on Github -- I would be startled if you didn't find a few ways to do this using a gem or plugin. The code itself is very simple, all you have to do is add the target attribute to your form, and make the value of that attribute the name and/or id of an iframe you have styled to be invisible. Everything else is the same. Then to get the response back from that iframe, you need to do a little more JavaScripting.

Walter

Hi Walter,

Sorry for replying in late..I was held up with things for the release
due yesterday.. I had in a way luckily been given more time to implement
this image upload via AJAX after yesterday's release.

I am not sure if calling it a "faux" AJAX call would be the appropriate
thing to say..,

I guess I need to really understand this
tutorial(http://www.williambharding.com/blog/rails/rails-ajax-image-uploading-made-simple-with-jquery/)
fully before I could really discover and then decide if I am using a
faux AJAX call or not..

But yes, after referring to
this(http://malsup.com/jquery/form/#file-upload)… it seems like I am
implementing something on the lines of using iframe…figuring my way
out… wondering how could I make use of text-area.

As of now I'm just trying a POC

Walter Davis wrote in post #1000273:

Hi Walter,

Sorry for replying in late..I was held up with things for the release
due yesterday.. I had in a way luckily been given more time to implement
this image upload via AJAX after yesterday's release.

I am not sure if calling it a "faux" AJAX call would be the appropriate
thing to say..,

I guess I need to really understand this
tutorial(http://www.williambharding.com/blog/rails/rails-ajax-image-uploading-made-simple-with-jquery/)
fully before I could really discover and then decide if I am using a
faux AJAX call or not..

I built one of these last year, and as of that time, the only browsers that could truly accept a real Ajax upload were WebKit nightlies and FF4 beta. Obviously time moves on. But the upload kit I used (noswfupload) had code paths for both kinds of browsers, and made it very simple to factor out the differences. Under the covers, for most browsers (AFAIK) an iframe is dynamically injected into the page and the file upload is ported through that keyhole. The "page" doesn't refresh, but the iframe's document certainly does, so the browser is happy either way.

Walter