Call update method when a checkbox is checked - ruby-on-rails

I am trying to figure out how to call the update method when the user checks on the check box. I want to update the database by deleting the value for the check box that is stored in the database. Here is my code
<% #items.each do |item|%>
<%if item.email == #user.email%>
<%= form_for #item do |f| %>
<%= f.check_box :to_do, url: update,:value => item.id%>
<%= item.to_do%><br />
<% end %>
<%end%>
<%end%>

you can do something like..
by using checked property..call ajax using jquery
$('input[type=checkbox][id=to_do]').change(function() {
var hall_id = $('#to_do:checked').val();
$.ajax({
url:"/todo",
type:'POST',
//pass any agruments if needed
//data: {"id": pass any data that you need},
beforeSend: function (){
//show the user that something is in progess
$("#to_do").parent().html("Submitting..");
},
success:function(data){
//update user on success/failure
$("#to_do").parent().html("Submitted");
}
});
})
Now,just implement your action on the controller...thats it.
Hope it helps :)

Related

Providing AJAX With Rails-Generated URL

Can I provide AJAX with a Rails URL/path?
For example, what I need is url: articles/1/comments/1.
Since I'm experiencing difficulties for some time now making AJAX execute this URL, I wonder if there's a way to use the Rails route I'm familiar with [comment.article, comment].
Note:
I'm loading a DIV using AJAX:
#welcome/index.haml
- #articles.each do |article|
= article.title
- article.comments.each do |comment|
%comment-content{ :id => "comment-#{ comment.id } %>", :class => "comment-content", "data-comment-id" => comment.id }
AJAX:
var loadComment = function() {
return $('.comment-content').each(function() {
var comment_id = $(this).data('comment-id');
return $.ajax({
url: "" ,
type: 'GET',
dataType: 'script',
});
});
};
Rails provide data-remote attribute in form. It works like AJAX and it uses url as you added in form
you can use it like below:
<%= form_for([comment.article, comment], remote: true) do |f| %>
...
<% end %>
you can use like
<%= form_for([comment.article, comment], remote: true) do |f| %>
...
<% end %>
if you are using form_for or if you want to send ajax like:
$.ajax({
})
then you can use
$.ajax({
url : "<%= url_for article_comment_path(article, comment)%>"
})

Checkbox in index view live updating

I'm currently learning rails and working on what I'm sure is everyone's first rails app, a simple todo list. I need to implement a checkbox next to the items to indicate whether they are complete or not. Each item has a boolean attribute called "completed" in their model. I have found a couple checkbox questions while searching but none explain the syntax very easily in the context of the index view.
Also, I really want the checkbox to work without a submit button. I know I could accomplish something like this using AngularJS's ng-model but I don't think it would be practical to implement angular for such a small thing and I don't know how angular works with rails.
If anyone could give me a pointer in the right direction, it would be greatly appreciated. Here's my index.html.erb for reference.
<h1>
To Do List
</h1>
<table>
<tr>
<% #todo_items.each do |item| %>
<!-- Checkbox here -->
<tc style="<%= 'text-decoration: line-through' if item.completed %>">
<%= link_to item.title, item %>
</tc>
<tc>
<%= item.description %>
</tc>
<tc>
<%= link_to "Edit", edit_todo_item_path(item) %>
</tc>
<tc>
<%= link_to "Delete",item, data:{:confirm => "Are you sure you want to delete this item?"}, :method => :delete %>
</tc>
<hr/>
<% end %>
</tr>
</table>
<p>
<%= link_to "Add Item", new_todo_item_path %>
</p>
This is my way, I don't know this way is right direction or not but this works for me (also different case but same of concept).
views for checkbox
You could put an id item or something into attribute of checkbox for find an object in controller if you send data to controller for get record of object, and you could define if attribute completed of record is true or false:
<%= check_box_tag :completed_item, 1, item.completed? ? true : false, { class: 'name-of-class', data: { id: item.id} } %>
controller
You need two action call set_completed and remove_completed, and also you don't need templates for them, just use format as json:
before_action :set_item, only [:set_completed, :remove_completed, :other_action]
def set_completed
#item.set_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
def remove_completed
#item.remove_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
private
def set_item
#item = Item.find params[:id]
end
Model
For set_completed! and remove_completed! you could define in your model
def set_default!
self.update_attributes(:completed => true)
end
def remove_default!
self.update_attributes(:completed => false)
end
routes
resources :address do
collection do
post 'set_completed'
post 'remove_completed'
end
end
Also, you need help JavaScript for handle send request from view to controller event click of checkbox:
jQuery
$(".completed_item").click(function(){
var check = $(this).is(":checked");
if (check == true){
set_completed($(this).attr('data-id'));
} else{
remove_completed($(this).attr('data-id'));
}
});
function set_completed(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}
function remove_compelted(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}

