Rails - Javascript - Add param to params before form submit - javascript

I have a form for multiple pupils, with checkboxes next to each pupil to collect their IDs. I'm trying to have two buttons that each lead to different forms, and I've tried submitted params with the button click but to no avail:
simple_form_for - multiple submit buttons with different params
Is there any way to write some JS that adds a parameter to the params before submitting the form? My form is as follows:
<%= simple_form_for :pupils, url: edit_multiple_school_group_pupils_path(school, group) do |f| %>
...
...
<%= f.button :submit, 'Change Levels', name: 'editing', value: 'levels' %>
<%= f.button :submit, 'Move to A Class', name: 'editing', value: 'classes' %>
<% end %>
Each of the buttons have their own ID in the raw HTML so I'm hoping theres a way to pluck that before the form gets submitted and add it to the params.
I'm extremely green with JS so wouldn't even know where to start. Thanks in advance.

I'm not 100% sure what is needed for the rails portion, but it sounds like you want to serialize your form.
This is fairly easily accomplished. Here is an example of what a serialize to JSON function might look like
function toJSONString( form ) {
var obj = {};
var elements = form.querySelectorAll( selectors );
for( var i = 0; i < elements.length; ++i ) {
var element = elements[i];
var name = element.name;
var value = element.value;
if( name ) {
obj[ name ] = value;
}
}
return JSON.stringify( obj );
}
The selectors can be pretty much whatever you want within your form. Inputs, textareas, buttons etc.
Hope this helps!

Related

Rails: Making each choice in a form select field render relevant input in another form field

