I have a delete button in my form that looks like this:
%td
%button.btn.btn-default{class: "delete-btn", "data-id" =>booking.id} Delete
How should I write my javascript to make it delete the row in the table when the Delete button is clicked?
Basically, how do I modify this in my application.js file
$(".delete-btn").on("click", function(e) {
var bkId = $(e.target).data("id");
//line to delete it from my form and the db
});
Previously, I had this in my html form to perform the deletion
'Delete', booking, :method => :delete, :data => { :confirm => 'Are you sure?' }
Please can someone show me how the .js/ajax equivalent would be?
I have developed this code so far (it executes but i keep getting my error message):
$(".delete-btn").on("click", function(e) {
var bkId = $(e.target).data("id");
$.ajax("/bookings", {
data: {
booking: {
id: bkId
}
},
method: "DELETE"
}).done(function(resp){
window.location = location.href;
}).fail(function(resp){
console.log("Error. Unable to delete");
alert("Error. Unable to delete this booking");
})
});
I found an easy to accomplish this:
%td= link_to 'Delete', booking, :method => :delete, class: "btn btn-danger"
Yet, I'm looking for the more complicated one which involves modifying my application.js (see above) to develop my understanding of how the communication between front and back end works.
Related
Is there any possible way to run controller action with confirm form before it?
I'd like to ask user is he/she really sure to do following action. And after confirmation run this action. In other case just do nothing.
I already tried this code:
= form_tag( '#', onclick: "confirm('#{text}')", :controller => :payments, :action => :pay, :subscription_id => subscription_plan) do
= hidden_field_tag 'current_subscription', subscription_plan.id
.payment_button= image_submit_tag "/images/popup/payment/#{label_img}", :value => label.to_s, data: { disable_with: "Please wait..." }
And I'm interesting in is there any way to do it without JavaScript?
Yes there is way
.payment_button= image_submit_tag "/images/popup/payment/#{label_img}", :value => label.to_s, data: { confirm: 'Your confirm message', disable_with: "Please wait..." }
OR another way is
= form_tag( '#', onsubmit => "return confirm('Are you sure?');", :controller => :payments, :action => :pay, :subscription_id => subscription_plan) do
I have a link_to with remote: set to true. What I want to do is add an extra attribute with the request so I tried it with this:
<script>
$(document).ready(
function(){
$("#part_btn").bind("ajax:beforeSend",
function(event, xhr, settings, data){
settings.data += "&user_id=5"
})
})
</script>
Now I don't even know if this is possible because the user_id is never sent to the controller and when I log the setting.data I get null&user_id=5.
If it's not possible like this, is there any other way to do it?
EDIT:
I didn't add an extra parameter to the link_to because the user_id actually comes from a select tag and I wanted to add the selected value as extra data like this:
settings.data += ("&user_id="+$("#register_user_id option:selected").val());
this is what my link_to looks like:
<%= text_field_tag :part_id, nil, :class => 'text_field', data: {source: autocomplete_parts_for_registers_registers_path} %>
<%= link_to('toevoegen', '#!', id: 'part_btn', class: 'btn btn-small btn-success addbtn', style: "margin-top: 5px", data: {source: add_part_registers_path}, remote: true) %>
I think the best and easiest way to update link_to when user change drop-down by javascript or an extra ajax call
JS
$("#user_select").change(function() {
user_id = $(this).val();
$("#user_link").data("params") = "user_id=" + user_id;
})
Extra Ajax
send user_id to server with user_id and make a method_name.js.erb and update link from there
like:
link_to "link", method_path(user_id: params[:user_id]), remote: true
Rather than taking the javascript approach, consider send the params with the route in the link_to:
link_to "My link", some_path(user_id: 5), remote: true, method: :post
This will add :user_id with a value of 5 to the params in the controller for some_path.
Additionally, you can use the data: attribute on the link to to add any params you want to XHR request.
link_to "My link", id: "user_link", some_path, remote: true, method: :post, data: { params: { user_id: 123 }.to_param }
If you need to change the value dynamically:
$("#user_select").change(function() {
user_id = $(this).val();
$("#user_link").data("params", "user_id=" + user_id);
})
In fact, it looks like this is exactly what Rails does to send AJAX values from jquery_ujs.
Obviously, be sure to check the value of user_id server-side.
I have migrated a :completed boolean, I then added it to my form like so (simple_form)
<%= f.input :completed, as: :boolean %>
This allows me to update completed, not completed in the edit view.
How can I edit the :completed method in my index view? I want to be able to update complete or not complete on the fly.
EDIT:
My Form
<%= f.input :completed, as: :boolean, input_html: { class: 'completed', id: #todo.id } %>
My View (label has to be after input as per materializecss)
<%= check_box_tag todo.id, 'completed', todo.completed?, class: 'completed' %>
<label class="strikethrough">
COMPLETE
</label>
The JS
// This could be other events as well, so add/change/remove the event trigger as needed
$(document).on('click', '.completed', function(){
updateCompleted($(this));
});
function updateCompleted($el) {
var id = $el.attr('id'),
val = $el.is(':checked');
$.PATCH({
url: '/todos/'+id,
data: { todo: { completed: val } },
success: function(){ whatever },
error: function() { whatever }
});
}
My Controller
params.require(:todo).permit(:title, :item, :image, :completed)
You are going to require some AJAX here. In my experience, doing this is a bit outside of the "rails way", but totally possible.
First, make sure you have the ID of the object somewhere in the dom:
<%= f.input :completed, as: :boolean, input_html: { class: 'completed', id: myobject.id %>
I used the simple_form syntax since that's what it appears you are using for your form builder. If not, comment back and I'll adjust the tag.
Secondly, add a jquery event listener:
// This could be other events as well, so add/change/remove the event trigger as needed
$(document).on('click', '.completed', function(){
updateCompleted($(this));
});
function updateCompleted($el) {
var id = $el.attr('id'),
val = $el.is(':checked');
$.PATCH({
url: '/your_endpoint/'+id,
data: { your_object_name: { completed: val } },
success: function(){ whatever },
error: function() { whatever }
});
}
And in your controller:
private
def your_object_params
params.require(:your_object).permit(..., :completed)
end
That's basically it.
Basically you will want to make a post to the update action from the index action. I would use JavaScript but you can also use a hard refresh if you want to stick with rails. Here is a good intro if you are not familiar with using JS in your rails app. http://railscasts.com/episodes/324-passing-data-to-javascript.
I am trying to implement Stripe Checkout using the custom integration in a rails app - my checkout form shows a green checkmark saying it submitted but the payment is not being processed. The simple integration works well, as do subscription payments on other parts of my site.
Like the simple integration, I am trying to place the custom integration script inside of a form_tag - I followed the Rails Checkout guide, which unfortunately is only written for the simple integration. Like the guide, I have a charges controller, with new and create actions to show the form and create the charges.
Charges Controller:
class ChargesController < ApplicationController
def new
end
def create
# Amount in cents
#amount = 500
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Rails Stripe customer',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end
end
And in my new view, the form is setup as follows:
<%= form_tag charges_path do %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<button id="customButton" class="btn btn-large btn-primary">Buy Now</button>
<script>
var handler = StripeCheckout.configure({
key: '<%= ENV["STRIPE_PUBLIC_KEY"] %>',
image: '/assets/my_logo.png',
token: function(token, args) {
// Use the token to create the charge with a server-side script.
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'My Company',
description: 'Product ($60.00)',
amount: 60*100,
shippingAddress: true
});
e.preventDefault();
});
</script>
<% end %>
I have tried just about everything I can think of, but the form will not be submitted to trigger the create action. I see the note to use a server side script, but can anyone point me in the right direction on what I may be missing?
Any help is much appreciated!! Thanks!
You need to finish the token callback function.
First pass in the response from the Stripe handler as an argument and then append the token id and email as inputs to the form before submitting it: (untested)
token: function(response) {
var tokenInput = $("<input type=hidden name=stripeToken />").val(response.id);
var emailInput = $("<input type=hidden name=stripeEmail />").val(response.email);
$("form").append(tokenInput).append(emailInput).submit();
}
Here is a working solution. Add an id to your form tag. Add a stripeToken and stripeEmail hidden field to your form tag. Then when we receive the token from Stripe we will use JavaScript to set the values of the hidden fields and submit the form by referencing their id's:
<%= form_tag charges_path, id: 'chargeForm' do %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<%= hidden_field_tag 'stripeToken' %>
<%= hidden_field_tag 'stripeEmail' %>
<button id="customButton" class="btn btn-large btn-primary">Buy Now</button>
<script>
var handler = StripeCheckout.configure({
key: '<%= ENV["STRIPE_PUBLIC_KEY"] %>',
image: '/assets/my_logo.png',
token: function(token, args) {
document.getElementById("stripeToken").value = token.id;
document.getElementById("stripeEmail").value = token.email;
document.getElementById("chargeForm").submit();
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'My Company',
description: 'Product ($60.00)',
amount: 60*100,
shippingAddress: true
});
e.preventDefault();
});
</script>
<% end %>
This can be solved many ways but bare in mind this is a JavaScript problem nothing to do with Rails or Stripe really. Stripe are simply giving us the token we can do whatever we want with it with JavaScript.
I think you don't want to preventDefault here, because that prevents your form from being submitted to the server. Does it submit the form to the create action when you take out e.preventDefault(); ?
With the "simple integration" you can still change the text in the default blue button with the data-label attribute(eg data-label='Buy now') using the configuration options. But yeh you have to use "custom integration" to fully style the button yourself
I'm developing autocomplete for a particular form in my rails app; for this purpose I'm using typeahead.js with custom controller method. So far, it works but I need using those values within the form again so that I can press the submit button and the form will be posted and processed by rails normally. How can I do this? Here's the code right now
.page-header
%h1
= #org.name
%small= t('.title')
= form_for #org_admin, |
url: organization_organization_admins_path(#organization) do |f|
.form-group
= f.label t('.user')
= f.hidden_field :user, id: 'user_id'
%input.typeahead{ :type => "text", :autocomplete => "off"}
= f.submit t('.submit'), class: 'btn btn-primary'
= link_to t('.back'), organization_organization_admins_path(#organization)
:javascript
$(document).ready(function() {
$('input.typeahead').typeahead({
name: 'names',
remote: "#{search_organization_organization_admins_path(#organization)}?term=%QUERY",
engine: Hogan,
template: '<p><strong>{{username}}</strong></p>',
limit: 10
}).on('typeahead:selected', function(e, data){
$('#user_id').value = data.id
});
});
So, I would like to populate the :user attribute in the form with the json object returned by the controller
Nevermind, I figured out... the above code is in the right path, except for the call to this line
$('#user_id').value = data.id
Since I'm using jQuery to select the hidden element I had to use the jQuery val function instead
$('#user_id').val(data.id)