how to catch value of symbol :confirm in rails

<%= f.submit "#{t('next_text')}", :class => "submit_button" ,:confirm=>'Edit all copies?'%>
how can I take value(true or false) of :confirm in rails 2.3.5?
I need this value to do some action in controller .
The easiest solution would be to just add a checkbox to your form whether or not to edit all copies.
If you really need the confirmation box on submit, attach an onSubmit handler to the form
<% form_for(#some_model, :html=> {:class => 'edit_confirmation'}) do |f| %>
<%= hidden_field_tag :edit_all, 0 %>
....
<% end %>
The javascript using jQuery:
$('form.edit_confirmation').on('submit', function(e) {
// the hidden field
var field = $('input#edit_all');
if(confirm("Edit all copies?")) {
field.val(1);
} else {
field.val(0);
}
return true;
});
In your controller you can get the result with params[:edit_all]

How to use AngularJS with Rails Form?

I'm using simple_form with AngularJS:
= simple_form #post do |f|
= f.input :title, input_html: { "ng-model" => "title" }
It works great for my scenario on new post, but for editing on existing post, it doesn't bind/fill in existing value from post's title on form. From what I thought Rails already fill in the value, but AngularJS wipes it out after the page load because $scope.title is blank.
I found the trick is to actually create a controller with an init function that takes the value you want. In my case I just created a app/assets/javascripts/angular_app.js file that looks like this:
//= require_self
AngularRails = angular.module('AngularRails', []);
AngularRails.controller('PostFormCtrl', function($scope) {
$scope.init = function(title) {
$scope.title = title;
}
});
You'll have to translate the view into haml but it should look something like this:
<div ng-app="AngularRails">
<div ng-controller="PostFormCtrl" ng-init="init('<%= #post.title %>')">
<%= form_for #post, html: {name: "postForm", "novalidate" => true} do |f| %>
<%= f.text_field :title, "ng-model" => "title", required: true %>
<%= f.submit "ng-disabled" => "postForm.$invalid" %>
<% end %>
</div>
</div>
Remember to include the angular_app file into application.js and it should world. Obviously, this isn't a very robust solution but you could use active model serializer to convert the rails object to a json object. Then, pass that json object to the init function and in the controller, iterate over the key/value pairs of that json object and set them to $scope. Something like this:
AngularRails.controller('PostFormCtrl', function($scope) {
$scope.init = function(input) {
Object.keys(input).forEach(function(key) {
$scope[key] = input[key];
});
};
});
Hope that helps!

Using an AJAX call to update a rails page without a refresh?

I have a page on my site that lets users respond to invites by either accepting or declining them.
Their response is stored in the database as the boolean 'accepted', and is used to apply the classes 'selected' or 'not_selected' (selected makes the text orange) to the 'attending' div or the 'not attending' div.
<% #going, #not_going = invite.accepted ? ['selected','not_selected'] : ['not_selected','selected'] %>
<%= link_to(outing_invite_accept_path( { :outing_id => invite.outing_id, :invite_id => invite.user_id } )) do %>
<div class="attending_div <%= #going %>">
attending
</div>
<%end %>
<%= link_to(outing_invite_decline_path( { :outing_id => invite.outing_id, :invite_id => invite.user_id } )) do %>
<div class="attending_div <%= #not_going %>">
not attending</div>
</div>
<% end %>
When either div is clicked, it's diverted to the appropriate controller actions:
def invite_accept
#outing = Outing.find(params[:outing_id])
#invite = OutingGuest.find_by_outing_id_and_user_id(params[:outing_id], params[:invite_id])
#invite.update_attribute(:accepted, true)
redirect_to({:action => "index"})
end
def invite_decline
#outing = Outing.find(params[:outing_id])
#invite = OutingGuest.find_by_outing_id_and_user_id(params[:outing_id], params[:invite_id])
#invite.update_attribute(:accepted, false)
redirect_to({:action => "index"})
end
And as right now, this code works just fine. But it requires the index page be refreshed for it to take effect.
I know it's possible to update the page without a refresh using a jQuery ajax call attached to a listener on the appropriate div, but I have no idea what such a call would look like, or where to start, really...
You want to use rail's link_to :remote => true.
See http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
For dealing with callbacks you can bind to certain events that will trigger. For example:
<%= link_to "Click Me!", some_path, :class => 'ajax', :remote => true %>
<script>
jQuery(function($) {
$("a.ajax")
.bind("ajax:loading", console.log('loading'))
.bind("ajax:complete", console.log('complete'))
.bind("ajax:success", function(event, data, status, xhr) {
console.log(data);
})
.bind("ajax:failure", function(xhr, status, error) {
console.log(error);
});
});
</script>
This page is also a pretty good write up: http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/

Resources