Rails: Checkbox to change the value of a variable on click - javascript

I have a basic to do type app and I am trying to change the variable completed for an item to the current date/time when I click a checkbox. I found this post, which has led me to the following code structure:
My lists#show, on which items are created, checked off (updated), edited, and deleted:
<div class="container">
<div class="row" style="height: 70px"></div>
</div>
<div class="col-xs-10 col-xs-push-1 container">
<div class="md-well">
<h1 class="text-center"><%= #list.name %></h1>
<% if #items.count == 0 %>
<h4 class="text-center">You don't have any items on this list yet! Want to add some?<h4>
<% elsif #items.count == 1 %>
<h4 class="text-center">Only <%= #items.count %> Item To Go!</h4>
<% else %>
<h4 class="text-center">You Have <%= #items.count %> Items To Go!</h4>
<% end %>
<%= render 'items/form' %>
<% #items.each do |item|%>
<p>
<%= form_for [#list, item], class: "inline-block", id: 'item<%= item.id %>' do |f| %>
<%= f.check_box :completed, :onclick => "$this.parent.submit()" %>
<% end %>
<%= item.name %>
( <%= link_to "Delete", list_item_path(#list, item), method: :delete %> )
</p>
<% end %>
<div class="text-center">
<%= link_to "Back to My Lists", lists_path %>
</div> <!-- text-center -->
</div> <!-- well -->
</div> <!-- container -->
Here is my update method in my items_controller (which I believe has jurisdiction instead of the lists_controller even though it is the lists#show page because it is an item being updated:
def update
#list = List.friendly.find(params[:list_id])
#item = #list.items.find(params[:id])
#item.name = params[:item][:name]
#item.delegated_to = params[:item][:delegated_to]
#item.days_til_expire = params[:item][:days_til_expire]
#item.completed = params[:item][:completed]
#item.user = current_user
if #item.update_attributes(params[:item])
#item.completed = Time.now
end
if #item.save
flash[:notice] = "List was updated successfully."
redirect_to #list
else
flash.now[:alert] = "Error saving list. Please try again."
render :edit
end
end
Here is what is currently appearing:
And here are the two problems I'm having:
LESS IMPORTANT PROBLEM: The checkboxes should be displayed inline with the list items but aren't. My class inline-block simply makes links to this in the application.scss file:
.inline-block {
display: inline-block !important;
}
MORE IMPORTANT PROBLEM: Even after the checkbox is clicked, the value for completed remains nil as per my console:
[6] pry(main)> Item.where(name: "Feed Dexter")
Item Load (0.1ms) SELECT "items".* FROM "items" WHERE "items"."name" = ? [["name", "Feed Dexter"]]
=> [#]
Any ideas how to make this functional?

Related

Ajax record delete not appended to HTML

I am venturing into AJAX and would like to delete a record of a model and followed this thread : How to perform Controller.destroy action asynchronously in rails?
models:
Photographe
Photographephoto
views/photographes/edit.html.erb
<div id="sectionimages" class="gutter-0 row" >
<% #photographe.photographephotos.all.each do |f| %>
<div class="col-md-2 col-sm-3 col-xs-6 col">
<%= link_to professionnel_photographe_photographephoto_path(#photographe.professionnel.id,#photographe.id, f.id), method: :delete, remote: 'true', id: "destruction"+f.id.to_s do %>
<div class="killimage" >
<%= image_tag f.image.url(:small) %>
<%= image_tag 'fatcrosswhite.svg', class: 'imgover' %>
</div>
<% end %>
</div>
<% end %>
</div>
link to Photographephotos#destroy is remote and there's an id like "destruction134"
photographephotos_controller.rb
def destroy
#imagedestroyed = Photographephoto.find(params[:id])
#imagedestroyedid = #imagedestroyed.id
#imagedestroyed.image = nil
#imagedestroyed.save
#imagedestroyed.destroy
respond_to do |format|
format.js
end
end
views/photographephotos/destroy.js.erb
var destroyelement = document.getElementById("<%= "destruction"+#imagedestroyedid.to_s %>");
destroyelement.parentNode.remove();
Problem is the file is indeed deleted but I have to refresh the page to see it removed. It seems the javascript is not effective. (I am trying to remove the parent of the link which is a Bootstrap DIV)

How to filter search form drop down menu in Rails?

I'm trying to filter selected options from 3 dropdown menus.
Here are my models:
class Profile < ApplicationRecord
belongs_to :user
has_and_belongs_to_many :skills
has_and_belongs_to_many :jobs
has_and_belongs_to_many :industries
end
and
class Industry < ApplicationRecord
has_and_belongs_to_many :profiles
end
and
class Job < ApplicationRecord
has_and_belongs_to_many :profiles
end
and
class Skill < ApplicationRecord
has_and_belongs_to_many :profiles
end
Views
profiles/index.html.erb
I list all 3 drop down menus
<section class="top-search">
<div class="container">
<%= form_tag #filter, :method => :get do %>
<%= select_tag "skills_id", options_from_collection_for_select(Skill.all, "id", "name"), prompt: "Specialized Skills" %>
<%= select_tag "industries_id", options_from_collection_for_select(Industry.all, "id", "name"), prompt: "Industries" %>
<%= select_tag "jobs_id", options_from_collection_for_select(Job.all, "id", "name"), prompt: "Job Functions" %>
<%= submit_tag "Filter", name: nil, class:"btn btn-primary" %>
<% end %>
</div>
</section>
And in the same page below the above section, I have another section where I want to display the filter result..
<section class="search-result">
<div class="container">
<div class="row flex-container">
<% #profiles.each do |profile| %>
<div class="col-md-5 mentor-profile">
<div class="media">
<div class="media-left">
<%= link_to profile do %>
<%= image_tag profile.avatar.url(:thumb) %>
<% end %>
</div>
<div class="media-body">
<h4 class="media-heading">
<%=link_to profile do %>
<%= "#{profile.first_name }" " #{ profile.last_name}" %>
<% end %>
</h4>
<strong>Works at <%= profile.company %></strong>
<p><%= profile.city %>, <%= profile.country %></p>
</div>
</div>
<div class="dvider"></div>
<div class="profile-section">
<h5>SUMMARY</h5>
<p><%= profile.summary %></p>
</div>
<div class="profile-section">
<h5>SPECIALIZED SKILLS</h5>
<p><%= profile.skills.map(&:name).join(', ') %></p>
</div>
<div class="profile-section">
<h5>CRITERIA MET</h5>
<p>NEED TO WORK ON IT....</p>
</div>
</div>
<% end %>
</div>
</div>
</section>
In Profiles Controller I defined a filter method:
def filter
#profiles = Profile.all
#profiles = Profile.joins(:skills).where('skills.name = ?', params[:skill])
#profiles = Profile.joins(:industries).where('industries.name = ?', params[:industry])
#profiles = Profile.joins(:jobs).where('job.name = ?', params[:job])
end
It seems filters works, the urls shows this http://localhost:3000/profiles?utf8=%E2%9C%93&skills_id=13&industries_id=9&jobs_id=8
But nothing got filtered.
How would I get it to work? I have seen similar cases where filter uses JS to filter the page and append the result (in my case <section class="search-result"> section to the page).
Am I correct?

Implementing AJAX Creation, Missing Template (Create) Error

I am trying to implement AJAX in my to do type app, but am getting a missing template error (Missing template items/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}.) on my create action. There shouldn't be a create.html.erb page because the creation of items happens on a lists#show page:
<div class='new-item'>
<%= render 'items/form' %>
</div>
<div class="js-items">
<% #items.each do |item| %>
<%= div_for(item) do %>
<p><%= link_to "", list_item_path(#list, item), method: :delete, remote: true, class: 'glyphicon glyphicon-ok', style: "margin-right: 10px" %>
<%= item.name %>
<% if item.delegated_to != "" && item.user_id == current_user.id %>
<small>(Delegated to <%= item.delegated_to %>)</small>
<% elsif item.delegated_to != "" && item.user_id != current_user.id %>
<small>(Delegated by <%= item.user_id %>)</small>
<% end %></p>
<% end %>
<% end %>
</div>
And the _form.html.erb partial to which it links:
<div class="row">
<div class="col-xs-12">
<%= form_for [#list, #item], remote: true do |f| %>
<div class="form-group col-sm-6">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter Item Name" %>
</div>
<div class="form-group col-sm-6">
<%= f.label 'Delegate To (Not Required)' %>
<%= f.text_field :delegated_to, class: 'form-control', placeholder: "Enter an Email Address" %>
</div>
<div class="text-center"><%= f.submit "Add Item to List", class: 'btn btn-primary' %></div>
<% end %>
</div>
</div>
Here's the create method in the items_controller:
def create
#list = List.friendly.find(params[:list_id])
#item = #list.items.new(item_params)
#item.user = current_user
#new_item = Item.new
if #item.save
flash[:notice] = "Item saved successfully."
else
flash[:alert] = "Item failed to save."
end
respond_to do |format| <<<<ERROR CALLED ON THIS LINE
format.html
format.js
end
end
And here's my create.js.erb file:
<% if #item.valid? %>
$('.js-items').prepend("<%= escape_javascript(render(#item)) %>");
$('.new-item').html("<%= escape_javascript(render partial: 'items/form', locals: { list: #list, item: #new_item }) %>");
<% else %>
$('.flash').prepend("<div class='alert alert-danger'><button type='button' class='close' data-dismiss='alert'>×</button><%= flash.now[:alert] %></div>");
$('.new-item').html("<%= escape_javascript(render partial: 'items/form', locals: { list: #list, item: #item }) %>");
<% end %>
Anyone have any ideas why I am getting this? I tried removing the format.html line from the items_controller but I got an unrecognizable format error.
You can force the form submission to use a JS format, instead of the default HTML format, so that your respond_to block will render the create.js.erb view instead of the create.html.erb view.
<%= form_for([#list, #item], format: :js, remote: true) do |f| %>
Typically, Rails will detect your remote: true option via "unobtrusive JavaScript (ujs)", which will effectively handle the format: :js option for you. There is something unique in your setup that we have not identified, which is requiring you to enforce the format option.
To see that your create.js.erb is working, you can change the line that renders your item partial:
$('.js-items').prepend("<%= escape_javascript(render(#item)) %>");
To render a the item's name, wrapped in a <p> tag:
$('.js-items').prepend("<p>" + <%= #item.name %> + "</p>");
You can customize that line to generate the html that you want to appear for your new list item. Based on your code above, this looks like it will work out for you.
As you finish your to-do app, you can create a partial for your item, and then change that line again so that your partial will be appended to your list of items.

Why does jQuery only enter the function in some links?

I am relatively new to jQuery and JavaScript, so I'm having this issue, hope you can help me through it.
I am making an e-commerce page for selling cloths in Rails 4, so I am focusing more than I used to in the form of displaying forms and all of that, so it can be more attractive to the users. Because of that, I have the forms hidden and I set the values to it via jQuery.
The problem can be divided in two parts:
The first part of the problem is in the cloths#show where the user add the cloth to his cart:
Form:
<%= form_for #order_item, remote: true do |f| %>
<h5>Select a size</h5>
<div class="input-sizes">
<% #sis.each do |si| %>
<%= link_to si.size.letter, "#{si.size_id}", class:"normal-size" %>
<% end %>
</div>
<%= f.hidden_field :size_id, id: "size-input" %>
<h5>Select a color</h5>
<div class="input-colors">
<% #cos.each do |co| %>
<%= link_to "#{co.color_id}", id: "link-circle" do %>
<div id="circle" style="background: <%= co.color.hex %>">
<div id="mini-circle"></div>
</div>
<% end %>
<% end %>
</div>
<%= f.hidden_field :color_id, id: "color-input" %>
...
<% end %>
jQuery:
//Select size
$('a.normal-size').on('click', function(e){
e.preventDefault();
var value = $(this).attr("href");
$('#size-input').val(value);
$(this).removeClass("normal-size").addClass("selected").siblings().removeClass("selected").addClass("normal-size");
});
//Select Color
$('#link-circle').on('click',function(e){
e.preventDefault();
var value = $(this).attr("href");
$('#color-input').val(value);
$(this).children().children().css('opacity', '1');
return false;
});
The set of the size input works perfectly but in the color input the user only can select the first color because if the user wants to select the second, the jQuery function doesn't gets called so it goes to the link (I tried even writing e.preventDefault() and return false at the same time).
The second part of the problem comes in the cart#show when the user can see the summary of all his cloths. In this it is displayed a table with each row being a cloth, here the user can see the image of the cloth, description, selected color, selected size and price. The color and size section is made for the user so he can edit his cloth if he changes his mind and select another size or color. The issue in here is in both size and color and I don't know why. In the color section happens exactly the same as above, but in the size section he can only make one click because if he makes another one the jQuery function doesn't get called. Is like if the click only works once:
Form:
<%= form_for (order_item), remote: true,:url => "/order_items/#{order_item.id}", :html=>{:id=>'item_form_cart'} do |f| %>
<div class="input-colors col-md-1">
<% #cos.each do |co| %>
<% if co.cloth == order_item.cloth %>
<% if co.color_id == order_item.color_id %>
<%= link_to "#{co.color_id}", id: "link-circle" do %>
<div id="circle" style="background: <%= co.color.hex %>;">
<div id="mini-circle" style="opacity: 1;"></div>
</div>
<% end %>
<% else %>
<%= link_to "#{co.color_id}", id: "link-circle" do %>
<div id="circle" style="background: <%= co.color.hex %>;">
<div id="mini-circle"></div>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
</div>
<%= f.hidden_field :color_id, id: "color-input" %>
<div class="input-sizes col-md-2">
<% #sis.each do |si| %>
<% if si.cloth == order_item.cloth %>
<% if order_item.size_id == si.size_id %>
<%= link_to si.size.letter, "#{si.size_id}", class:"selected" %>
<% else %>
<%= link_to si.size.letter, "#{si.size_id}", class:"normal-size cart-el" %>
<% end %>
<% end %>
<% end %>
</div>
<%= f.hidden_field :size_id, id: "size-input-cart" %>
...
<% end %>
jQuery:
//Select size
$('a.normal-size.cart-el').on('click',function(e){
e.preventDefault();
var value = $(this).attr("href");
$(this).parent().next('#size-input-cart').val(value);
$(this).removeClass("normal-size").addClass("selected").siblings().removeClass("selected").addClass("normal-size");
$(this).closest('#item_form_cart').submit();
});
In here I only make the size function because I didn't know how to fix the color one, but this also has a bug, that only gets called the first time. This happens no matter which cloth's size you select, e.i. if I change the first cloth's size works good but if I want to change again the same cloth's size or change the size of another cloth the jQuery function doesn't get called.
Hope you can help me,
Thanks in advance.
Edit:
I have investigated more about why is happening the second problem and I saw that it can be related to Ajax, because in my form if a user changes the size or color it gets done by Ajax, as we can see here. I tried the second solution but it did not work:
$('.well').on('click','a.normal-size.cart-el',function(e){
e.preventDefault();
var value = $(this).attr("href");
$(this).parent().next('#size-input-cart').val(value);
$(this).removeClass("normal-size").addClass("selected").siblings().removeClass("selected").addClass("normal-size");
$(this).closest('#item_form_cart').submit();
});
$('.well').on('click','.link-circle.cart-el',function(e){
e.preventDefault();
var value = $(this).attr("href");
$(this).parent().next('#color-input-cart').val(value);
$(this).siblings().children().children().css('opacity', '0');
$(this).children().children().css('opacity', '1');
$(this).closest('#item_form_cart').submit();
});
And here is render each item in the view:
<div class="order_items">
<% #order_items.each do |order_item| %>
<div class = "well">
<%= render 'carts/cart_row', cloth: order_item.cloth, order_item: order_item, show_total: true %>
</div>
<% end %>
</div>
Your select color function is attached to the id "link-circle". It looks like you're potentially rendering multiple elements with the same id. Your select size function is based on a class which you can have on multiple elements. You cannot however have the same id on multiple elements according to w3 . Try changing "link-circle" to a class like so..
<%= link_to "#{co.color_id}", class: "link-circle" do %>
and the your selector to..
$('.link-circle').on('click',function(e){

Rails: AJAX not working with form Create Action

This is a simple grocery list app. Left column div is a list of lists. Items for a particular list are displayed in the right column div.
Here's the process:
A user clicks on one of the lists, which then loads (AJAX) it's related items in the right div. This is working fine.
Here's where I'm stuck:
Above the items is an input field to submit a new item to the list of items below. I want AJAX to add the new item to the items below but when I press enter on the form field, nothing happens. When I refresh, the new item is added.
Here's what the server said:
Processing by ItemsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"YWIlMPXqoTvhqzGGPqm6Rn/E7jPRt8do/2tkjd0H1Qk=", "item"=>{"name"=>"Mayo"}, "list_id"=>"4"}
List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", "4"]]
(0.0ms) begin transaction
SQL (20.9ms) INSERT INTO "items" ("completed", "created_at", "description", "list_id", "name", "position", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["completed", false], ["created_at", Mon, 29 Apr 2013 21:59:06 UTC +00:00], ["description", nil], ["list_id", 4], ["name", "Mayo"], ["position", nil], ["updated_at", Mon, 29 Apr 2013 21:59:06 UTC +00:00]]
(1.6ms) commit transaction
Rendered items/_piece.html.erb (0.0ms)
Rendered items/create.js.erb (0.7ms)
Here's the page loading process:
home.html.erb > _single.html.erb > create.js.erb > adds _piece.html.erb to home.html.erb
This is the Create Action from my items_controller.rb file:
def create
#list = List.find(params[:list_id])
#item = #list.items.create!(params[:item])
respond_to do |format|
format.html
format.js
end
end
This is my create.js file:
$('#item-container').prepend('<%= j render(partial: 'piece', locals: {item: #item}) %>');
This is my _piece.html.erb file:
<li><%= item.name %></l1>
This is my _single.html.erb file:
<div id="filter">
<div id="filter-left">
</div>
<div id="filter-right">
<%= link_to 'Delete', #list, :method => :delete %>
</div>
</div>
<div id="quick-add">
<%= form_for [#list, #item], :id => "form-quick", remote: true do |form| %>
<%= form.text_field :name, :id => "input-quick", :autocomplete => "off" %>
<% end %>
</div>
<ul class="item-container">
<% #list.items.incomplete.each do |item| %>
<% if item.id %>
<li><%= link_to "", complete_item_path(#list.id,item.id), :class => "button-item button-item-incomplete" %> <%= item.name %></li>
<% end %>
<% end %>
</ul>
<div class="title">Completed items</div>
<ul class="item-container">
<% #list.items.completed.each do |item| %>
<% if item.id %>
<li><div class="button-item button-item-completed"></div><%= item.name %></li>
<% end %>
<% end %>
</ul>
This is my home.html.erb file:
<div id="main-left">
<div id="main-left-1">
<%= link_to 'Add List', new_list_path, class: "button", id: "new_link", remote: true %>
</div>
<ul id="lists" data-update-url="<%= sort_lists_url %>">
<% #lists.each do |list| %>
<%= content_tag_for :li, list do %>
<%= link_to list.name, list, :remote => true, :class => "link" %>
<% end %>
<% end %>
</ul>
</div>
<div id="main-right">
</div>
Well, I had "item-container" as an ID instead of a class in the JS.ERB file. SILLY ERRORS!

Categories

Resources