I have a view page, where the user inputs a number and clicks on generate to get a form in the same page based on this input. So I'm using javascript in my main view:
<div class="label-field-pair"><%= "#{t('total')} #{t('amount')}" %>:
<%= form.text_field :total, :value =>precision_label(#total_pay.to_f) , :disabled=> true , :id=>'total' %></div>
<div class="label-field-pair">
<label for="student_grade"><%= t('no_payments') %><span class="necessary-field">*</span> </label>
<input type="number" min="1" max="12" step="1" value="1" name="no_payments" id="no_payments"> </div>
<%= form.hidden_field :no_payments, :id=>'payments' %>
<%= form.hidden_field :total_pay, :id=>'total_pay' %>
<%#= submit_tag "", :value => "► #{t('generate')}", :class => "submit_button", :disable_with => "► #{t('please_wait')}" %>
<%#= render :partial => 'distribute_payments', :locals => {:no_payments=>2, :total => 30000 , :guardian=>#guardian.id} %>
<button type="button" id="gen" onClick="generate()" style="display: block">Generate</button>
<div id="payments_distribute"></div>
<%end%>
<script type="text/javascript">
function generate() {
var t = document.getElementById("total").value;
var n = document.getElementById("no_payments").value;
j('#total_pay').val("<%= #total_pay %>");
document.getElementById("gen").style.display = "none";
<%="#{remote_function(:url => {:action => "distribute_payments", :id=>#guardian.id,:total_pay=>#total_pay}
)}"%>
}
</script>
And this is the action for my partial view:
def distribute_payments
#total_amount=params[:total]
#no_payments=params[:no_payments]
#total_payment=params[:total_pay]
#guardian = Guardian.find(params[:id])
#students=Student.find_all_by_sibling_id(#guardian.ward_id)
render(:update) do |page|
page.replace_html 'payments_distribute', :partial=>'distribute_payments', :total_pay=>#total_payment, :no_payments=>#no_payments
end
end
The problem here is that I need to pass the value of "no_payments" with the parameters to my partial view, and I don't know how to do this from my Javascript function (remote_function). I was trying to use render_partial with a submit button, but I wasn't able to open the partial view in the same page. You can check my question here: Rails: Render Partial from controller
You need to use Ajax:
<script type="text/javascript">
function generate() {
var t = document.getElementById("total").value;
var n = document.getElementById("no_payments").value;
var id="<%= #guardian.id %>"
j('#total_pay').val("<%= #total_pay %>");
document.getElementById("gen").style.display = "none";
j.ajax({
type: 'POST' ,
url: '<%= url_for :action => "distribute_payments" %>',
data : {
'no_payments' :n,
'total_payment' :t,
'id' :id
},
beforeSend : function() {
},
success : function() {
j("#payments_distribute").html(data)
}});
}
</script>
Related
For some time now, I'm trying to generate a reservation form, where only available rooms are listed for the arrival and departure dates chosen in that same reservation form. Unfortunately, until now I didn't manage to do so.
I set out a question already on my previous attempt, without any success. => https://stackoverflow.com/posts/59083421/edit
I'm now trying to look for alternative ways to get there. For reference, please find my previous attempt below.
Previous attempt: general idea
Tried to send/receive an AJAX. Cannot reach the success stage, and the bug seem lie in the dataType the AJAX call is expecting/I'm sending (JS vs JSON). Unfortunately, I don't know how to solve this.
When I use format.js in my controller, I do not reach the success stage in my ajax call
when I use render json: {:rooms => #rooms} I do not reach my hotels/rooms_availability.js.erb file and subsequently am not able to insert my available rooms.
Previous attempt: code
reservations/new.html.erb
<%= simple_form_for [#hotel, #reservation] do |f|%>
<div class="col col-sm-3">
<%= f.input :arrival,
as: :string,
label:false,
placeholder: "From",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "start_date"} %>
</div>
<div class="col col-sm-3">
<%= f.input :departure,
as: :string,
label:false,
placeholder: "From",
wrapper_html: { class: "inline_field_wrapper" },
input_html:{ id: "end_date"} %>
</div>
<div class="col col-sm-4">
<%= f.input :room_id, collection: #rooms %>
</div>
<%= f.button :submit, "Search", class: "create-reservation-btn"%>
<% end %>
script for reservations/new.html.erb
<script>
const checkIn = document.querySelector('#start_date');
const checkOut = document.querySelector('#end_date');
const checkInAndOut = [checkIn, checkOut];
checkInAndOut.forEach((item) => {
item.addEventListener('change', (event) => {
if ((checkIn.value.length > 0) && (checkOut.value.length > 0)){
checkAvailability();
}
})
})
function checkAvailability(){
$.ajax({
url: "<%= rooms_availability_hotel_path(#hotel) %>" ,
dataType: 'json',
type: "POST",
data: `arrival=${start_date.value}&departure=${end_date.value}`,
success: function(data) {
console.log('succes')
console.log(data);
},
error: function(response) {
console.log('failure')
console.log(response);
}
});
};
</script>
hotels_controller
def rooms_availability
hotel = Hotel.includes(:rooms).find(params[:id])
arrival = Date.parse room_params[:arrival]
departure = Date.parse room_params[:departure]
time_span = arrival..departure
#unavailable_rooms = Room.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival <= ? AND ? >= reservations.departure", arrival, departure).distinct
#hotel_cats = hotel.room_categories
#hotel_rooms = Room.where(room_category: hotel_cats)
#rooms = hotel_rooms - #unavailable_rooms
render json: {:rooms => #rooms}
#respond_to do |format|
#format.js
#end
end
def room_params
params.permit(:arrival, :departure, :format, :id)
end
hotels/rooms_availability.js.erb
var selectList = document.getElementById('reservation_room_id')
function empty() {
selectList.innerHTML = "";
}
empty();
<% unless #rooms.empty? %>
<% #rooms.each do |room|%>
selectList.insertAdjacentHTML('beforeend', '<option value="<%= room.id %>"><%= room.name %></option>');
<% end %>
<% end %>
I wrote a rails form and it was working fine until I added a javascript to it. This javascript sums field values enter by user and saves them in a total field so user don't have to manually total it.
here is my code:
<script type="text/javascript">
function findTotal(){
console.log("this is working")
var arr = document.getElementsByName('qty');
var tot=0;
for(var i=0;i<arr.length;i++){
if(parseInt(arr[i].value))
tot += parseInt(arr[i].value);
}
document.getElementById('total').value = tot;
}
</script>
<%= bootstrap_form_for(#payment) do |f| %>
<div class="field">
<%= f.text_field :student_id,label: "Admission Number of Student" %>
</div>
<div class="field">
<%= f.number_field :tuition_fee , onblur: "findTotal()", id: "qty1", name: "qty" %>
</div>
<div class="field">
<%= f.number_field :fine, onblur: "findTotal()", id: "qty2", name: "qty" %>
</div>
<div class="field">
<%= f.number_field :previous_books, onblur: "findTotal()", id: "qty3", name: "qty" %>
</div>
<div class="field">
<%= f.number_field :annual_fund, onblur: "findTotal()", id: "qty4", name: "qty" %>
</div>
<div class="field">
<%= f.hidden_field :total, name: "total", id: "total" %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-success" %>
</div>
<% end %>
Now when I fill the form, the function works fine and submitting button creates record as well but all the values entered in these number fields are not stored in the database and it shows nil. If I remove it from number fields, these work fine. Any idea what I am doing wrong? thanks.
EDIT:
here are my params:
private
# Use callbacks to share common setup or constraints between actions.
def set_payment
#payment = Payment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def payment_params
params.require(:payment).permit(:student_id, :section_id, :year, :month, :date, :payment_mode, :tuition_fee, :fine, :previous_books, :annual_fund, :total)
end
end
and relevant controller method:
def create
#payment = Payment.new(payment_params)
#payment.student_id = Student.find_by_admission_number(#payment.student_id).id
#payment.section_id = Student.find(#payment.student_id).section_id
respond_to do |format|
if #payment.save
format.html { redirect_to new_payment_path, notice: 'Payment Record was successfully created.' }
format.json { render :show, status: :created, location: #payment }
else
format.html { render :new }
format.json { render json: #payment.errors, status: :unprocessable_entity }
end
end
end
The problem is that you are overriding the 'name' attributes. They should be like, for example: name="payment[fines]". So, when you do submit, it generates the following object:
Parameters=> { payment => { fines: value} }
That is spected in your controller (payment_params)
If I have a controller that return a json, How can I load the json data result into the page using jquery, also my webpage is using the remote true, so the request will be ajax, the result json is return to the page, bu t now I need to load the json array into the handsontable. I need somekind of binding of the data returned by the json call into the handsontable object.
class GradesController < ApplicationController
def index
logger.debug params
respond_to do |format|
format.html
format.json { render json: GradesDatatable.new(view_context) }
#format.js { #result = GradesDatatable.new(view_context).as_json }
end
end
end
Webpage
<div class="row">
<%= simple_form_for :filters, url: grades_index_path('json'), method: :get, :remote => true do |f| %>
<div class="small-4 columns">
<%= f.input :curso, collection: Curso.all, :label_method => "nombre", :value_method => "nombre" %>
<%= f.input :seccion, collection: Seccion.all, :label_method => "nombre", :value_method => "nombre" %>
<%= f.collection_radio_buttons :tanda, [['M', 'Matutina'] ,['D', 'Despertina'],['N', 'Nocturna']], :first, :last, :checked => 'M' %>
</div>
<div class="small-3 columns">
<div class="form-actions">
<%= f.button :submit, "Filtrar", :class => "button large" %>
</div>
</div>
<% end %>
</div>
<div class="row">
<div id="grades"></div>
</div>
JS
$(function(){
data = []
window.data = data.aaData
var container = document.getElementById('grades');
window.hot = new Handsontable(container,
{
data: window.data,
...
I'm building a Rails app that takes credit cards and I'm trying to use Stripe to do it. I'm having some issues passing the data from my app to Stripe in order to charge. That's what I'm hoping to get help with on this topic.
First, I have a standard form (with values instead of placeholders for quick submitting for testing purposes). The form successfully enters the name and email into the DB and the customer's "plan" is hardcoded in the controller for the time being:
<%= form_for #customer do |f| %>
<div class="payment-errors"></div>
<div class="name field">
<%= f.label :name %>
<%= f.text_field :name, :value => "Your name" %>
</div>
<div class="email field">
<%= f.label :email %>
<%= f.text_field :email, :value => "yourname#example.com" %>
</div>
<div class="cc_number field">
<%= label_tag 'cc_number' %>
<%= text_field_tag 'cc_number', nil, :value => "4242424242424242" %>
</div>
<div class="ccv field">
<%= label_tag 'ccv' %>
<%= text_field_tag 'ccv', nil, :value => "123" %>
</div>
<div class="cc_expiration field">
<%= label_tag 'cc_month', "Expiration date" %>
<%= text_field_tag 'cc_month', nil, :value => "12" %>
<%= text_field_tag 'cc_year', nil, :value => "2012" %>
</div>
<div class="actions">
<%= f.submit "Continue", :class => 'btn' %>
</div>
<% end %>
Also in my signups_view where the above code is, I have this JS, mostly provided by Stripe:
<script type="text/javascript">
// this identifies your website in the createToken call below
Stripe.setPublishableKey('<%= STRIPE['public'] %>');
function stripeResponseHandler(status, response) {
if (response.error) {
// show the errors on the form
$(".payment-errors").text(response.error.message);
$("input[type=submit]").removeAttr("disabled");
} else {
var form$ = $("form");
// token contains id, last4, and card type
var token = response['id'];
// insert the token into the form so it gets submitted to the server
form$.append("<input type='hidden' name='customer[stripe_token]' id='stripeToken' value='" + token + "'/>");
// and submit
$('.cc_number.field, .ccv.field, .cc_expiration.field').remove();
form$.get(0).submit();
}
}
$(document).ready(function() {
$("form").submit(function(event) {
// disable the submit button to prevent repeated clicks
$('input[type=submit]').attr("disabled", "disabled");
Stripe.createToken({
number: $('#cc_number').val(),
cvc: $('#ccv').val(),
exp_month: $('#cc_month').val(),
exp_year: $('#cc_year').val()
}, stripeResponseHandler);
// prevent the form from submitting with the default action
return false;
});
});
</script>
There seems to be a problem with the line form$.append("<input type='hidden' name='customer[stripe_token]' id='stripeToken' value='" + token + "'/>");, as my Ruby app breaks when it gets to customer[stripe_token].
Finally, in my `customers_controller`, I have:
def create
#customer = Customer.new(params[:customer])
#customer.product =
if #customer.save
save_order
redirect_to #customer
else
render action: 'new'
end
def save_order
Stripe.api_key = STRIPE['secret']
charge = Stripe::Charge.create(
:amount => 20,
:currency => "usd",
:card => #customer.stripe_token,
:description => "Product 1"
)
end
Whenever I submit the form, it hits the else clause in the controller each time and after plenty of debugging, Googling around and stripping out this from and rebuilding from scratch, I'm still stumped.
Any help would be very very much appreciated.
Edit: Added the customer model
attr_accessible :name, :email, :stripe_token, :product
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence => true,
:format => { :with => email_regex },
:length => { :minimum => 6, :maximum => 60 },
:uniqueness => { :case_sensitive => false }
validates :name, :length => {:minimum => 2, :maximum => 80 }
It would help to see your Customer model to get an idea of what's going on. If #customer.save returns false, it means that a validator is likely failing.
Also, do you have stripe_token as an accessible attribute on your model? Otherwise you won't be able to assign it form the form like you're doing. Note that the token should not be stored in the database, since it can only be used once.
class Customer
attr_accessor :stripe_token # do you have this?
end
One more note: you will probably want to store a Stripe ID field so that you can retrieve customer payments and cancel their account later.
Hello guys i am trying attempt a dynamic select here. as soon as i select the customer his total value in the bill should come and get displayed in the text field tag.
the view
jQuery(document).ready(function(){
jQuery(".customerid").bind("change", function() {
var data = {
customer_id: jQuery(".customerid :selected").val()
}
jQuery.ajax({
url: "get_cust_bill",
type: 'GET',
dataType: 'script',
data: data
});
});
});
</script>
<div class ="customerid"><%= f.label :customer_id %>
<%= f.collection_select :customer_id, Customer.all, :id, :name, options ={:prompt => "-Select a Customer"}, :class => "state", :style=>'width:210px;'%></div><br />
<div class ="customerbill">
<%= f.label :total_value, "Total Value" %>
<%= render :partial => "customerbill" %>
js.erb file
jQuery('.customerbill').html("<%= escape_javascript(render :partial => 'customerbill') %>");
the customerbill partial
<% options = []
options = #cust_bill.total_value if #cust_bill.present? %>
<%= text_field_tag "total_value", options %>
in contoller
def get_cust_bill
#cust_bill = CustomerBill.find_all_by_customer_id(params[:customer_id]) if params[:customer_id]
end
I feel the problem lies in the partial, the way i am calling the options so can anyone guide me how to get the value in text field??? thank in advance.
From what I understand, total_value text field does not show anything. Could you try to output the value of options and check if it always has a value? I suggest you check out the documentation for the text_field_tag. Basically, it accepts three variables like this:
text_field_tag(name, value = nil, options = {})
i was using getJSON method....and i feel that can be used here. hope the followng works.
jQuery(document).ready(function()
{
jQuery(".customerid select").bind("change", function() {
var data = {
product_id: jQuery(this).val()
}
jQuery.getJSON(
"/controller_name/get_cust_bill",
data,
function(data){
var result = "";
res = parseFloat(a[1]);
jQuery('.price input').val(res);
});
});
});
controller
def get_cust_bill
#cust_bill = CustomerBill.find_all_by_customer_id(params[:customer_id]).map{|p| [p.price]} if params[:customer_id]
respond_to do |format|
format.json { render json: #cust_bill }
end
end
so no need of calling js. erb partial you can simply have
<div class = "price"><%= f.input :price, :label => 'Price', :input_html => { :size => 20} %></div><br/>
all the best :)