Javascript / jQuery - Price calculation -


i'm building events app using ruby on rails. @ moment user wishes book onto event can book , pay 1 space @ time. need offer facility them book multiple spaces , pay appropriate price - 5 spaces £10 each = £50 pay etc. i've looked appropriate solutions in ror sort i'm hitting brick wall. however, believe i've perhaps approached wrong way , solution using javascript or jquery best way forward. i'm novice @ both , need assistance in achieving objective.

here's payment/booking page -

booking page

i want user able place number of spaces in first text area , price (total amount) change accordingly.

here's other relevant code -

booking.rb -

class booking < activerecord::base      belongs_to :event     belongs_to :user      def total_amount          #quantity.to_i * @price_currency.to_money         quantity.to_i * strip_currency(event.price)     end      private          def strip_currency(amount = '')             amount.to_s.gsub(/[^\d\.]/, '').to_f         end    end 

bookings_controller.rb

class bookingscontroller < applicationcontroller      before_action :authenticate_user!      def new         # booking form         # need find event we're making booking on         @event = event.find(params[:event_id])         # , because event "has_many :bookings"         @booking = @event.bookings.new(quantity: params[:quantity])         # person booking event?         @booking.user = current_user         #@booking.quantity = @booking.quantity         @total_amount = @booking.quantity.to_f * @event.price.to_f     end      def create         # process booking         @event = event.find(params[:event_id])         @booking = @event.bookings.new(booking_params)         @booking.user = current_user         @price = price         @quantity = quantity         #@total_amount = @booking.quantity.to_f * @event.price.to_f          booking.transaction              @event.reload             if @event.bookings.count > @event.number_of_spaces             flash[:warning] = "sorry, event booked."             raise activerecord::rollback, "event booked"             end          end          if @booking.save              # charge user who's booked             # #{} == puts variable string             stripe::charge.create(amount: @event.price_pennies, currency: "gbp",                 card: @booking.stripe_token, description: "booking number #{@booking.id}")              flash[:success] = "your place on our event has been booked"             redirect_to event_path(@event)         else             flash[:error] = "payment unsuccessful"             render "new"         end          if @event.is_free?              @booking.save!             flash[:success] = "your place on our event has been booked"             redirect_to event_path(@event)         end     end      #def total_amount         #@total_amount = @booking.quantity * @event.price     #end      private        def booking_params         params.require(:booking).permit(:stripe_token, :quantity)       end  end 

bookings.new.html.erb

<div class="col-md-6 col-md-offset-3" id="eventshow">   <div class="row">     <div class="panel panel-default">         <div class="panel-heading">             <h2>confirm booking</h2>         </div>              <div class="panel-body">                     <p>confirm number of spaces wish book here:                   <input type="number" placeholder="1"  min="1" value="1"></p>                 <p>total amount   £<%= @event.price %></p>                 <%= simple_form_for [@event, @booking], id: "new_booking" |form| %>                     <span class="payment-errors"></span>                  <div class="form-row">                     <label>                       <span>card number</span>                       <input type="text" size="20" data-stripe="number"/>                     </label>                 </div>                  <div class="form-row">                   <label>                   <span>cvc</span>                   <input type="text" size="4" data-stripe="cvc"/>                   </label>                 </div>                  <div class="form-row">                     <label>                         <span>expiration (mm/yyyy)</span>                         <input type="text" size="2" data-stripe="exp-month"/>                     </label>                     <span> / </span>                     <input type="text" size="4" data-stripe="exp-year"/>                 </div>             </div>             <div class="panel-footer">                     <%= form.button :submit %>               </div>   <% end %> <% end %>        </div>   </div> </div>      <script type="text/javascript" src="https://js.stripe.com/v2/"></script>  <script type="text/javascript">   stripe.setpublishablekey('<%= stripe_public_key %>');   var striperesponsehandler = function(status, response) {     var $form = $('#new_booking');      if (response.error) {     // show errors on form     $form.find('.payment-errors').text(response.error.message);     $form.find('input[type=submit]').prop('disabled', false);     } else {     // token contains id, last4, , card type     var token = response.id;     // insert token form gets submitted server     $form.append($('<input type="hidden" name="booking[stripe_token]"     />').val(token));     // , submit     $form.get(0).submit();     }   };    // jquery(function($)  { - changed line below   $(document).on("ready page:load", function () {      $('#new_booking').submit(function(event) {       var $form = $(this);        // disable submit button prevent repeated clicks       $form.find('input[type=submit]').prop('disabled', true);        stripe.card.createtoken($form, striperesponsehandler);        // prevent form submitting default action       return false;     });   }); </script> 

one aspect of building site didn't appreciate how difficult , complex can deal money when using ror. few of suggestions i've received stated should using monetize gem (i'm not, i'm using money-rails) , coupled model method/mvc magic achieve this. however, think i'd prefer route if right solution can found.

as suggest, 1 approach use javascript calculate total.

you change snippet of view:

<p>   confirm number of spaces wish book here:   <input type="number" placeholder="1"  min="1" value="1"> </p> <p>total amount   £<%= @event.price %></p> 

to make easier target jquery , provide reference price per space. example:

<div class="calculate-total">   <p>     confirm number of spaces wish book here:     <input type="number" placeholder="1"  min="1" value="1">   </p>   <p>     total amount     £<span class="total" data-unit-cost="<%= @event.price %>">0</span>   </p> </div> 

using javascript, can listen keyup event on input field , perform calculation.

$('.calculate-total input').on('keyup', calculatebookingprice);  function calculatebookingprice() {   var unitcost = parsefloat($('.calculate-total .total').data('unit-cost')),       numspaces = parseint($('.calculate-total .num-spaces').val()),       total = (numspaces * unitcost).tofixed(2);    if (isnan(total)) {     total = 0;   }    $('.calculate-total span.total').text(total); } 

having function separated event listener means call when page loads have starting value.

here's fiddle demonstrate (it assumes @event.price 10).

update

the key here @event.price should return unit price of booking. new action can simple this:

def new   # find event booking.   @event = event.find(params[:event_id])   # @event.price should return unit cost of booking.    # don't need set attributes here -- can add them in create.   @booking = @event.bookings.new end 

also note if want store quantity and/or total_amount on @booking object, should move fields inside form (simple_form_for) , adjust markup submitted part of booking. this:

<%= simple_form_for [@event, @booking], id: "new_booking" |form| %>   <%= f.input :quantity %>   <%= f.input :total_amount %>   ... 

and adjust javascript target these inputs (instead of input , span in original post).


Comments

Popular posts from this blog

java - Jasper subreport showing only one entry from the JSON data source when embedded in the Title band -

mapreduce - Resource manager does not transit to active state from standby -

serialization - Convert Any type in scala to Array[Byte] and back -