JQuery can't find the Sub Category ID - javascript

I followed the instructions in this question's answer by emmanuel and the form now finds the Category ID and submits it but does not find the Sub Category ID associated with the Category and does not save it.
The params are taken which can be noted by this,
Parameters: {"utf8"=>"✓", "authenticity_token"=>"PTRTGGblf3HoWNXmanKl8TIP7F4j/QKTLN2Wd6oKSQWSXV27qioztUpXgb6YjHEroaWf8dgTzUIgQiRBK2XxWQ==", "post"=>{"title"=>"200k", "description"=>"FMxd123", "category_id"=>"2", "subcategory_id"=>"9"}, "commit"=>"Create Post"}
It then shows the error message on my screen (with my error partial) that "Sub Category must exist. The SQL output is like so:
(0.2ms) begin transaction
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
(0.0ms) rollback transaction
Rendering posts/new.html.erb within layouts/application
Rendered shared/_errors.html.erb (0.8ms)
Category Load (0.1ms) SELECT "categories".* FROM "categories"
CACHE (0.0ms) SELECT "categories".* FROM "categories"
SubCategory Load (0.1ms) SELECT "sub_categories".* FROM "sub_categories" WHERE "sub_categories"."category_id" = ? [["category_id", 1]]
SubCategory Load (0.1ms) SELECT "sub_categories".* FROM "sub_categories" WHERE "sub_categories"."category_id" = ? [["category_id", 2]]
SubCategory Load (0.1ms) SELECT "sub_categories".* FROM "sub_categories" WHERE "sub_categories"."category_id" = ? [["category_id", 3]]
My Posts.coffee:
jQuery ->
subcat = $('#subcategory-select').html()
$('#category-select').change ->
cat = jQuery('#category-select').children('option').filter(':selected').text()
options = $(subcat).filter("optgroup[label='#{cat}']").html()
if options
$('#subcategory-select').html(options)
else
$('#subcategory-select').empty()
And the part where category_id and sub_category_id are taken in the form with select boxes:
<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>
Confused as to how it isn't working because it made my category_id get saved when it wasn't working. Any ideas?

Gone through your code and I found some errors.
Here are the changes you should make to make your project work.
As you mentioned, it is not any jquery issue.
Error1:-
You have taken the subcategory model name as SubCategory and table is sub_categories, so the foreign key should be sub_category_id, but you have taken subcategory_id.
So either you have to change the column in the database, or tell rails to take the name.
Here are the changes to tell rails about it.
post.rb
class Post < ApplicationRecord
belongs_to :category
# belongs_to :sub_category
belongs_to :sub_category, class_name: 'SubCategory', foreign_key: 'subcategory_id'
end
sub_category.rb
class SubCategory < ApplicationRecord
belongs_to :category
# has_many :posts, :primary_key => "subcategory_id"
has_many :posts, class_name: 'Post', primary_key: 'id', foreign_key: 'subcategory_id'
end
Check the lines commented.
Now the post show view also has some errors which I solved.
Error2:-
posts/show.html.erb:
<% content_for :title, #post.title %>
<% navigation_add #post.title, post_path(#post) %>
<h2 align="center">Title: <%= #post.title %></h2>
<div class="well col-xs-8 col-xs-offset-2">
<h4 class="center description"><strong>Description:</strong></h4>
<hr>
<%= simple_format(#post.description) %>
<hr>
<p>Post ID: <%=#post.id%></p>
<hr>
<div class="post-actions">
<%= link_to "Edit this post", edit_post_path(#post), class: "btn btn-xs btn-primary" %>
<%= link_to "Delete this post", post_path(#post), method: :delete,
data: { confirm: "Are you sure you want to delete the post?"},
class: "btn btn-xs btn-danger" %>
<%= link_to "View all posts", posts_path, class: "btn btn-xs btn-success" %>
</div>
</div>
Last but not the least, your seeds.rb is wrong.
Error3:-
category_1 = Category.where(name:"cat1").first_or_create(name:"cat1")
category_2 = Category.where(name:"cat2").first_or_create(name:"cat2")
#SUB
# 1
SubCategory.where(name: 'g', category_id: category_1.id).first_or_create
SubCategory.where(name: 'er', category_id: category_1.id).first_or_create
#L2
SubCategory.where(name: 'tu', category_id: category_2.id).first_or_create
SubCategory.where(name: 'dual', category_id: category_2.id).first_or_create
Add this script to posts/new.html to get your dropdown work.
<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>
Here is the working image:

Related

Error in Rails 5 rendering form in partial: " undefined method `simple_fields_for' for "#<SimpleForm::FormBuilder "

This is a continuation from here:
Passing a form as a local to a ajax rendered partial in Rails 5
I've looked all over and can't find a solution that works.
Relevant Controller (profits_controller.rb):
def new_tabs
#market = Market.order('mjsnumber').all.first
#profit = Profit.new
profit_types_markets_products
end
def fetch_market
#market = Market.where(:id => params[:market_id]).first
#form = params["form"]
respond_to do |format|
format.js { render layout: false}
end
end
Relevant View (new_tabs.html.erb):
<%= simple_form_for #profit, :remote => true do |form| %>
<% #markets.each_with_index do |market, i| %>
<%= link_to market.nick, fetch_market_path(:market_id => market.id, :form => form, profit: #profit), :remote=>'true', :id => 'navBtn' + market.id.to_s, :class => 'd-flex flex-grow-1 align-content-center text-center nav-item nav-link ' + active(i).to_s + profit_nav_font_color(market.color).to_s, "data-toggle" => "pill", "roll" => "tab", "style" => "background-color: " + market.color.to_s + ";", remote: true %>
<% end %>
<%= render :partial => 'edit_partial_form', locals: { market: #market, form: form, profit: #profit } %>
Relevant Partial (_edit_partial_form.html.erb):
<%= market.namae %>
<%= form.simple_fields_for :figures, :defaults => { :input_html => { :class => "floatTextBox" }}, remote: true do |figures_form| %>
<%= figures_form.input "[test]" %>
<% end %>
Relevant JS (fetch_market.js.erb):
$("#edit_partial_form").html("<%= escape_javascript(render partial: 'edit_partial_form', locals: { market: #market, form: #form, profit: #profit } ) %>");
Routes:
resources :profits do
resources :markets
resources :products
collection do
get 'new_by_product_type'
get 'new_tabs'
end
end
get "/fetch_market" => 'profits#fetch_market', as: 'fetch_market'
patch 'profits/:id/autosave', as: :autosave_profit, to: 'profits#autosave'
It renders the partial fine, and the links appear to contain the FormBuilder information. When I click the link and add a "puts params" to the controller, it shows the params there. But then gives me an error when loading the partial in console:
ActionView::Template::Error (undefined local variable or method `form' for #<#<Class:0x00007fdbd6453648>:0x00007fdbd68db5f8>
Did you mean? fork):
1: $("#edit_partial_form").html("<%= escape_javascript(render partial: 'edit_partial_form', locals: { market: #market, form: form, profit: #profit } ) %>");
Full Error from local environment when I click on the link for the second market in the list of generated markets:
Processing by ProfitsController#fetch_market as JS
Parameters: {"form"=>"#<SimpleForm::FormBuilder:0x00007fed50dba9f8>", "market_id"=>"2"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ /home/mudl/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Market Load (0.3ms) SELECT "markets".* FROM "markets" WHERE "markets"."id" = $1 ORDER BY "markets"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/profits_controller.rb:75
Rendering profits/fetch_market.js.erb
Rendered profits/_edit_partial_form.html.erb (6.5ms)
Rendered profits/fetch_market.js.erb (7.5ms)
Completed 500 Internal Server Error in 12ms (ActiveRecord: 0.6ms)
ActionView::Template::Error (undefined method `simple_fields_for' for "#<SimpleForm::FormBuilder:0x00007fed50dba9f8>":String):
11: MJS 番後: <%= market.mjsnumber %>
12: </span>
13: </div>
14: <%= form.simple_fields_for :figures, :defaults => { :input_html => { :class => "floatTextBox" }}, remote: true do |figures_form| %>
15: <%= figures_form.input "[test]" %>
16: <% end %>
17:
app/views/profits/_edit_partial_form.html.erb:14:in `_app_views_profits__edit_partial_form_html_erb__249336059151108365_70328546926840'
app/views/profits/fetch_market.js.erb:1:in `_app_views_profits_fetch_market_js_erb___2023159631102932010_70328546933900'
app/controllers/profits_controller.rb:78:in `block (2 levels) in fetch_market'
app/controllers/profits_controller.rb:77:in `fetch_market'
(undefined method `simple_fields_for' for "#<SimpleForm::FormBuilder
I am removing the simple_form tag because after a simple test changing the simple_form to a regular form, the error persists with whatever method I call after field_for in the partial.
Thanks in advance.
EDIT:
So I ended up giving up and just using the #profit variable to make a new form in the partial (not ideal, but I'll hack it). Still curious if this is even possible, though, so I'll leave the question open..
So first of all you need to close your form block, then if you couldn`t pass form to partial then try to do this without partial
<%= simple_form_for #profit, remote: true do |form| %>
<% #markets.each_with_index do |market, i| %>
<%= link_to market.nick, fetch_market_path(market_id: market.id, form: form, profit: #profit), id: 'navBtn' + market.id.to_s, class: 'd-flex flex-grow-1 align-content-center text-center nav-item nav-link ' + active(i).to_s + profit_nav_font_color(market.color).to_s, "data-toggle" => "pill", "roll" => "tab", "style" => "background-color: " + market.color.to_s + ";", remote: true %>
<%= market.name %>
<% end %>
<%= form.simple_fields_for :figures, :defaults => { :input_html => { :class => "floatTextBox" }}, remote: true do |figures_form| %>
<%= figures_form.input "[test]" %>
<% end %>
<% end %>
And better to used something_key: "value" instead of this syntax :something_key => "value"

I want to validate a textbox to check negative value Like -100?

i create a simple banking app This is the Link For study purpose. alll the function are work charming but i weant to check validation if user enter Negative value like -100 so it shows error or alert message. so how can ii implement.
Thanks in advance :)
_form.html.erb
<%= form_for(#depositemoney) do |f| %>
<% if #depositemoney.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#depositemoney.errors.count, "error") %> prohibited this depositemoney from being saved:</h2>
<ul>
<% #depositemoney.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :balance %><br>
<%= f.number_field :balance %>
</div>
<%= f.hidden_field :u_id, :value => current_user.id %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Model.rb
class Depositemoney < ActiveRecord::Base
# validates :balance, :numericality => {:only_integer => true}
# validates :balance, presence: true
validates :balance, presence: true
# validates :balance, :inclusion => {:in => [1,2]}
validates :balance, format: { with: /\A\d+\z/, message: "Integer only. No sign allowed." }
end
I tried 3 Types of validations but it does not worrk for me so any one can help me out :)
:greater_than or :greater_than_or_equal_to option is that.
class Hoge < ApplicationRecord
validates :balance, numericality: { greater_than: 0 }
end
it works like below:
Loading development environment (Rails 5.1.4)
[1] pry(main)> Hoge.create(balance: 1)
(0.6ms) SET NAMES utf8mb4 COLLATE utf8mb4_general_ci, ##SESSION.sql_mode = CONCAT(CONCAT(##sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), ##SESSION.sql_auto_is_null = 0, ##SESSION.wait_timeout = 2147483
(0.1ms) BEGIN
SQL (12.2ms) INSERT INTO `hoges` (`balance`, `created_at`, `updated_at`) VALUES (1, '2017-10-18 06:06:18', '2017-10-18 06:06:18')
(11.1ms) COMMIT
[2] pry(main)> Hoge.create(balance: -1)
(0.2ms) BEGIN
(0.2ms) ROLLBACK
=> #<Hoge:0x007fa212e1cd80 id: nil, balance: -1, created_at: nil, updated_at: nil>
[4] pry(main)> Hoge.create(balance: -1).errors
(0.3ms) BEGIN
(0.2ms) ROLLBACK
=> #<ActiveModel::Errors:0x007fa20fcc37c0
#base=#<Hoge:0x007fa20f6c08f0 id: nil, balance: -1, created_at: nil, updated_at: nil>,
#details={:balance=>[{:error=>:greater_than, :value=>-1, :count=>0}]},
#messages={:balance=>["must be greater than 0"]}>
FYI: http://guides.rubyonrails.org/active_record_validations.html

How do I render my JS erb?

I have a save_video action on my NodesController that does this:
format.html { redirect_to video_tag_users_path(#video) }
What I want to happen is when it calls that action, it should render my tag_users.js.erb, but it is not.
This is my tag_users action:
def tag_users
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#node = #video.node
respond_to do |format|
format.html
format.js
end
redirect_to root_path
end
This is the log of what is happening:
Redirected to http://localhost:3000/videos/164/tag_users
Completed 302 Found in 23ms (ActiveRecord: 12.3ms)
Started GET "/videos/164/tag_users" for 127.0.0.1 at 2015-03-20 08:24:09 -0500
Processing by VideosController#tag_users as HTML
Parameters: {"video_id"=>"164"}
# truncated for brevity
Rendered videos/tag_users.html.erb within layouts/application (0.2ms)
This is the file I want it to render: tag_users.js.erb
$("#add-video-step-3").html("<%= escape_javascript(render 'videos/tag_users_in_video') %>");
Which then renders this modal _tag_users_in_video.html.erb:
<div class="bootstrap-styles" id="add-video-step-5">
<div class="modal-header">
<div class="titles clearfix">
<h2>Tag Users</h2>
<p><i>Step 3 of 3</i></p>
</div>
</div>
<div class="modal-body">
<div class="content">
<div>Tag someone</div>
<%= simple_form_for #node, url: add_tagged_user_node_path(#node), method: :post do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.association :user, label: "Users", collection: #users, as: :check_boxes, checked: #node.user_tags %>
</div>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-success ladda-button" %>
</div>
<% end %>
</div>
</div>
<div class="modal-footer">
</div>
</div>
Edit 1
So I changed the respond_to block in my tag_users action to this:
render 'tag_users.js'
But now it is actually rendering the JS rather than executing it and rendering the modal I want it to render.
i.e. this is what shows up in my browser, it redirects to URL localhost/videos/167/tag_users.js:
$("#add-video-step-3").html("<div class=\"bootstrap-styles\" id=\"add-video-step-5\"> \n <div class=\"modal-header\">\n <div class=\"titles clearfix\">\n <h2>Tag Users<\/h2>\n <p><i>Step 3 of 3<\/i><\/p>\n <\/div>\n <\/div>\n <div class=\"modal-body\">\n <div class=\"content\">\n <div>Tag someone<\/div>\n <form accept-charset=\"UTF-8\" action=\"/nodes/40/add_tagged_user\" class=\"simple_form edit_node\" id=\"edit_node_40\" method=\"post\" novalidate=\"novalidate\"><div style=\"display:none\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" /><input name=\"authenticity_token\" type=\"hidden\" value=\"Jj8CsHGzcNJJuJn9HGWjNaSjIfSJaZ8N81vmZ+Zp6KQ=\" /><\/div>\n \n \n <div class=\"form-inputs\">\n <div class=\"control-group check_boxes optional node_user\"><label class=\"check_boxes optional control-label\">Users<\/label><div class=\"controls\"><label class=\"checkbox\"><input class=\"check_boxes optional\" id=\"node_user_id_true\" name=\"node[user_id][]\" type=\"checkbox\" value=\"true\" />Yes<\/label><label class=\"checkbox\"><input class=\"check_boxes optional\" id=\"node_user_id_false\" name=\"node[user_id][]\" type=\"checkbox\" value=\"false\" />No<\/label><input name=\"node[user_id][]\" type=\"hidden\" value=\"\" /><\/div><\/div>\n <\/div> \n\n <div class=\"form-actions\">\n <input class=\"btn btn btn-success ladda-button\" name=\"commit\" type=\"submit\" value=\"Update Node\" />\n <\/div>\n<\/form> <\/div>\n <\/div>\n <div class=\"modal-footer\">\n <\/div>\n<\/div>");
That basically means that it is not rendering the HTML like I expect it to, but just spitting out the HTML from the view _tag_users_in_video.html.erb partial.
What I want to happen is for it to pop-up a modal that looks like the modal with id=add-video-step-3, but with the content I specified in _tag_users_in_video.html.erb.
Edit 2
The server log for the above action is:
Started GET "/videos/168/tag_users.js" for 127.0.0.1 at 2015-03-20 10:03:56 -0500
Processing by VideosController#tag_users as JS
Parameters: {"video_id"=>"168"}
User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (0.9ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.1ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.6ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (1.1ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 168]]
Node Load (1.1ms) SELECT "nodes".* FROM "nodes" WHERE "nodes"."media_id" = $1 AND "nodes"."media_type" = $2 LIMIT 1 [["media_id", 168], ["media_type", "Video"]]
ActsAsTaggableOn::Tag Load (1.8ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 41], ["taggable_type", "Node"]]
Rendered videos/_tag_users_in_video.html.erb (23.6ms)
Rendered videos/tag_users.js.erb (25.5ms)
Completed 200 OK in 196ms (Views: 23.1ms | ActiveRecord: 84.6ms)
Edit 3
So I added the JS render to the format.html inside my save_video action like you suggest. This is the code:
respond_to do |format|
if #node
format.html { render 'tag_users.js' }
format.js
end
end
This is what the result looks like:
Whereas I am trying to get it to look like this:
Edit 4
This is the save_video method in my controller (I left commented out code to see what has been tried with no success):
def save_video
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
if params[:status].to_i == 200
#video.update_attributes(:yt_video_id => params[:id].to_s, :is_complete => true)
#node = current_user.nodes.create!(family_tree: #family_tree, media: #video, name: #video.title, circa: #video.circa)
if #node
render 'tag_users.js'
end
# respond_to do |format|
# if #node
# format.html { }
# format.js
# end
# end
else
Video.delete_video(#video)
end
# respond_to do |format|
# format.html { redirect_to video_tag_users_path(#video, #node) }
# format.js
# end
# redirect_to root_path
# redirect_to video_tag_users_path(#video, #node)
end
Here is the server log for this permutation of the save_video action:
Started GET "/videos/172/save_video?status=200&id=bMaCxSIbJYU" for 127.0.0.1 at 2015-03-20 13:39:19 -0500
Processing by VideosController#save_video as HTML
Parameters: {"status"=>"200", "id"=>"bMaCxSIbJYU", "video_id"=>"172"}
User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (1.0ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.2ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.4ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (0.9ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 172]]
(0.9ms) BEGIN
SQL (1.3ms) UPDATE "videos" SET "is_complete" = $1, "updated_at" = $2, "yt_video_id" = $3 WHERE "videos"."id" = 172 [["is_complete", "t"], ["updated_at", "2015-03-20 18:39:19.959122"], ["yt_video_id", "bMaCxSIbJYU"]]
(1.5ms) COMMIT
(0.9ms) BEGIN
SQL (5.4ms) INSERT INTO "nodes" ("created_at", "family_tree_id", "media_id", "media_type", "name", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["created_at", "2015-03-20 18:39:19.967237"], ["family_tree_id", 57], ["media_id", 172], ["media_type", "Video"], ["name", "Outro 10PP"], ["updated_at", "2015-03-20 18:39:19.967237"], ["user_id", 57]]
(1.2ms) COMMIT
ActsAsTaggableOn::Tag Load (1.7ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 45], ["taggable_type", "Node"]]
Rendered videos/_tag_users_in_video.html.erb (10.3ms)
Rendered videos/tag_users.js.erb (12.7ms)
Edit 5
There is no front-end part that sends request to save_video. What happens is, the user fills out the form that appears in this modal:
<div id="overlay"> </div>
<div class="popup" id="add-video-step-4" data-step="4" data-intro="GETS TO UPLOADING">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 1 of 3</i></p>
</div>
<div class="content">
<% if #family_tree %>
<%= simple_form_for([#family_tree, #video], :remote => true) do |f| %>
<div class="column">
<div class="f-row">
<%= f.input :title, label: "Title:" %>
</div>
<div class="f-row">
<%= f.input :description,label: "Description:" %>
</div>
<div class="f-row">
<%= f.input :circa, as: :datepicker, start_year: Date.today.year - 5, label: "Circa:" %>
</div>
<div class="f-row">
<label for="family">Family in this video:</label>
<%= f.collection_select :user_ids, #family_tree.members.order(:first_name), :id, :first_name, {}, {multiple: true} %>
</div>
</div>
<%= f.button :submit, "Add Video", id: "video-submit" %>
<% end %>
<% end %>
</div> <!-- //content -->
</div> <!-- //popup -->
That modal then sends the request to this Create action in my Video controller:
def create
authorize! :read, #family_tree
#video = Video.new(video_params)
respond_to do |format|
if #video.save
format.html { redirect_to video_upload_path(#video) }
# format.json { render action: 'show', status: :created, location: #video }
else
format.html { render action: 'new' }
format.json { render json: #video.errors, status: :unprocessable_entity }
end
end
end
Which, if successful, then sends the request to this Video#Upload action:
def upload
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#upload_info = Video.token_form(#video, video_save_video_url(#video))
respond_to do |format|
## Note that I have been tinkering with this, but it doesn't work properly yet
format.html { redirect_to video_tag_users_path(#video, #node) }
format.js
end
end
Which first sends to the video_save in the assignment statement.
Hope that provides clarity.
Edit 6
This is the contents of my application.js
//= require jquery
//= require jquery_ujs
//= require best_in_place
//= require bootstrap-sprockets
//= require jquery-ui/datepicker
//= require best_in_place.jquery-ui
//= require jquery.purr
//= require best_in_place.purr
//= require bootstrap.file-input
//= require chosen.jquery
//= require main.js
//= require spin.min
//= require ladda.min
//= require masonry.js
//= require introjs
//= require pnotify
$(document).ready(function(){
$("input.datepicker").datepicker();
/* Activating Best In Place && Include Success Highlighting & Bounce for comments & videos */
$(".best_in_place").best_in_place().bind("ajax:success", function () {$(this).closest('p, h5').effect('highlight').effect("bounce", { times:3 }, { duration:400}).dequeue(); });
$('.dropdown-toggle').dropdown();
$('#unread-notification').click(function(){
var url = $(this).data('read-url');
$.ajax({
type: "PUT",
url: url
});
});
});
Edit 7
Here is the server log after the first create is called:
Started POST "/family_trees/57/videos" for 127.0.0.1 at 2015-03-23 15:05:46 -0500
Processing by VideosController#create as JS
Parameters: {"utf8"=>"✓", "video"=>{"title"=>"Hello There", "description"=>"This is an interesting video", "circa"=>"", "user_ids"=>[""]}, "commit"=>"Add Video", "family_tree_id"=>"57"}
User Load (15.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (5.6ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
FamilyTree Load (2.2ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."id" = $1 LIMIT 1 [["id", 57]]
(2.3ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.8ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
(2.6ms) BEGIN
SQL (6.1ms) INSERT INTO "videos" ("created_at", "description", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", "2015-03-23 20:05:46.637067"], ["description", "This is an interesting video"], ["title", "Hello There"], ["updated_at", "2015-03-23 20:05:46.637067"]]
(2.8ms) COMMIT
Redirected to http://localhost:3000/videos/177/upload
Completed 302 Found in 84ms (ActiveRecord: 39.2ms)
Started GET "/videos/177/upload" for 127.0.0.1 at 2015-03-23 15:05:46 -0500
Processing by VideosController#upload as JS
Parameters: {"video_id"=>"177"}
User Load (2.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 57 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (1.9ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 57]]
(1.3ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 57]]
Membership Load (1.7ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 57 AND "memberships"."family_tree_id" = 57
Video Load (2.8ms) SELECT "videos".* FROM "videos" WHERE "videos"."id" = $1 LIMIT 1 [["id", 177]]
Rendered videos/_upload_video.html.erb (4.6ms)
Rendered videos/upload.js.erb (7.6ms)
Completed 200 OK in 344ms (Views: 23.7ms | ActiveRecord: 10.3ms)
Edit 8
_upload_video.html.erb
<div class="bootstrap-styles" id="add-video-step-3">
<div class="modal-header">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 2 of 3</i></p>
</div>
</div>
<div class="modal-body">
<div class="content">
<%= form_tag #upload_info[:url], :multipart => true do %>
<%= hidden_field_tag :token, #upload_info[:token] %>
<div class="uploader clearfix">
<%= file_field_tag :file, title: 'SELECT FILE TO UPLOAD', class: "upload" %>
</div>
<button class="btn btn-success ladda-button" data-color="green" data-style="expand-left"><span class="ladda-label">Upload Video</span><span class="ladda-spinner"></span></button>
<% end %>
</div>
</div>
<div class="modal-footer">
</div>
</div>
upload.js.erb
$("#add-video-step-4").html("<%= escape_javascript(render 'videos/upload_video') %>");
Assuming this is your code
def tag_users
authorize! :read, #family_tree
#video = Video.find(params[:video_id])
#node = #video.node
respond_to do |format|
render format.html
format.js
end
end
And, by looking at output i can say that server is receiving HTML as format. Since, you want to execute script you must send datatype to script.
Looking at html code, i think you have to pass data: {type: "script"} to simple_form function, so it will be
<div id="overlay"> </div>
<div class="popup" id="add-video-step-4" data-step="4" data-intro="GETS TO UPLOADING">
<div class="titles clearfix">
<h2>Upload a Video</h2>
<p><i>Step 1 of 3</i></p>
</div>
<div class="content">
<% if #family_tree %>
<%= simple_form_for([#family_tree, #video], :remote => true, data: {type: "script"} ) do |f| %>
<div class="column">
<div class="f-row">
<%= f.input :title, label: "Title:" %>
</div>
<div class="f-row">
<%= f.input :description,label: "Description:" %>
</div>
<div class="f-row">
<%= f.input :circa, as: :datepicker, start_year: Date.today.year - 5, label: "Circa:" %>
</div>
<div class="f-row">
<label for="family">Family in this video:</label>
<%= f.collection_select :user_ids, #family_tree.members.order(:first_name), :id, :first_name, {}, {multiple: true} %>
</div>
</div>
<%= f.button :submit, "Add Video", id: "video-submit" %>
<% end %>
<% end %>
</div> <!-- //content -->
</div> <!-- //popup -->
See here Why I need add "data: {type: "script"}" on remote link with rails / ajax
If you want to use the redirect, you might just try adding a format to the redirect path:
format.html { redirect_to video_tag_users_path(#video, format: :js) }

Updating URL query string with JS / Rails and a dropdown form

I am looking to update a url when a selection is made from a dropdown. I would like to have the query to be dynamic, here is the following code:
<select id="mySchool" onchange="this.form.submit()">
<% #schools.each do |school| %>
<option value="<%= school.id %>"><%= school.name %></option>
<% end %>
</select>
<%= link_to "Apply School", "schools/assign_users?user_id=#{#user.id}&school_id=", :class => "btn btn-primary", :type => "button" %>
Can anyone point me in the right direction?
This is not the best way to create select in rails. You should rather use rails select_tag helper like this:
<%= select_tag 'school_id', options_for_select(#schools.collect{ |s| [u.name, u.id] }), id: "mySchool" %>
I am looking to update a url when a selection is made from a dropdown.
I think instead of showing the link upfront you should show the link only when a user select a value from dropdown so your code should be something like this:
<%= select_tag 'school_id', options_for_select(#schools.collect{ |s| [u.name, u.id] }), id: "mySchool" %>
<div id="schoolLink"></div>
#_link.html.erb
<%= link_to "Apply School", "schools/assign_users?user_id=#{user.id}&school_id=#{school.id}", :class => "btn btn-primary", :type => "button" %>
Now make a route to which you want to send the ajax request to:
post 'selected_school/:id' => 'school#selected', as: "select_school"
write a js function which will send ajax request on changing values in dropdown
$(document).on("change","#mySchool",function(e){
var school_id = $(this).val();
$.ajax({
type: "POST",
url: "/selected_school",
data: {id : school_id }
});
});
Find school and user inside controller and then finally render link by js
#school_controller.rb
def selected
#school = School.find(params[:id]) # find school by the passed id
#user = current_user # your logic to find user
end
#app/views/school/selected.js
$("#schoolLink").html("<%=j render partial: 'link', locals: {user: #user, school: #school} %>");
For details checkout Working with Javascript in Rails

Delete nested comments with Ajax

I'm having some issues deleting my comments with Ajax. I think I'm close but not sure and would like some advice. Still getting used to jquery and such. I can remove the comment via ajax but not actually delete the record itself so maybe its a simple syntax issue.
destroy.js.erb
$('#remove_comment').remove();
I think I need to tag this with the comment ID but I'm having issues being as the comments are nested under the Pit model.
_comment.html.erb
<div class = "well", id = "remove_comment">
<p>
<%= comment.body %>
<p>posted by: <%= comment.user.name %></p>
<div class = "response">
<p class = "like-response">Was this response persuading to you?</p>
<%= link_to "Yes", pit_comment_like_path(#pit, comment), method: :put %>
<%= link_to "No", pit_comment_dislike_path(#pit, comment), method: :put %>
</div>
<div class = "response-convince">
<p class = "dislike-comment">
<%= comment.get_dislikes.size %> users found this response unpersuasive
</p>
<p class = "like-comment">
<%= comment.get_likes.size %> users found this response persuasive</p>
</p>
</div>
<p>
<%if comment.user == current_user %>
<%= link_to 'Destroy Comment', [#pit, comment],
method: :delete,
data: { confirm: 'Are you sure?' }, remote: true, class: "btn btn-default" %>
</p>
<% end %>
</div>
Comments Controller
def destroy
#pit = Pit.find(params[:pit_id])
#comment = #pit.comments.find(params[:id])
#comment.destroy
respond_to do |format|
format.html {redirect_to pit_path(#pit)}
format.js {}
end
Logs seem to be working properly
Started DELETE "/pits/398/comments/63" for 127.0.0.1 at 2014-09-11 12:31:08 -0500
Processing by CommentsController#destroy as JS
Parameters: {"pit_id"=>"398", "id"=>"63"}
Pit Load (0.1ms) SELECT "pits".* FROM "pits" WHERE "pits"."id" = ? LIMIT 1 [["id", 398]]
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."pit_id" = ? AND "comments"."id" = ? LIMIT 1 [["pit_id", 398], ["id", 63]]
(0.1ms) begin transaction
ActsAsVotable::Vote Load (0.1ms) SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? [["votable_id", 63], ["votable_type", "Comment"]]
SQL (0.3ms) DELETE FROM "comments" WHERE "comments"."id" = ? [["id", 63]]
(3.0ms) commit transaction
Rendered comments/destroy.js.erb (0.5ms)
Completed 200 OK in 13ms (Views: 3.9ms | ActiveRecord: 3.7ms)
This is the associated markup I have in pits/show.html.erb
<h3>Responses</h3>
<div id = "comment_body">
<%= render #pit.comments %>
</div>
<%= render partial: "comments/form" %>
pit.rb
class Pit < ActiveRecord::Base
validates :topic, :author, :summary, presence: true
acts_as_votable
has_many :comments
belongs_to :user
mount_uploader :image, ImageUploader
end
comment.rb
class Comment < ActiveRecord::Base
acts_as_votable
belongs_to :pit
belongs_to :user
end
Everything inserts correctly with my create.js.erb. I just need to remove it and I think I need to pass in the comment ID or something to that effect. Any advice here would be appreciated. Thanks.
Actually, the comment is being DELETED as logs shows the query:
SQL (0.3ms) DELETE FROM "comments" WHERE "comments"."id" = ? [["id", 63]]
I guess your jQuery doesn't remove the appropriate comment after the callback. You can try changing view code of _comment.html.erb:
<div class = "well", id = "remove_comment_<%= comment.id %>">
<p>
<%= comment.body %>
And then your destroy.js.erb:
$("#remove_comment_<%= #comment.id %>").remove(); // Since #comment will be available in the variable here!
create a link_to with a data-id attribute, when clicked use jquery to make a GET request to your controller.
First, create a route for the delete action in your config/routes.rb:
get 'delete_comment' => 'comments#delete_comment'
Next, add a method to your controller (assumably CommentsController):
def delete_comment
#comment = Comment.find(params[:id])
#comment.destroy
end
Now, set up a link in your view:
= link_to "Remove Comment", "#", :class => "remove_comment", :'data-id' => #comment.id
Now set up the jquery GET request to fire when you click on the link:
$(".remove_comment").click(function(event){
event.preventDefault();
$.get("/delete_comment", {id: $(this).attr("data-id") } );
});
In this example, you would need to rename your delete.js.erb file to delete_comment.js.erb

Categories

Resources