How to automatically submit all forms with checked check_box? - javascript

A user is given the command "Choose 5 Inspirations"
A list of 20+ inspirations are shown.
There is a check_box on the top right hand corner of each inspirational panel.
<% #inspirations.each do |inspiration|
<%= simple_form_for(current_user.inspirations.build) do |f| %>
<%= f.check_box :check %>
<%= inspiration.name %>
<% end %>
<% end %>
<script>
# How to make script where once a 5th check_box is checked then submit all forms with :check automatically?
# Below is work in progress...
$(function () {
$('input[type=checkbox]').is(':checked').length;
form.submit();
})
</script>
What javascript is needed to make this work?
UPDATE
fast_track_one.html.erb
<%= simple_form_for(current_user.inspirations.build) do |f| %>
<% #inspirations.each do |inspiration| %>
<%= check_box_tag 'inspiration_ids[]', inspiration.id %>
<%= inspiration.name %>
<% end %>
<% f.submit %>
<% end %>
<script>
$(document).on('click', 'input[name="inspiration_ids[]"]', function() {
var count = $('input[name="inspiration_ids[]"]:checked').length;
if (count === 5) {
$('#new_inspiration').trigger('submit.rails');
}
});
</script>
inspirations_controller.rb
class InspirationsController < ApplicationController
respond_to :html, :json
before_action :set_inspiration, only: [:show, :like]
before_action :correct_user, only: [:edit, :update, :destroy]
def fast_track_one
#suggestions_user = User.find(1)
#inspirations = #suggestions_user.inspirations
if params[:inspiration_ids].present? && params[:inspiration_ids].size == 5
#inspirations = Inspiration.where(id: params[:inspiration_ids])
#inspirations.each do |inspiration|
current_user.inspirations << inspiration
end
end
end
def index
if params[:tag]
#inspirations = Inspiration.tagged_with(params[:tag])
else
#inspirations = current_user.inspirations.order("created_at DESC") if current_user.inspirations.present?
end
end
def show
#commentable = #inspiration
#comments = #commentable.comments
#comment = Comment.new
#notable = #inspiration
#notes = #notable.notes
#note = Note.new
if current_user
#correct_user = current_user.inspirations.find_by(id: params[:id])
else
#correct_user = nil
end
end
def new
#suggestions_user = User.find(21) #1 in Development
#inspirations = #suggestions_user.inspirations.top_6
#maximum_length = Inspiration.validators_on( :name ).first.options[:maximum]
existing_inspiration = Inspiration.find_by_id params[:inspiration_id]
if existing_inspiration
#inspiration = existing_inspiration.dup
elsif params[:inspiration].try(:[], :name)
#inspiration = Inspiration.new(inspiration_params)
else
#inspiration = current_user.inspirations.build
end
respond_modal_with #inspiration
end
def edit
#suggestions_user = User.find(21)
#maximum_length = Inspiration.validators_on( :name ).first.options[:maximum]
#inspirations = #suggestions_user.inspirations.order("created_at DESC")
existing_inspiration = Inspiration.find_by_id params[:inspiration_id]
if existing_inspiration
#inspiration = existing_inspiration.dup
#inspiration.image_file_name = existing_inspiration.image_file_name
end
respond_modal_with #inspiration
end
def create
##suggestions_user = User.find(21)
##inspirations = #suggestions_user.inspirations.order("created_at DESC")
if current_user == nil
# If there is no user, store the lifetime values to the session.
session[:inspiration_name] = inspiration_params[:name]
session[:inspiration_image] = inspiration_params[:image]
redirect_to signup_path
else
##inspiration.image_remote_url = params[:inspiration_image]
#inspiration = current_user.inspirations.build(inspiration_params)
if #inspiration.conceal == true
#inspiration.save
if current_user.inspirations.count < 5
redirect_to root_url
else
respond_modal_with #inspiration
end
flash[:info] = 'INSPIRATION SECRETLY SAVED. YOUR INSPIRATIONS ARE RANDOMIZED ON YOUR HOME PAGE TO GIVE YOU A FRESH SPARK OF INSPIRATION - EVERY TIME!'
elsif
#inspiration.save
track_activity #inspiration
if current_user.inspirations.count < 5
redirect_to root_url
else
respond_modal_with #inspiration
end
flash[:info] = 'INSPIRATION SAVED. YOUR INSPIRATIONS ARE RANDOMIZED ON YOUR HOME PAGE TO GIVE YOU A FRESH SPARK OF INSPIRATION - EVERY TIME!'
else
respond_modal_with #inspiration
end
end
end
def update
if #inspiration.update(inspiration_params)
respond_modal_with #inspiration, location: root_path
flash[:info] = 'INSPIRATION UPDATED'
else
respond_modal_with #inspiration
end
end
def destroy
#inspiration.destroy
redirect_to root_path
flash[:alert] = 'INSPIRATION DELETED'
end
def like
if current_user
#inspiration_like = current_user.inspiration_likes.build(inspiration: #inspiration)
if #inspiration_like.save
#inspiration.increment!(:likes)
flash[:info] = 'THANKS FOR LIKING!'
else
flash[:alert] = 'TWO MANY LIKES!'
end
redirect_to(:back)
else
redirect_to root_path
flash[:alert] = "PLEASE SIGN IN FIRST"
end
end
private
def set_inspiration
#inspiration = Inspiration.find(params[:id])
#redirect_to root_url unless #inspiration.user_id == current_user.id or #inspiration.conceal == false
end
def correct_user
#inspiration = current_user.inspirations.find_by(id: params[:id])
redirect_to root_url, notice: "NOT AUTHORIZED TO INSPIRATION" if #inspiration.nil?
end
def inspiration_params
params.require(:inspiration).permit(:name, :image, :conceal, :tag_list, :content, :commentable, :comment, :like, :check, :image_file_name, :image_content_type, :image_file_size, :image_updated_at)
end
end

