Ruby on Rails Wednesday, June 21, 2017



On Tuesday, June 20, 2017 at 8:52:58 AM UTC-4, Walter Lee Davis wrote:

> On Jun 20, 2017, at 3:29 AM, fugee ohu <fuge...@gmail.com> wrote:
>
>
>
> On Sunday, June 18, 2017 at 11:30:27 PM UTC-4, Walter Lee Davis wrote:
>
> > On Jun 18, 2017, at 8:24 PM, fugee ohu <fuge...@gmail.com> wrote:
> >
> >
> >
> > On Friday, June 16, 2017 at 6:47:49 PM UTC-4, Walter Lee Davis wrote:
> > There can only be one instance of an ID on any given page. And nothing you did in this example will render the id #commentable. If you look at my example, I did not use an ID on each element. The selector in $('#commentable').each should be $('#parent_of_the_list div'), and you'll have to apply whatever ID you want to search for to a parent element of the commentables. If you want to do this in a slightly simpler manner, you could apply a classname to the commentables, using the div_for helper: <%= div_for(commentable, class: 'commentable') do %>. Then you can change the jQuery to $('.commentable') and that will also work.
> >
> > Walter
> >
> > > On Jun 16, 2017, at 4:14 PM, fugee ohu <fuge...@gmail.com> wrote:
> > >
> > > The anchor doesn't get rendered I didn't know what to use for the element name so I used the same as I used the same variable I passed to div_for in my view, commentable Thanks in advance
> > >
> > >
> > > View:
> > >  <%= div_for(commentable) do %>
> > >  <% end %>
> > >
> > > js.erb
> > > $(document).on('turbolinks:load', function(){
> > >   $('#commentable').each(function(){
> > >     var elm = $(this);
> > >     elm.append('<a href="/comments/new?commentable_id=' + elm.attr('id').split('_')[1] + '">Comment</a>');
> > >           });
> > > });
> > >
> > >
> >
> >
> >  Here's my page souce and js.erb it's not appening anything to the page with the render
> >
> > <div class="post">
> >   <p>Doing nothing as usual</p>
> >  
> >
> >   <a data-remote="true" href="/comments/new?comment%5Bcommentable_id%5D=14&amp;comment%5Bcommentable_type%5D=Post">Comment</a>
> > </div>
> > <div class="post" id="post_14">
> > </div>
> >
> > $(document).on('turbolinks:load', function(){
> >   $('#post div').click.(function(){
> >     var elm = $(this);
> >     elm.append('<%= form_for @comment do |f| %>  <%= f.hidden_field :commentable_id, value: @comment.commentable_id %><%= f.hidden_field :commentable_type, value: @comment.commentable_type %>  <div class="field form-group">                <%= f.text_area :body, class: 'form-control' %>          </div>          <div class="field form-group">                <%= submit_tag "Post comment", class: 'btn btn-primary' %>          </div>        <% end %>');
> >   });
> > });
> >  
>
> You've skipped over the last set of instructions I sent you, and you really need to do this in order or it will never make sense. Show me the code you are using that loads the form into another page, and please don't post it unless it is working in a browser and you can save comments. Get that far, and THEN I will be happy to help you take it into Ajax land.
>
> Walter
>
>  _post.html.erb
>
> <%= content_tag_for(:div, post) do %>
>     <%= simple_format post.content %>
>     <% unless post.attachment.blank? %>
>       <%= image_tag(post.attachment, height: 250) %><br>
>     <% end %>
>     <%= link_to 'Comment', new_comment_path( 'comment[commentable_type]': 'Post', 'comment[commentable_id]': post.id), remote: true %>
>     <%= content_tag_for(:div, post, :comment) do %>

You may want to insert the existing comments here:

<%= render post.comments %>

Then you can inject the form at the top or the bottom of the list. Remember, you'll need a _comment.html.erb partial in the views/comments folder for the short-hand to work.

>     <% end %>
> <% end %>
>
> produces
>
> <div class="post" id="post_13">
>         <p>listening to blues</p>
>  
>
>         <a data-remote="true" href="/comments/new?comment%5Bcommentable_id%5D=13&amp;comment%5Bcommentable_type%5D=Post">Comment</a>
>         <div class="comment_post" id="comment_post_13">
> </div></div><div class="post" id="post_14">
>         <p>Doing nothing as usual</p>
>  
>
>         <a data-remote="true" href="/comments/new?comment%5Bcommentable_id%5D=14&amp;comment%5Bcommentable_type%5D=Post">Comment</a>
>         <div class="comment_post" id="comment_post_14">
> </div></div>
>
> new.js.erb
>   $('#post comment div)click.(function(){
>
> This doesn't produce anything

That's not surprising. Your RJS handler is going to be rendered with the same parameters that new.html.erb is when it creates a new page. So what you do in that instance is not observe a click (that click already happened) but rather identify the parts of the page that you want to replace, and replace them with the parts you need to insert. You're already on the other side of the click.

The content_tag_for method has a partner: dom_id(element, name_addition=nil). It produces just the ID for the element, not the entire element.

Inside the new.js.erb, rather than having the <%= render 'form' %> just spew out some HTML, you target where that should go:

$('#<%= dom_id(post, :comment) %>').prepend('<%=j render( 'comments/form' ) %>');

That will expand to $('#comment_post_14').prepend('<form ... >'); which will inject the form into the top of the comment_post_N container.

Trouble is, it will also do that again and again if you click the link repeatedly. To get around that, you could put the link to add a comment inside the container you want to fill with the form, and then use the jQuery html() method to replace the contents. That would look the same as above, just replace prepend with html. This gets around you needing to test if the form is already there, because the moment you click the link, the link is replaced with the form and you can't click it again.

So you have something like this in the end:

<%= content_tag_for(:div, post) do %>
    <%= simple_format post.content %>
    <% unless post.attachment.blank? %>
      <%= image_tag(post.attachment, height: 250) %><br>
    <% end %>
    <%= content_tag_for(:div, post, :new_comment) do %>
      <%= link_to 'Comment', new_comment_path( 'comment[commentable_type]': 'Post', 'comment[commentable_id]': post.id), remote: true %>
    <% end %>
    <%= content_tag_for(:div, post, :comments) do %>
      <%= render post.comments %>
    <% end %>
<% end %>

The new.js.erb becomes this:

$('#<%= dom_id(post, :new_comment) %>').html('<%=j render( 'comments/form' ) %>');

And then to update the page, you want to render just that post again into the list. This is why you wanted to have the posts/index.html.erb depend on a _post.html.erb partial to render the list -- you're automatically set up to do this last step.

Make sure that your form_for method includes the remote: true configuration pair. This will submit the form via Ajax.

In comments_controller.rb, make sure you have a respond_to block for :js in the #create method. In case of an error, it will need to render the :new method again, but if the save succeeds, it should just render the create.js.erb by default (pass an empty block to that content_for).

create.js.erb would be something like this:

$('#<%= dom_id(@comment.post) %>').replaceWith('<%=j render @comment.post %>');

And that's really it. If it doesn't work, it's probably a typo on my part.

Walter


>
>
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/3fea1525-2b10-4718-9fa0-b6d04216aa51%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


List comments and inject the form at the top or bottom of the list, what about a link to new comment we skipped over that no?

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/6e4181c9-5e44-40f4-ab04-361a8f0906c2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment