How to prepopulate _form with duplicated image? - javascript

A user can click on a featured_inspiration to prepopulate a new _form with the data from that featured_inspiration. The data being :text and/or :image. This is so the user can save a preexisting Inspiration to his own list of Inspirations.
:text correctly prepopulates the form, but for some reason :image remains nil.
controller
def new
existing_inspiration = Inspiration.find_by_id params[:inspiration_id]
if existing_inspiration
#inspiration = existing_inspiration.dup
### Attempt at Making It Works. Had No Effect. ###
#inspiration.image_file_name = existing_inspiration.dup.image_file_name
#inspiration.image_content_type = existing_inspiration.dup.image_content_type #Attempt at Making It Works. Had No Effect.
#inspiration.image_file_size = existing_inspiration.dup.image_file_size
#inspiration.image_updated_at = existing_inspiration.dup.image_updated_at
##############
else
#inspiration = current_user.inspirations.build
end
end
Console
[41] pry(main)> Inspiration.last
Inspiration Load (1.7ms) SELECT "inspirations".* FROM "inspirations" ORDER BY "inspirations"."id" DESC LIMIT 1
=> #<Inspiration:0x007fa6d15ec9a8
id: 13,
conceal: false,
user_id: 8,
created_at: Fri, 26 Feb 2016 15:29:52 EST -05:00,
updated_at: Fri, 26 Feb 2016 15:29:52 EST -05:00,
likes: nil,
name: "",
image_file_name: nil, #SHOULD BE: "inspiring-quotes-about-life-6gbwrvxd.jpg",
image_content_type: nil, #SHOULD BE: "image/jpeg",
image_file_size: nil, #SHOULD BE: 83348
image_updated_at: nil> #SHOULD BE: Wed, 24 Feb 2016 15:25:44 EST -05:00>
_form
<%= simple_form_for(#inspiration, html: { data: { modal: true } }) do |f| %>
<%= f.file_field :image %>
<%= f.text_area :text %>
<% end %>
Question that got duplicating text to work.
UPDATE
suggested_inspirations
<% #inspirations.each do |inspiration| %>
<%= link_to inspiration_path(inspiration) do %>
<div class="box panel panel-default" style="width: 175px;">
<% if inspiration.image.present? %>
<div id="box">
<%= link_to new_inspiration_path(inspiration_id: inspiration.id), data: { modal: true } do %>
<div class="inspiration-image-button"><span class="glyphicon glyphicon-plus"></span></div>
<% end %>
<%= link_to image_tag(inspiration.image.url(:medium)), inspiration %> #This is how image is pulled
</div>
<% end %>
<% if inspiration.name.present? %>
<div class="panel-body">
<%= link_to new_inspiration_path(inspiration_id: inspiration.id), data: { modal: true } do %>
<div class="inspiration-button"><span class="glyphicon glyphicon-plus"></span></div>
<% end %>
<%= inspiration.name %>
</div>
<% end %>
</div>
<% end %>
<% end %>

I wonder what you need to do is something like this:
#inspiration = existing_inspiration.dup
#inspiration.image_file_name = existing_inspiration.image_file_name
Leaving out the dupand doing the "deep" copies by hand.
Take a look at What is the easiest way to duplicate an activerecord record?. It is a bit old, but an enlightening discussion as well as pointers to some gems that make "deep" copies.

Related

rails - Update View when Form is Submitted without Refreshing the Page

I'm building a Rails app in which there are exercises and user_answers. When the user sees an exercise, there is a form that he can submit with the answer he thinks is right.
When submitting, I want the same view to be shown, without a refresh, but with a new div which has the solution of the exercise. The view shown is the exercises/show and a form rendered in the user_answers folder. Right now, my code looks like this:
exercises/show.html.erb
<div class="container exercise-page">
<h2 class="exercise-title">Exercício <%= #exercise.id %> de <%= #exercise.category %> - <%= #exercise.sub_category %></h2>
<br>
<%= render 'user_answers/user_answer_form' %>
<br>
<div id="solution_exercise">
</div>
user_answers/_user_answer_form.html.erb
<%= simple_form_for [#exercise, #user_answer], authenticity_token: true, remote:true, :method => 'POST', :html=> { class: 'col-xs-12 col-sm-12 col-lg-3 mx-auto text-center list-group', id:"form"} do |f| %>
<%= f.simple_fields_for :answers, include_id: false do |answer| %>
<%= f.input_field :answer,
label: 'Answer',
as: :radio_buttons,
class: 'form-check-input',
:item_label_class => 'list-group-item',
name: 'answer',
collection: #answers, label_method: :answer %>
<br>
<%= f.submit 'Submit Answer!', class: "btn btn-outline-success", id: "submit" %>
<% end %>
user_answers_controller.rb
def create
#user_answer = UserAnswer.new(user_answer_params)
#answers = Exercise.find(params[:exercise_id]).answers
#exercise = Exercise.find(params[:exercise_id])
#user_answer.exercise = #exercise
#user_answer.answer = #exercise.answers.find(params[:answer])
#user_answer.user_id = current_user.id
#user_answer.save
respond_to do |format|
format.js
end
end
user_answers/create.js.erb
solution = document.querySelector("solution_exercise")
solution.innerHTML = '<%= j render partial: "solution" %>'
user_answers/_solution.html.erb
<p>Your answer: <%=current_user.user_answers.last.answer.answer%></p>
The error:
Does someone know what I'm doing wrong?

Not showing posts where boolean is true

I have an app I am making where users can post items and then they can select "live" when they select "live" as true the post should show up in a live tab.
Right now this is my posts_controller.rb create and update actions
def create
#post = Post.new(post_params)
if #post.save
redirect_to post_path(#post)
flash[:success]="Post created"
else
render 'new'
end
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
flash[:success]="Updated successfully"
redirect_to post_path(#post)
else
render 'edit'
end
end
--------------------------------
def post_params
params.require(:post).permit(:title, :description,
:category_id, :subcategory_id, :live)
end
My Post form for editing and creating a new post.
<script type="text/javascript">
$(document).ready(function() {
var subcat;
subcat = $('#subcategory-select').html();
return $('#category-select').change(function() {
var cat, options;
cat = jQuery('#category-select').children('option').filter(':selected').text();
options = $(subcat).filter("optgroup[label='" + cat + "']").html();
if (options) {
return $('#subcategory-select').html(options);
} else {
return $('#subcategory-select').empty();
}
});
});
</script>
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
<%= render 'shared/errors', obj: #post%>
<%= form_for #post do |f| %>
<p>
<%= f.label :title %><br/>
<%= f.text_field :title, maxlength: "10" %>
</p>
<p>
<%= f.label :description %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.label :category_id%>
<%= f.collection_select(:category_id, Category.all, :id, :name,
{ prompt: 'Select a category' }, { id: 'category-select' }) %>
</p>
<p>
<%= f.label :subcategory_id%>
<%= f.grouped_collection_select :subcategory_id, Category.all, :sub_categories,
:name, :id, :name, { include_blank: 'Select a sub category' },
{ id: 'subcategory-select' } %>
</p>
<p>
<%= f.label :live%>
<%= check_box_tag :live , 0 , #post.live ? false : true %> <!--work on-->
<p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to "Back to posts listing", posts_path %>
The posts doesn't save as being live, I can force it into being live with the rails console however. This brings me to the next issue.
I forced a post to have live == true and it doesn't show up in my bootstrap live tab. This is for my subcategory show action which is where I am trying to do this first.
def show
#subcategory = SubCategory.find(params[:id])
#subcategory_posts = #subcategory.posts#live posts in this subcat
#subcategory_posts_live = (params[:live] == 'true')
end
And the show.html.erb bootstrap navigation tabs which should show the live posts but doesn't on click
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Posts</li>
<li role="presentation">Live ◯</li>
<li role="presentation">xx</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home"><%=render 'posts/post', obj: #subcategory_posts %></div>
<div role="tabpanel" class="tab-pane" id="profile"><%=render 'posts/post', obj: #subcategory_posts_live %></div>
<div role="tabpanel" class="tab-pane" id="messages">...</div>
</div>
I know that it is looking for posts because in the view it shows <p>No Listings found</p> which is what I am displaying in my 'posts/_post` partial if no posts are found within that specific category i.e Live Subcategory Posts.
Unsure on how to work this one out, any guidance appreciated.
It looks like your form is missing a checkbox to allow the user to select if a post is live or not. You need a checkbox.
So something like this may work:
<%= f.check_box :live %>
To query for all posts that are live (I'm assuming this is a boolean column in your db):
#live_posts = Post.where(live: true)
For your subcategory query, you can do this:
#subcategory_posts = Post.where(subcategory_id: params[:id], live: true)
(This assumes posts have a subcategory_id column)

Rails 5: Trying to render divs with a single partial but keep the div class unique so that JQuery doesn't fire on all partials

A bit of a confusing title.
I am trying to implement a bit of a reddit like comment system. So that you can view a Post and add a Comment to it which is polymorphic. Or, comment on another Comment.
My view looks like so:
<h2>Post:</h2>
<div class="well">
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<% if #post.description %>
<p>
<strong>Description:</strong>
<%= #post.description %>
</p>
<% end %>
</div>
<% if current_user %>
<%= render "shared/comment_form" %>
<% else %>
<p>Log in to add comments</p>
<% end %>
<% if #post.comments.any? %>
<%= render "shared/comment_list" %> # Another comment_form inside of this partial
<% else %>
<p>No comments yet</p>
<% end %>
Inside of comment_list is another rendering of comment_form so that you can comment on a comment:
<h2>Comments</h2>
<ul>
<% #post.comments.each do |co| %>
<li><%= co.body %></li>
<%= render "shared/comment_form" if current_user %>
<% end %>
</ul>
Finally, my comment form itself:
<div id="comment-form" class="form-group">
<%= form_for #comment, remote: true, url: post_comments_path(#post) do |f| %>
<%= f.text_area :body, required: true, rows: 5, class: "form-control" %>
<%= f.hidden_field :commentable_id, :value => #post.id %>
<%= f.hidden_field :commentable_type, :value => #post.class.name %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<br>
<%= f.submit class: "btn btn-primary" %>
<% end %>
</div>
<span id="add-comment">Add a comment</span>
And the Jquery code that acts on the comment_form:
$(document).on('turbolinks:load', function() {
$("#comment-form").hide();
$('#add-comment').click( function() {
$("#comment-form").fadeToggle("fast");
($("#add-comment").text() === "Cancel") ? $("#add-comment").text("Add comment") : $("#add-comment").text("Hide");
});
});
My question is:
How could I separate these divs so that Jquery doesn't fire on all instances of id="comment-form? I would like to pass in an erb tag like <%= #post.class.name %><%= #post.id %>, but again, keep the variable universal. Then, how could I implement that unique id name in my JQuery code.
Edit: I got one part of my question solved. I left the rest of what I wasn't able to do up for everyone to see.
You could use prev() like this:
$(document).ready(function() {
$('.comment-form').hide();
$('.add-comment').click( function(event) {
// Store the button which has just been clicked on a variable
var eventTarget = $(event.target);
// Find the previous element with the #comment-form and id and toggle it
eventTarget.prev('.comment-form').fadeToggle('fast');
// Use the eventTarget Again
(eventTarget.text() === 'Cancel') ? eventTarget.text('Add comment') : eventTarget.text('Cancel');
});
});
You can see this in action here: http://codepen.io/rebagliatte/pen/MbKNJv

How do I grab a comments class after a successful ajax form submit then display it with out page refresh?

I want to get ".comment_container" for the post just made and place it after the last comment.
Each comment and it's related content is stored in a ".comment_container" class.
The code below does what I need but not 100%. Rather than append the word TEST I want to append the new comment_contaner holding the comment just posted.
I've been cracking at this all day and this is how far I've come. I would appreciate some solutions with examples if possible.
JQuery:
$('#new_comment').on('ajax:success', function(){
$(this).parent('.post_content').find('.comment_container:last').after("TEST");
});
<% sleep 1 %>
HTML:
<div class="postHolder">
<nav class="micropostOptions">
<ul class="postMenu">
<li class="deletePost"><%= link_to content_tag(:span, "Delete post"), m, :method => :delete, :confirm => "Are you sure?", :title => m.content, :class => "message_delete" %>
</li>
<li class="disableCommenting"><%= link_to content_tag(:span, "Pause commenting"), "2" %></li>
<li class="blockCommenter"><%= link_to content_tag(:span, "Block commenter"), "3" %></li>
<li class="openInNewWindow"><%= link_to content_tag(:span, "Open in new window"), "4" %></li>
<li class="reportAbuse"><%= link_to content_tag(:span, "Report abuse"), "5" %></li>
</ul>
</nav>
<%= link_to image_tag(default_photo_for_current_user, :class => "poster_photo"), current_users_username %>
<div class="post_content">
<div class="post_container">
<div class="userNameFontStyle"><%= link_to current_users_username.capitalize, current_users_username %> -
<div class="post_time"> <%= time_ago_in_words(m.created_at) %> ago.</div> </div>
<%= simple_format h(m.content) %> </div>
<% if m.comments.any? %>
<% comments(m.id).each do |comment| %>
<div class="comment_container">
<%= link_to image_tag(default_photo_for_commenter(comment), :class => "commenter_photo"), commenter(comment.user_id).username %>
<div class="commenter_content"> <div class="userNameFontStyle"><%= link_to commenter(comment.user_id).username.capitalize, commenter(comment.user_id).username %> - <%= simple_format h(comment.content) %> </div>
</div><div class="comment_post_time"> <%= time_ago_in_words(comment.created_at) %> ago. </div>
</div>
<% end %>
<% end %>
<% if logged_in? %>
<%= form_for #comment, :remote => true, :html => {:class => "new_comment} do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :micropost_id, :value => m.id %>
<%= f.text_area :content, :placeholder => 'Post a comment...', :class => "comment_box", :rows => 0, :columns => 0 %>
<div class="commentButtons">
<%= f.submit 'Post it', :class => "commentButton" %>
<div class="cancelButton"> Cancel </div>
</div>
<% end %>
<% end %>
</div>
</div>
Comments controller:
class CommentsController < ApplicationController
def create
#comment = Micropost.find(params[:comment][:micropost_id]).comments.build(params[:comment])
respond_to do |format|
if #comment.save
unless params[:comment][:recipient].blank? # this will be blank when current user is commenting/replying on their own wall
recipient = User.find(params[:comment][:recipient])
UserMailer.new_wall_post_comment_notification(recipient, current_user).deliver if recipient.email_notification == 1
end
format.js { render :post_comment }
else
format.js { render :form_errors }
end
end
end
end
Comment partial:
<div class="comment_container">
<%= link_to image_tag(default_photo_for_commenter(#comment), :class => "commenter_photo"), commenter(#comment.user_id).username %>
<div class="commenter_content">
<div class="userNameFontStyle"><%= link_to commenter(#comment.user_id).username.capitalize, commenter(#comment.user_id).username %> - <%= simple_format h(#comment.content) %>
</div>
</div>
<div class="comment_post_time">
<%= time_ago_in_words(#comment.created_at) %> ago.
</div>
</div>
Seems to be working apart from 1 minor issue. Let's say I post 4 comment... 1 after each other. First comment 1, second 2, third 3 and fourth 4.. e.g. 1, 2, 3 and 4 the result I get is this:
I have a feeling it's something to do with some kind of reset needing to be done after each comment is left. After refreshing the comments display as expected. 1, 2, 3 and 4. Any thoughts?
Kind regards.
You should make the partial for rendering your Comments (I guess it should be the /views/comments/_comment.html.erb).
Then just replace:
.after("TEST");
with:
.after("<%= j render #comment %>");
This along with the advice from jdoe fixed my issue
$('.new_comment').off().on('ajax:success', function(e){
e.preventDefault();
$(this).parent('.post_content').find('.comment_container:last').after("<%= j render 'comments/partials/comment' %>");
$('#comment_content').removeClass("comment_box_focused").addClass("comment_box");
$(".commentButtons").removeClass("displayButtons");
$('#comment_content').val("");
<% sleep 1 %>
});

rails .js.erb views does not work on production server since it work on development machine

I don't have any idea why code works on development machine, but doesn't work on production server. I am trying to create live chat between operator and user. In development machine the user's interface and operator's works fluently. I am using pusher as web-sockets. Actually every js.erb view does not work at all in production server. There is some parts of my view.
_show.html.erb:
<%= content_tag :div, id: "chat-heading", class: %w(mpreview migedit r).include?(action_name) ? 'panel-heading2' : 'panel-heading', style: "font-size:14px;" do %>
<%= t :chat_heading %>
<i class="fa fa-arrow-up" aria-hidden="true" style="float: right;"></i>
<% end %>
<div class="panel panel-primary" style="display: none" id="chat-primary" tabindex="0">
<%= content_tag :div, class: 'panel-body', id: 'messages', data: {url: "/#{params[:locale]}/chats/#{#chat.id}/messages/"} do %>
<% unless #messages.total_pages < 2 %>
<div class="row" id="show-more-aligment">
<div class="col-md-4 col-md-offset-5" style="margin-bottom: 20px;">
<%= link_to 'Show more', url_for(:controller => 'home', :action => 'index', :page => 2, :locale => params[:locale]), :remote => true, :id => 'show_more_link' %>
</div>
</div>
<% end %>
<ul class="chat" id="chat-ul">
<% #messages.reverse_each do |message| %>
<%= render partial: 'messages/message', locals: {message: message} %>
<% end %>
</ul>
</div>
<div class="panel panel-footer">
<div class="row">
<%= simple_form_for #chat.messages.build, url: "/#{params[:locale]}/chats/#{#chat.id}/messages/", :user_id => current_user, remote: true, :html => {:autocomplete => "off"} do |f| %>
<div class="col-md-10">
<%= f.input :text, required: true, as: :string, :class => 'btn-input form-control input-sm', :placeholder => "Type your message here...", :label => false %>
</div>
<div class="col-md-2">
<%= f.submit 'Send', :class => 'btn-chat btn btn-warning btn-sm form-control msg-submit' %>
</div>
<% end %>
<% end %>
</div>
</div>
render of _show.html.erb:
<% if user_signed_in? %>
<%= content_tag :div, class: %w(mpreview migedit r).include?(action_name) ? 'welcome_chat2' : 'welcome_chat' do %>
<%= render 'chats/show' %>
<% end %>
<% end %>
controller for create method:
def create
#message = #chat.messages.new(params[:message])
#message.user = current_user
respond_to do |format|
if #message.save
format.html {redirect_to #chat}
format.js { Pusher.trigger("live_chat_#{#chat.id}", 'chat', {message: #message}) }
else
format.html {render 'new'}
format.js
end
end
end
create.js.erb:
$('#message_text').val('');
index.js.erb(adding new sent message to chat div):
if ($('#chat-ul li').length == 0){
$('ul.chat').html("<%= escape_javascript(render partial: 'messages/message', locals: {message: #message}) %>");
}
else {
$('ul.chat li:last').after("<%= escape_javascript(render partial: 'messages/message', locals: {message: #message}) %>");
}
That's it if I didn't miss something. Basically this code should add new message to database and render it on form send. Actually it saves to database but do not append it to the messages div. It gives 500 internal error. And what is most important in development machine the same exact code works like a charm, but in production it does not. This must be something with server or environment config I guess. Maybe someone has some ideas? Thanks in an advance.
ERROR IS HERE

Categories