Maybe you could try something like this:
<script>
$(document).on('change', 'input[type=checkbox]', function() {
if ($('input[type=checkbox]').is(':checked').length == 5) {
$('form').submit(); // form should be selected as DOM element
}
})
</script>

Use a rails form helper for a check box tag.
<%= simple_form_for(current_user.inspirations.build) do |f| %>
<% #inspirations.each do |inspiration|
<%= check_box_tag 'inspiration_ids[]', inspiration.id %>
<%= inspiration.name %>
<% end %>
<% f.submit %>
<% end %>
Access in the controller with:
if params[:inspiration_ids].present? && params[:inspiration_ids].size == 5
#inspirations = Inspiration.where(id: params[:inspiration_ids])
#inspirations.each do |inspiration|
current_user.inspirations << inspiration
end
end
Javascript:
$(document).on('click', 'input[name="inspiration_ids[]"]', function() {
var count = $('input[name="inspiration_ids[]"]:checked').length;
if (count === 5) {
$('#new_inspiration').trigger('submit.rails');
}
});

Your actual code was as below:
<% #inspirations.each do |inspiration| # this line should be inside simple_form_for tag
<%= simple_form_for(current_user.inspirations.build) do |f| %>
<%= f.check_box :check %>
<%= inspiration.name %>
<% end %>
<% end %>
which generate form multiple times, instead of your code replace below code which generates only one form with multiple checkboxes.
So here is the final code with JS. Hope this will solve your issue.
<%= simple_form_for(current_user.inspirations.build) do |f| %>
<% #inspirations.each do |inspiration|
<%= f.check_box :check %>
<%= inspiration.name %>
<% end %>
<% end %>
<script>
$(document).on('change', 'input[type=checkbox]', function() {
if ($('input[type=checkbox]').is(':checked').length == 5) {
$('form').submit(); // form should be selected as DOM element or form id or form class like: $('.fomaClass') or $('#formId')
}
});
</script>
Refer check_box API doc form set value in a checkbox, So when you submit the form you will get the value.

Related

multipleselect is forgeting selected values after proceed

