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?
Related
I have a search form on my page with two buttons - "news" and "events".
I can get the Rails search function to work correctly but I don't want a search form, I want the user to press one of the two buttons and the search to be executed.
I figure this probably has to be done with JQuery so when a button is clicked, either "news" or "events" are added to the rails input form and it submits the form. Please appreciate where I'm going wrong here as the form won't submit and the search won't execute.
Application.js
$(document).on('ready page:load', function () {
$(".news-button").click(function(){
$("#search").val("news");
$("#news-search").submit();
});
$(".events-button").click(function(){
$("#search").val("event");
$("#news-search").submit();
});
});
Index.html.erb
<%= form_tag news_index_path, :method => 'get', :id => "news_search" do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<div class="col-sm-3 sort-buttons">
<%= link_to "News", "", class: "btn btn-standard news-button" %>
<%= link_to "Events", "", class: "btn btn-standard events-button" %>
</div>
<div class="row">
<% #news.each do |n| %>
<div class="col-sm-4">
<div class="news-wrap">
<%= image_tag("#{n.image}", class: "img-responsive", alt: "Event/News Postings") %>
</div>
</div>
<% end %>
</div>
News.rb
class News < ApplicationRecord
if Rails.env.development?
def self.search(search)
if search
where('category LIKE ?', "%#{search}%")
else
scoped
end
end
end
end
News Controller:
def index
if params[:search]
#news = News.search(params[:search]).page(params[:page]).per_page(10)
else
#news = News.all.page(params[:page]).per_page(10)
end
end
I am try to render my comments with ajax in my rails app...but it is not working and the comments diplay just after I redirect the page...so the comment get created successfully but the problem is rendering comments with ajax and jquery!!!!
I have this lines in my application.html.erb:
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
and this require line in my application.js:
//= require jquery
//= require jquery_ujs
here is my show.html.erb file under posts :
<div id="posts" class="transitions-enabled">
<div class="box panel panel-default">
<%= render 'post', post: #post %>
</div>
</div>
my _post partial:
<div class="panel-body">
<%= link_to image_tag(post.user.avatar.url, size: "50x50", class: "img-circle"), profile_path(post.user.user_name) %>
<ul class="posts-shows">
<li><strong><%= link_to post.user.user_name, profile_path(post.user.user_name) %></strong></li>
<li><small><%= link_to "#{time_ago_in_words(post.created_at)} ago", post_path(post), class: "time-link" %></small></li>
</ul>
<p class="disc-posts"><%= post.description %></p>
<%= link_to image_tag(post.image.url(:large), class: "img-responsive img-in" ) %><br/>
<% if post.user == current_user %>
<div><%= link_to "Edit", edit_post_path(post) %> | <%= link_to "delete", post, method: :delete, data: {confirm: "Are you sure?"} %> </div>
<% else %>
<div><%= link_to "Repost", repost_post_path(post), method: :post, data: { confirm: "Are you sure?"} if user_signed_in? %></div>
<% end %>
</div>
<div class="panel-footer">
<div class="comment-form">
<%= form_for([post, post.comments.build], remote: true) do |f| %>
<%= f.text_field :content, placeholder: 'Add a comment...', class: "form-control comment_content", id: "comment_content_#{post.id}" %>
<% end %>
</div>
<div class="comments" id= "comments_#{post.id}">
<% if post.comments.present? %>
<%= render post.comments, post: post %>
<% end %>
</div>
</div>
my _comment.html.erb in comments folder:
<% if comment.user_id.present? %>
<div id="comment">
<%= link_to image_tag(post.user.avatar.url, size: "30x30", class: "img-circle img-comments"), profile_path(comment.user.user_name) %>
<div class="user-name">
<%= link_to comment.user.user_name, profile_path(comment.user.user_name), class: "username-size" %>
</div>
<div class="comment-content">
<%= comment.content %>
</div>
</div>
<% end %>
and here is the create.js.erb under comments folder :
$('#comments_<%= #post.id %>').append("<%=j render 'comments/comment', post: #post, comment: #comment %>");
$('#comment_content_<%= #post.id %>').val('')
and my comments controller:
class CommentsController < ApplicationController
before_action :set_post
def index
#comments = #post.comment.all
end
def new
#comment = #post.comments.build(comments_params)
end
def create
#comment = #post.comments.build(comments_params)
#comment.user_id = current_user.id
if #comment.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
else
flash[:alert] = "Check the comment form, something went horribly wrong."
render root_path
end
end
def destroy
#comment = #post.comments.find(params[:id])
#comment.destroy
flash[:success] = "Comment deleted :("
redirect_to root_path
end
private
def comments_params
params.require(:comment).permit(:content)
end
def set_post
#post = Post.find(params[:post_id])
end
end
I don't think this line is right -
<div class="comments" id= "comments_#{post.id}">
I think you need this
<div class="comments" id= "comments_<%= post.id %>">
I'm trying to render an edit form when someone clicks on an object in a list.
I made a test action in my controller like this:
def test
respond_to do |format|
format.js
end
end
In my view I made a link like this:
<%= link_to image_tag('icons/edit3.png'),
:remote => true,
:controller => :aliens,
:id => alien.expansion.id,
:ph_id => alien.id,
:action => :test
%>
and in my test.js.erb
console.log('testing');
I also made a custom route
get 'expansions/:id/aliens/:ph_id/test' => 'aliens#test', as: :test
This works great. Everytime I click on an object it prints out in the console.
The problem is that I want the .js.erb to render the form. BUT, if I add this code to the js:
$('.dialog__content').append('<%= j render :partial => 'editform', :formats => :html %>');
or
$('.dialog__content').html("<%= j render(#editform) %>'");
or
$('.dialog__content').html("<%= escape_javascript (render partial: 'editform') %>");
It returns GET "My path" 404 (Not Found)
And If I add variables to my action like this:
def test
#aliens = Alien.all
#expansions = Expansion.all
#expansion = Expansion.find(params[:expansion_id])
#alien = #aliens.find(params[:id])
respond_to do |format|
format.js
end
end
It also returns: GET "My path" 404 (Not Found)
What should I do?
Thanks.
Update:
My editform partial,
Seems like the variables is the problem. I tried rendering a partial with only html in it, and that works fine.
<div class="hidden_form form_holder">
<%=form_for [#expansion, #alien], :remote => true, :html => {:class => "add edit", :multipart => true } do |f| %>
<h2>Rediger Alien </h2>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :difficulty %>
<%= f.select :difficulty, ['Beginner', 'Intermediate', 'Hard']%>
<%= f.label :tokens %>
<%= f.number_field :tokens %>
<div class="clearfix">
<div class="byside">
<%= f.check_box :gamesetup %>
<%= f.label :gamesetup, :class => 'check'%>
</div>
<div class="byside">
<%= f.file_field :avatar %>
</div>
</div>
<%= f.submit %>
<% end %>
</div>
I've got a form 'tasks' and I am dynamically adding a child 'steps' form.
The 'steps' is added through a javascript call to render('steps/form').
The form loads fine, but when submitting the tasks form, the added step is not put into the database.
I assume this is because I'm not linking the two forms together, but I'm not entirely sure.
My code is
Tasks/new.html.erb
<%= form_for #task, :html=>{:multipart=>true} do |f| %>
<%= f.label :task_name %>
<%= f.text_field :task_name %>
<%= link_to "Add Step", #step, :remote=>true, :class=>'addStep %>
<%= f.submit %>
<% end %>
<% content_for(:js) do %>
$('a.addStep').click(function(){
$('div#newStep').append("<%= escape_javascript(render('steps/form'))%>");
});
<% end %>
the steps/_form.html.erb is
<p class="fields">
<%= fields_for :steps do |builder| %>
<%= builder.label :title %>
<%= builder.text_field :title %>
<% end %>
I believe the problem is that i'm not passing 'f' or 'task' into the 'step' form, but I couldn't figure out how to do that.
Try something like this:
<%= render :partial => 'steps/form',
:locals => {:form => f} %>
Hope this helps.
Edit- 1
Do as follows:
<%= form_for #task, :html=>{:multipart=>true} do |f| %>
<%= f.label :task_name %>
<%= f.text_field :task_name %>
<div style="display:none;" id="steps_form">
<%= render :partial => 'steps/form',
:locals => {:form => f} %>
</div>
<%= link_to "Add Step", #step, :onClick=>"js_function_to_change_display_property()", :class=>'addStep' %>
<%= f.submit %>
<% end %>
then you can use simple javascript to view the steps form by changing the display property of steps_form.
You might have to update the params in your parent controller to include the attributes of the child. e.g.
controllers/task_controller.rb
Class TasksController < ApplicationController
...
def task_params
params.require(:task).permit :name, :description ,
steps_attributes: [:step, :step_description, :due_date]
end
end
models/task.rb
Class Task < ActiveRecord::Base
has_many :steps
accepts_nested_attributes_for :steps
end
models/step.rb
Class Step < ActiveRecord::Base
belongs_to :task
end
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