Noob here so I apologize ahead of time for sounding like an amateur. I'm trying to code an e-commerce site. Customers will order posters from images uploaded to the site and get to choose the size of poster (h x w) they want depending on the dimensions of the original image. I have a form for creating a new order and one of the fields is a select field with the poster size options. When they select a size, I want a price to automatically update in a separate field in the form so they know before submitting the form what the price will be.
The strategy I've been trying is to add jQuery onclick code in the select field choices. Here's what I have for the form (just showing the first choice in the select field for brevity):
<%= form_for(#order) do |f| %>
<div id="order_form">
<div class="field">
<%= f.label(:size) %><br>
<%= f.select(:size, [link_to("#{#image.dimensions['width']/120} * #{#image.dimensions['height']/120}", '#', :onclick => "showPrice('#{#image.dimensions['width']/120} * #{#image.dimensions['height']/120}'); return true;"), ... ]) %>
</div>
<div class="field">
<%= f.label(:price) %><br>
<%= f.text_field :price, :id => 'price' %>
</div>
</div>
And in assets>javascripts>application.js my jQuery code is:
function showPrice(size) {
$("#price").html("$" + size * 0.08);
}
It's not working and I don’t know if what I’m trying to do won’t work or if I'm just doing it wrong.
Thanks in advance for any help.
Here's the solution I came up with finally... I changed my goal a little, instead of trying to make it so when the user selects the size it will automatically update the price field I just made a separate paragraph (not a form field). Here's what it looks like:
<div id="order_form">
<p id='price'><%= '$' + :size.to_int * 0.8 %></p>
<div class="field">
<%= f.label(:size) %><br>
<%= f.select :size, ["#{#image.dimensions['width']/120} X # {#image.dimensions['height']/120}", "#{#image.dimensions['width']/140} X #{#image.dimensions['height']/140}", "#{#image.dimensions['width']/160} X #{#image.dimensions['height']/160}", "#{#image.dimensions['width']/180} X #{#image.dimensions['height']/180}", "#{#image.dimensions['width']/200} X #{#image.dimensions['height']/200}", "#{#image.dimensions['width']/220} X #{#image.dimensions['height']/220}"], {}, :oninput => "showPrice(this)" %>
</div>
</div>
and here's my jQuery function:
function showPrice(size) {
var Amt = $(size).val();
var arr = Amt.split(" ");
var newerAmt = Math.round( arr[0] * arr[2] * 0.8);
$("#price").html('Price: $' + newerAmt);
}
This works except it's not automatically showing the price when the page with the form loads with the default size... any advice on that would be great...
~~~~~~~~~
OK I finally figured that last part out. I referred to another thread on here and it led me to this solution so sorry for the resubmit but here it is:
To get JavaScript to recognize the ruby symbol :size I added this div in that same file:
<%= content_tag :div, class: "size_information", data: {size: #size} do %>
<% end %>
It isn't visible in the browser but it contains the data we need for JS.
Then in the JS function on that same page I referred to that data and then was able to use it as a variable:
<%= javascript_tag do %>
$(document).ready(function() {
var size = $('.size_information').data('size');
var arr = size.split(" ");
var newerAmt = Math.round( arr[0] * arr[2] * 0.8);
$("#price").html('Price: $' + newerAmt);
})
<% end %>
I would try something like this.
$('select#size').change( function () {
var amount = $('select#size').val();
var newAmt = amount * 0.08
$('#price').val('$' + newAmt);
})
Try breaking down the parts of the code to see which is working and which are not.
For example start with something simple like this
$('select#size').change(function () {
var amount = $('select#size').val();
console.log(amount)
//checking to see if .change function works
//and if you are able to collect the value of
//whats inside 'select#size'
})
If this works then maybe you can consider doing the next line
var newAmt = amount * 0.08
console.log(newAmt)
If this works then next would be to try checking to see if you are successfully calling on the #price field.
var price = $('#price').val();
console.log(price)
So if thats working then maybe you can try placing values into #price first
$('#price').val('its working!')
If all of them are working, combining the whole code should work too. Hope this helps!

calling .val() on date_select element returning undefined?

I'm trying to obtain the selected date from a date_select:
<%= form_for(#newevent) do |f| %>
<%= f.date_select :day, { id: "date-select"} %>
<button id="check-button" type="button">Check</button>
<% end %>
using JQuery/Javascript:
$(document).on('click', "#check-button", function(){
var selectedDate = $("#date-select").val();
alert(selectedDate);
var checkList = []; //creates array to store customer ids
$("#check-list li input").each(function(){ //for each listed colleague...
if( $(this).is(":checked")){ //if check-box is ticked
checkList.push($(this).val()); //add id to list
}
});
$.ajax({
url: '/events/check',
data: {checkList: checkList , selected_date: selectedDate },
method: "POST"
}
);
});
for reference here is where :day is defined in my migration file:
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.timestamps
t.references :calendar, foreign_key: true
...
t.date :day
...
end
However, on alert the returned value is "undefined". Why is this happening? I would like it to return the a value in the form YYYY-MM-DD. Apologies if this is obvious, but I am new to programming and can't seem to fix this one myself
Date_select, according to the rails api "Returns a set of select tags (one for year, month, and day)". Your javascript is going to have to deal with three separate selects and construct a date from them. Look at your generated HTML to get the id's.

Javascript / Jquery Split Variable Into Two for Stripe Integration

I apologize in advance as I am fairly good with PHP, but when it comes to javascript and jquery, I really am a bit clueless. I have the following code, which I edited from the example found here https://gist.github.com/boucher/1750375, and wanted to combine the credit card exp month and year field into one. The issue is splitting them back apart to use with the stripe example code where it creates a token. Obviously the example on github works perfectly but when I attempt to edit, the script doesn't act like anything is wrong but doesn't submit to stripe and retreive the token as before.
$(document).ready(function() {
$("#payment-form").submit(function(event) {
// disable the submit button to prevent repeated clicks
$('.submit-button').attr("disabled", "disabled");
var expgroup = document.getElementById('date-exp').val;
var expArray = expgroup.split( '/' );
var expmm = ( expArray[ 0 ] );
var expyy = ( expArray[ 1 ] );
// createToken returns immediately - the supplied callback submits the form if there are no errors
Stripe.createToken({
number: $('.cc').val(),
cvc: $('.card-cvc').val(),
exp_month: expmm,
exp_year: expyy
}, stripeResponseHandler);
return false; // submit from callback
});
});
This won't work.
var expgroup = document.getElementById('date-exp').val;
use this instead:
var expgroup = $("#date-exp").val()
Also "cc" is id and not a class.
You need to use:
$("#cc").val()
and not:
$(".cc").val()
document.getElementById('date-exp').val
Is a mixture of jQuery and DOM idiom. It should either be:
document.getElementById('date-exp').value
or:
$('#date-exp').val()
Also consider checking that / is actually in the value (ie that expArray.length===2).
Stripe's jquery.payment library has this function built into it already:
https://github.com/stripe/jquery.payment#paymentcardexpiryvalstring-and-fnpaymentcardexpiryval
Here's some sample code.
# form fields on HTML.ERB page
<%= form_tag url do %>
<%= text_field_tag :expiry, nil, name: nil, placeholder: "MM / YYYY", size: 9, id: "stripe-card-expiry" %>
<%= hidden_field_tag :exp_month, nil, name: nil, id: "stripe-card-exp-month", data: { stripe: "exp-month" } %>
<%= hidden_field_tag :exp_year, nil, name: nil, id: "stripe-card-exp-year", data: { stripe: "exp-year" } %>
...other fields and submit...
<% end %>
# Split single expiration field into month/year
expiration = $("#stripe-card-expiry").payment("cardExpiryVal") # => {month: "value", year: "value"}
$("#stripe-card-exp-month").val(expiration.month || 0)
$("#stripe-card-exp-year").val(expiration.year || 0)
# Submit to Stripe.com and get token
Stripe.card.createToken($("#form-id"), handleStripeResponse)
Depending on which version of Stripe.js you are using, if you use the "data-stripe..." items Stripe.js will automatically grab the values from the hidden fields.

Rails and jQuery: How to select input from a specific form

I have a rails app with a job model, and on the index page, each job has a form. I need to be able to access the specific form everytime the submit button is selected, so I can take the input for the form and perform some jQuery validation with it.
Here is some of my index.html page.
<ul>
<% #unassigned.each do |job| %>
<li>
<div class="row new-message">
<div class="small-12 columns">
<%= form_for #message do |f| %>
<%= f.text_area :body, {placeholder: 'enter a new message...'} %>
<%= f.hidden_field :job_id, value: job.id %>
<%= f.submit 'send message', class: 'button small radius secondary message-button', "data-job-id" => job.id %>
<div id="message<%= i %>-validation-errors"> </div>
<% end %>
</div>
</div>
<li>
<% end %>
<ul>
And here is the javascript/jQuery where I try to select the input from a specific form
var messages;
messages = function() {
$('.message-button').click(function(e) {
var id = $(this).data('job-id');
messageValidation(e, id);
});
function messageValidation(e, id) {
var body = $('#message_body').val();
var div = '#message' + id + '-validation-errors';
if(body == "") {
$(div).html('');
e.preventDefault();
$(div).html('<small style="color:red"> Message body empty </small>');
}
};
};
$(document).ready(messages);
The index page will have a form for each job, and I want there to be front end validation that checks when the button is submitted, that the body field is not empty. It works fine the first time, but after going back to the index page, and trying to validate a second time var body = $('#message_body').val(); always seems to be empty, whether I put anything in the body or not. I believe it has something to do with the fact that since there is the same form for each job, there are multiple #message_body id's on the same page, and it is selecting the incorrect one. I am new to jQuery and javascript can someone please help me
You cannot have multiple elements with same id on a page. What you can do is add a class identifier to those elements.
In your case, simple set class="message_body" to your elements and select them as shown below:
$('.message-button').click(function(e) {
var id = $(this).data('job-id');
var body = $(this).parent().find('.message_body').val();
messageValidation(e, body, id);
});
To solve this problem I needed to select the child of the form and find the message_body through that.
messages = function() {
$('.new_message').submit(function(e) {
//var id = $(this).data('job-id');
var $this = $(this);
var body = $this.children('#message_body').val();
var id = $this.children('#message_job_id').val();
messageValidation(e, body, id);
});
function messageValidation(e, body, id) {
var div = '#message' + id + '-validation-errors';
if(body == "") {
$(div).html('');
e.preventDefault();
$(div).html('<small style="color:red"> Message body empty </small>');
}
};
};

clear input after search

I have a search box on my site. The search works well. I'd like the search field to clear after you submit a search. I have it working to clear onclick but the onsubmit doesn't work. It is definitely submitting a search because I can see the results.
js
<script type="text/javascript">
function clearDefault(el) {
if (el.defaultValue==el.value) el.value = ""
}
function clearText(thefield){
if (thefield.defaultValue==thefield.value)
thefield.value = ""
}
</script>
view
<%= form_tag guidelines_path, :class => 'navbar-search pull-right', :onSubmit=>"clearText(this)",:method => :get do %>
<%= text_field_tag :search, params[:search], :class => 'search-query', :placeholder=>"Search", :ONFOCUS=>"clearDefault(this)" %> <% end %
>
Th onsubmit isn't an event of a text field but rather the form it belongs to. If you move your onsubmit attribute to the form, it should clear it.
Rather than pass the field as a parameter, why not just fetch the field by it's class? So using jquery:
function clearText(){
search = $('.search-query');
if (search.defaultValue==search.value)
search.value = ""
}
If you can't use jQuery for some reason you could try and assign the form field an ID and use document.getElementById() instead?

Categories

Resources