Multiplyselect is forgetting owners values after searching.
After proceed i got params[:search] and params[:owners] but only input for search is filled-in. This is my code.
def index
#all_owners = Owner.select('distinct name').pluck(:name)
#animal = Animal.search(params[:search])
#animal = #animals.joins(:owners).where("owners.name IN (?) ", params[:owners].present? ? params[:owners] : #owners)
end
#------------------------------------------
<%= form_tag animals_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search]%>
<%= select_tag :owners, options_for_select(#all_owners),id: "multiselect-id", multiple: true %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% #aminals.each do |animal| %>
<%= animal.name %>
<%= animal.owners.map(&:name).join(', ') %>
<% end %>
<script type="text/javascript">
$(document).ready(function() {
$('#multiselect-id').select2();
});
</script>
You forgot to specify the currently selected values in the select_tag. This is done e.g. by a second argument to the options_for_select helper, i.e. something like: options_for_select(#all_owners, params[:owners] || #owners).
See the docs here.

Rails AJAX Destroy - Re-render index issues

I have an issue with a Rails AJAX app which is confusing me, even though it seems very simple! I am dealing with class Order in a simple point of sale rails app. The request is being made as the order will be deleted on page refresh (but I am getting no refresh of #orders) as I thought I am specifying in destroy.js.erb.
orders/index.html
<div id="orders">
<%= render 'orders/index' %>
</div>
<%= link_to 'New Order', new_order_path, remote: true %>
<div id="order-form" style="display:none;"></div>
orders/_index.html
<% if #orders.any? %>
<% #orders.each do |order| %>
<%= link_to "Show #{order.id}", order_path(order), class: "something" %>
<%= link_to "Delete #{order.id}", order_path(order), method: :delete, class: "something" %>
<%= link_to "Delete order with ajax", order_path(order), remote: true, method: :delete %>
<% end %>
<% else %>
<p>No orders yet</p>
<% end %>
destroy.js.erb
//When deleting order on order index - render orders again.
$('#orders').html("<%= j (render 'orders/index') %>");
and the relevant actions from orders_controller.rb
class OrdersController < ApplicationController
respond_to :html, :js
def index
#orders = Order.paginate(page: params[:page])
if params[:search]
#orders = Order.search(params[:search]).order("created_at DESC")
else
#orders = Order.all.order('created_at DESC')
end
end
def destroy
#order = Order.find(params[:id])
if #order.destroy
flash[:notices] = ["Order was successfully deleted"]
redirect_to orders_path
else
flash[:notices] = ["Order could not be deleted"]
render order_path(#order)
end
end
I suspect the issue is in my orders_controller destroy or index action, but I am a little unclear on a number of the ways of working with AJAX in Rails.
Link to repo - https://github.com/benhawker/point-of-sale-rails
Might be because after your destroy you're redirecting to the index path
I am getting no refresh of #orders
Your JS is likely not firing, you'll need the following:
def destroy
#order = Order.find params[:id]
respond_to do |format|
if #order.destroy
format.js
format.html { redirect_to orders_path, notice: "Order was successfully deleted" }
else
format.js
format.html { render order_path(#order), notice: "Order could not be deleted" }
end
end
end
This will fire app/views/orders/destroy.js.erb, which seems okay in your OP.
Try Updating your destroy action to
#order = Order.find(params[:id])
#order.destroy
#orders=Order.all
remove all the redirects
will work.

Prevent form being submitted until final button - avoid edit page

I know there are a lot of similar questions on SO but I haven't found one that fits what I'm trying to do...(because I'm not 100% sure it is even possible to do what I am trying to do!!)
At the moment I have a page that creates several form_tags based on how many 'questions' there are in the 'test', like this:
<div class="jumbotron">
<% #test.questions.each do |question| %>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Question <%= question.question %></h3>
</div>
<div class="panel-body">
<p>
<%= image_tag question.image.url(:medium) %>
</p>
<%= form_tag edit_test_testsession_path(#test, question.testsessions), id: 'submit_answer' do %>
<%= radio_button_tag :answer, "A" %> A
<%= radio_button_tag :answer, "B" %> B
<%= radio_button_tag :answer, "C" %> C
<%= radio_button_tag :answer, "D" %> D
<%= submit_tag 'Submit', class: "btn btn-success", id: 'single_submit' %>
<% end %>
</div>
</div>
<% end %>
<br/>
<%= link_to "See Test Results!", results_path(#test), class: "btn btn-lg btn-info btn-block", id: "submit_all" %>
</div>
At the moment I have disabled the 'submit' buttons because I don't want the forms to actually be submitted until all of them are completed so I have this Javascript:
$(document).ready(function() {
$('.btn.btn-success').click(function(e) {
e.preventDefault();
this.value="Resubmit";
});
$('#submit_all').click(function(){
$('#submit_answer').each(function(){
$(this).submit();
});
});
});
It does attempt to submit the answers but still tries to take the user to an edit page, but of several [:id], which obviously doesn't work...
In my TestsessionsController I have this:
class TestsessionsController < ApplicationController
def new
#test = Test.find(params[:test_id])
#testsession = Testsession.new
redirect_to action: :create
end
def create
#test = Test.find(params[:test_id])
#test.questions.each do |question|
#test.testsessions.create user: current_user, question: question
end
redirect_to action: :index
end
def index
#test = Test.find(params[:test_id])
#questions = #test.questions
# #testsession = Testsession.find(params[:id])
end
def show
#testsession = Testsession.find(params[:id])
#test = Test.find(params[:test_id])
#questions = #test.questions
end
def update
#testsession = Testsession.find(params[:id])
# #question = Question.find(params[:question_id])
#testsession.update(params.require(:testsession).permit(:answer))
redirect_to action: :results
end
def edit
#testsession = Testsession.find(params[:id])
#question = Question.find(params[:question_id])
#testsession.update(params.require(:testsession).permit(:answer))
redirect_to action: :results
end
def results
#test = Test.find(params[:id])
#testsession = Testsession.find(params[:id])
end
end
Is there any way to force the last link to take it directly to the results page, but still submit the information from the form_tags?
At the moment it is just giving me this error:
No route matches [POST] "/tests/1/testsessions/%23%3CTestsession::ActiveRecord_Associations_CollectionProxy:0x007fe197a72e40%3E/edit"
and only when I hit the back button it takes me to the results page...
EDIT
config/routes file:
Rails.application.routes.draw do
devise_for :users
root 'welcome#index'
get 'tests/:id/testsessions/new' => 'testsessions#create'
get 'tests/:id/testsessions/results' => 'testsessions#results', as: :results
resources :tests do
resources :questions
resources :testsessions
end
end
Upd I think what you was meaning is:
<%= form_tag edit_test_testsession_path(#test, #testsession), id: 'submit_answer' do %>
The problem seems to be here:
<%= form_tag edit_test_testsession_path(#test, question.testsessions), id: 'submit_answer' do %>
You are passing a collection of all associated testsessions instead of single object, and I doubt it's what you intended to do.
Please show a part of your config/routes.rb related to the controller

Form_for doesn't work with JS/JQuery

I have problems getting a form to work when I use JavaScript with it.
Without the remote option set to true all works fine but as soon as I
set it, change the controller and create the needed JS files it produces an
POST .. 500 Internal Server Error
when clicking on the submit button.
Furthermore the reply-preview shows me a Rails Error Page saying
NoMethodError in Vocabs#create and undefined method > for nil:NilClass
in a related partial (which works fine before using JS)
The form (vocabs/_new_form.html.erb) looks like this:
<%= form_for #vocab, remote: true do |f| %>
<%= render 'fields', f: f %>
<%= f.submit "Add", class: "btn btn-large btn-primary" %>
<% end %>
The vocab_controller's create action like this:
def create
#user = current_user
#vocab = current_user.vocabs.build(vocab_params)
#vocabs = #user.vocabs.paginate(page: params[:page])
respond_to do |format|
format.html {
if #vocab.save
flash.now[:success] = "Vocab created!"
redirect_to root_url
else
flash.now[:error] = "Vocab not saved!"
render 'new'
end
}
format.js
end
end
The create.js.erb like this:
$('#new_vocab').remove();
Of course I want to do more than just to remove the form but as I didn't even manage to do that I wanted to keep it simple.
_fields.html.erb:
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.label :nl_word, #user.native_language %>
<%= f.text_field :nl_word %>
<%= f.label :fl_word, #user.foreign_language %>
<%= f.text_field :fl_word %>
<%= f.label :tag, "Your Tag" %>
<%= f.text_field :tag%>
<%= f.label :importance, "Importance" %>
<%= f.select(:importance, options_for_select(
StaticData::IMPORTANCE_SEED, :selected => f.object.importance)) %>
</div>
I hope I could explain myself good enough to get some help here. I tried for hours to find the solution to the problem myself and was looking for similar questions here without finding any and without getting anywhere.
With the help of a friend I found out that the main problem was that I didn't provide any validation for the vocab object i wanted to create in the form (_new_form.html.erb), when processing it with JS.
So I changed the vocab_controller.rb to
def create
#user = current_user
#vocab = current_user.vocabs.build(vocab_params)
#vocabs = #user.vocabs.paginate(page: params[:page])
respond_to do |format|
if #vocab.save
flash.now[:success] = "Vocab created!"
format.html do
redirect_to root_url
end
format.js
else
flash.now[:error] = "Vocab not saved!"
format.html do
render 'new'
end
format.js
end
end
end
That does the trick, and my form works with JS now.

Using AJAX to search, sort, and paginate in Rails 4

I'm trying to do a real-time search in a Rails 4.0.1 application.
I used the Railscasts #240 tutorial, but I am not getting the same results as the cast. It seems that my only issue is with the AJAX script, but I don't know why or how.
app/views/subproducts/index.html.erb
<%= form_tag subproducts_path, :method => 'get', :id => "subproducts_search" do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<div id='subproducts'>
<%= render 'subproducts' %>
</div>
<% end %>
app/views/index.js.erb
$('#subproducts').html('<%= escape_javascript(render("subproducts")) %>');
app/views/_subproducts.html.erb
<table class="table table-stripped">
<thead>
<tr>
<th><Center>Nombre</Center></th>
<th><Center>Codigo</Center></th>
<th><Center>Marca</Center></th>
<th><Center>Categoria</Center></th>
<th><Center>Precio De Compra</Center></th>
<th><Center>Precio De Venta</Center></th>
</tr>
</thead>
<tbody>
<% for subproduct in #subproducts%>
<tr>
<td><CENTER><%= subproduct.name %></CENTER></td>
<td><CENTER><%= subproduct.code %></CENTER></td>
<td><CENTER><%= subproduct.product.brand %></CENTER></td>
<td><CENTER><%= subproduct.product.category %></CENTER></td>
<td><CENTER><%= subproduct.product.bought_price %></CENTER></td>
<td><CENTER><%= subproduct.product.sale_price %></CENTER></td>
</tr>
<% end %>
</tbody>
</table>
<%= will_paginate #subproducts %>
app/models/subproduct.rb
class Subproduct < ActiveRecord::Base
belongs_to :product
belongs_to :sale
attr_accessible :code, :sale_id, :available, :name
def cancelar_venta
self.available = true
self.sale_id = nil
end
before_create do
self.available = true
end
def self.search(search)
if search
where('code LIKE ?', "%#{search}%")
else
Subproduct.all
end
end
end
app/controllers/subproducts_controller.rb
class SubproductsController < ApplicationController
def create
#product = Product.find(params[:product_id])
#subproduct = #product.subproducts.create(params[:subproduct].permit(:code, :name))
redirect_to product_path(#product)
end
def destroy
#product = Product.find(params[:product_id])
#subproduct = #product.subproducts.find(params[:id])
#subproduct.destroy
redirect_to product_path(#product)
end
def index
# #subproducts = Subproduct.all
#subproducts = Subproduct.search(params[:search]).paginate(:per_page => 5, :page => params[:page])
end
def agregar_subproducto_venta
#subproduct = Subproduct.find(params[:id])
#subproduct.sale_id = params[:sale_id]
#subproduct.available = false
#subproduct.save
#sale = Sale.find(params[:sale_id])
#sale.price = #sale.price + #subproduct.product.sale_price
#sale.save
redirect_to sale_path(#sale)
end
def eliminar_subproducto_venta
#subproduct = Subproduct.find(params[:id])
#subproduct.sale_id = nil
#subproduct.available = true
#subproduct.save
#sale = Sale.find(params[:sale_id])
#sale.price = #sale.price - #subproduct.product.sale_price
#sale.save
redirect_to sale_path(#sale)
end
end
public/javascripts/application.js
$(function () {
// pagination links
$('#subproducts .pagination a').live('click', function () {
$.getScript(this.href);
return false;
});
// Search form
$('#subproducts_search input').keyup(function () {
$.get($('#subproducts_search').attr('action'), ↵
$('#subproducts_search').serialize(), null, 'script');
return false;
});
});
I do not know what error you are getting so its hard to tell. But from the looks of things it is your app/views/index.js.erb file. When rails responds with javascript it can not find the index.js file.
The folder path should include the class name. Thus, your "app/views/index.js.erb file" name should be
app/views/subproducts/index.js.erb
note the addition of subproducts.
In the event that does not work you can also try out the following:
1) You can use remote true with your form_for and then skip on writing the p ublic/javascripts/application.js file
2) Add remote true to your form_tag (i.e)
<%= form_tag('/articles', remote: true) do %>
...
<% end %>
you can find more information on remote true and rails ajax calls here: http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html
3) In your controller you should have the following
def index
#subproducts = Subproduct.search(params[:search]).paginate(:per_page => 5, :page => params[:page])
respond_to do |format|
format.html
format.js
end
end
4) in app/views/subproducts/index.js.erb file add your code
$('#subproducts').html('<%= escape_javascript(render("subproducts")) %>');
Hopefully one of those two options works for you.

Categories