How do I reload my comments partial with ajax? - ruby-on-rails

So I'm a beginner in Rails and I'm trying to reload a partial when I create a Comment.
I am creating a sort of forum where I have Posts and Comments on Posts.
Here is the situation :
/views/posts/show.html.erb
<% #posts.each do |post| %>
<%= post.title.capitalize %>
<%= post.content %>
<%= render 'comments/comment', post: post, comments: post.comments %>
<%= form_tag(category_forum_post_comments_path(#category, #forum, post), :method => :post, class: 'form newtopic') do %>
<%= text_field_tag :content, nil, placeholder: 'Commenter', class: 'form-control' %>
<%= submit_tag "Envoyer", class: "btn btn-primary" %>
<% end %>
<% end %>
<%= form_tag(category_forum_posts_path(#category, #forum), :method => :post, class: 'form newtopic') do %>
<%= text_field_tag :title, nil, placeholder: 'Titre de votre Post', class: 'form-control' %>
<%= text_area_tag :content, nil, placeholder: 'Description', id: 'desc', class: 'form-control' %>
<%= submit_tag "Envoyer", class: "btn btn-primary" %>
<% end %>
and then in /views/comments/_comment.html.erb
<% comments.each do |comment|%>
<%= comment.content %>
<%= link_to 'Supprimer', category_forum_post_comment_path(#category, #forum, post, comment),
method: :delete, class: "btn-danger btn-sm", data: { confirm: 'Etes-vous sûr?' } %>
<% end %>
I would like to reload my comment partial on post.
I tried to understand so many posts on stackoverflow and tutorial that I could find online and still have no idea how to do it.
If someone would be kind enough to help me get through this it would be great.

What's the action that you want to trigger that reload? you are showing forms, links, it's not too clear.
Basically, you need to use remote: true on the form/link, then add a view for that action with .js.erb extension, and, on that view, use javascript to change the content of an specific element.
Something like:
1st, you need to give some unique way to reach the element you want with javacsript:
<% #posts.each do |post| %>
<div id="post_<%= post.id -%>">
<%= post.title.capitalize %>
<%= post.content %>
<div class='comments'>
<%= render 'comments/comment', post: post, comments: post.comments %>
</div>
<%= form_tag(category_forum_post_comments_path(#category, #forum, post), :method => :post, class: 'form newtopic') do %>
<%= text_field_tag :content, nil, placeholder: 'Commenter', class: 'form-control' %>
<%= submit_tag "Envoyer", class: "btn btn-primary" %>
<% end %>
</div>
<% end %>
<%= form_tag(category_forum_posts_path(#category, #forum), :method => :post, class: 'form newtopic') do %>
<%= text_field_tag :title, nil, placeholder: 'Titre de votre Post', class: 'form-control' %>
<%= text_area_tag :content, nil, placeholder: 'Description', id: 'desc', class: 'form-control' %>
<%= submit_tag "Envoyer", class: "btn btn-primary" %>
<% end %>
Note the div with id=post_x and the div with class comment
Now you can locate it using javacsript:
#your_view.js.erb
post = document.getElementById('post_<%= #post.id -%>');
comments = post.querySelector('comments');
And finally, also on your view, render the partial and replace comments' innerHTML
comments.innerHTML = '<%= j(render partial: "comments/comment", post: #post, comments: #post.comments) -%>';
Just a suggestion, use "comments" (in plural) for the name of the partial, since you are rendering all the comments and not just one.

Related

Rails - Save parameters between actions

I have an app that books spaces for certain dates. In the index page, I have a search form to display only the spaces that are available from params[:query1] to params[:query2] certain dates. Then in the space show page, I have a form for booking the space.
I'd like to maintain the params[:query1] and params[:query2] also in the space show page as the default value for the booking form.
index.html.erb:
<%= form_tag spaces_path, method: :get, class: "form-inline" do %>
<%= label_tag :query1, "Check in" %>
<%= date_field_tag :query1, params[:query1], class: "form-control" %>
<%= label_tag :query2, "Check out" %>
<%= date_field_tag :query2, params[:query2], class: "form-control" %>
<%= submit_tag "Search", class: "btn" %>
<% end %>
show.html.erb
<%= form_with(model: [#space, #booking], local: true) do |f| %>
<%= label_tag :check_in, "Check in" %>
<%= f.date_field :check_in, value: params[:query1], class: "form-control" %>
<%= label_tag :check_out, "Check out" %>
<%= f.date_field :check_out, value: params[:query2], class: "form-control" %>
<%= submit_tag "Reserve", class: "btn" %>
<% end %>
You can use a session to store your queries and use them throughout your app. You can store your queries in a session in your index action like this:
def index
session[:query1] = params[:query1]
session[:query2] = params[:query2]
end
Then in your show action, you can access the session like this:
def show
#query1 = session[:query1]
#query2 = session[:query2]
end
In your form on your show page, you can then use the instance variables:
<%= form_with(model: [#space, #booking], local: true) do |f| %>
<%= label_tag :check_in, "Check in" %>
<%= f.date_field :check_in, value: #query1, class: "form-control" %>
<%= label_tag :check_out, "Check out" %>
<%= f.date_field :check_out, value: #query2, class: "form-control" %>
<%= submit_tag "Reserve", class: "btn" %>
<% end %>
Learn more about session

how to Edit a post in rails and display said post in the text_field

I am trying to build a page that will host the content of the post from the psql data base and allow user to edit the content of that post inside the text field
I am getting a no method error however message is the correct column in database
any help is very appreciated
<h1>Edit message</h1>
<%= form_with(modle: #post, local: true) do |form| %>
<p>
<%= form.label :message %><br>
<%= form.text_field :message, :value => form.message %>
</p>
<p>
<%= form.submit %>
</p>
<%end%>
<%= link_to 'Back', posts_url %>
<h1>Posts shown below</h1>
<p>To add a new post click link:
<%= link_to new_post_path do %>
New post
<% end %>
</p>
<p>---------------------------------------------</p>
<% #posts.reverse_each do |post| %>
<div id = "<%=post.id %>">
<p><%= post.message %></p>
<p><%= post.created_at.strftime(" Posted at %a %I:%M%p") %></p>
<p><%= link_to 'Destroy', post, :confirm => 'Are you sure?',
:method => :delete %></td>
<p> <%= link_to 'Update', edit_post_path(post) %> </p>
<p>---------------------------------------------</p>
</div>
<% end %>
It should be form.object.message, make changes in this line
<%= form.text_field :message, :value => form.object.message %>
or as max said, just remove the value option all together, it will still work
<%= form.text_field :message %>
Give it a try!
<h1>Edit message</h1>
<%= form_with(model: #post, local: true) do |form| %>
<p>
<%= form.label :message %><br>
<%= form.text_field :message, :value => Post.find(params[:id]).message %>
</p>
<p>
<%= form.submit %>
</p>
<%end%>
<%= link_to 'Back', posts_path %>

Reformat a form_tag to form_for to use formaction

I have a form_tag in my edit view:
<%= form_tag stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do %>
<div class="form-group">
<%= label_tag 'csv_batch_file', 'Select batch file' %>
<%= file_field_tag 'csv_batch_file', class: 'form-control' %>
</div>
<br>
<div class="form-group">
<%= label_tag 'potential_item_id', 'Input item id' %>
<%= text_field_tag "potential_item_id" %>
</div>
<br>
<%= button_tag 'Stage', class: 'btn btn-primary' %>
<% end %>
Currently it puts to stage_batches/:id which is what I want.
However, I want to add another button that posts to some other controller, say Foo#create. I read in another answer that the formaction option will work. But the given example uses form_for and not form_tag:
<% form_for(something) do |f| %>
...
<%= f.submit "Create" %>
<%= f.submit "Special Action", formaction: special_action_path %>
<% end %>
How do I rewrite my form_tag as a form_for?
<%= form_tag stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do %>
==>
<%= form_for #stage_batch, url: stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do |f|%>
Also the same as:
<%= form_for #stage_batch, class: 'form-inline' do |f|%> #if #stage_batch is new_record? then method: :post, else method: :put
PS: You should try this https://github.com/plataformatec/simple_form, a lifesaver.
With simple_form your form can be transformed to:
<%= simple_form_for #stage_batch do |f|%>
<%= f.input :csv_batch_file, as: :file %>
<%= f.input :potential_item_id %>
<%= f.submit 'stage' %>
<%end%>
simple and beautiful.

rails cant create an object

So I am making a colors palette manager and both tables requested on the form are nested and properly related(I would like to also point out that I am a rookie to rails)
This whole code was working perfectly fine when in line 4 was requesting links instead of just the names and suddenly wont work anymore, thank you for the help in advance
<div class='nav_bar'>#</div>
<% if #projects %>
<% #projects.each do |project| %>
<li><div class='container'><h1><%= project.name project_path(:id => project.id) %></h1>
<ul>
<%= form_for project do %>
<%= fields_for :palette, project.palette do |palette| %>
<%= palette.label 'background_dark_color' %>:
<%= palette.text_field :background_dark_color, placeholder: '#palette.background_dark_color' %><br/>
<%= palette.label 'background_light_color' %>:
<%= palette.text_field :background_light_color, placeholder: "#palette.background_light_color" %><br/>
<%= palette.label 'dark_color1' %>:
<%= palette.text_field :dark_color1, placeholder: "#palette.dark_color1" %><br/>
<%= palette.label 'dark_color2' %>:
<%= palette.text_field :dark_color2, placeholder: "#palette.dark_color2" %><br/>
<%= palette.label 'light_color1' %>:
<%= palette.text_field :light_color1, placeholder: "#palette.light_color1" %><br/>
<%= palette.label 'light_color2' %>:
<%= palette.text_field :light_color2, placeholder: "#palette.light_color2" %><br/>
<%= palette.submit %>
<%= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
</ul>
<% end %></li>
<%end%>
<%end%>
<div class='circle'><%= link_to "+", new_project_path %></div>
<button type="button"><%= link_to "+", new_project_path %></button>
I think you are referring to the following line,
<%= project.name project_path(:id => project.id) %>
There is a mistake in this code. There are two ways to fix this.
Solution 1
If you want to display a link or an anchor tag this use replace this with the following code,
<%= link_to project.name, project_path(:id => project.id) %>
Solution 2
If you don't want a link but, just the name to appear then, do the following,
<%= project.name %>

Pre select form input based on params

I have a button on an index page that links to a new_assignment_path
<% #users.each do |user| %>
<tr>
<td><%= link_to user.name, user %></td>
<td><%= link_to 'Assign to Class', new_assignment_path, :class => 'btn btn-mini' %></td>
</tr>
<% end %>
And I want it so that when you click on it, it takes you to the new_assignment_path, and takes the dropdown select on that pages form.
<%= simple_form_for(#assignment) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :user_id, collection: User.all.collect, as: :select %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
And have the drop down automatically set to the user.id of whatever user the button was inside of.
<%= link_to 'Assign to Project', new_assignment_path(#assignment, :user_id => user.id), :class => 'btn btn-mini' %>
and
<%= link_to 'Assign to Project', new_assignment_path(:user_id => user.id), :class => 'btn btn-mini' %>
And neither of them worked.
What is the best way of doing this?
With your second option try setting the instance variable in the AssignmentsController.
#user_id = params[:user_id]
Then you need to specify the default in the form
<%= f.input :user_id, collection: User.all.collect, selected: #user_id %>
You don't need as: :select with Simple Form.

Resources