Rails 5: How Can a Form Submit with Custom HTTP Headers? - ruby-on-rails

I cant seem to find any information on how to get a webform in Rails 5 to submit with custom headers. I would like the URL to which I am sending a PUT request to also receive some custom headers. I am surprised that there is no argument for form_for for this.
I could accomplish this by submitting the form to an action where I modify the headers there, e.g., request.headers['my-header'] = 'xyz'. I would then have to make the PUT request from within this "middle" controller action, and I feel this additional step is clunky and unconventional.
I could also use jQuery to bind to the submit click, and submit the form data after adding the headers via JavaScript. Id rather not involve another layer (i.e., JS) in this process.
I would rather not do either. Is there a way I can just use the Rails form helpers (or some controller helper) to add some custom headers to the request made by the form submission?

Rails does not have any tags that allows us to do that and therefore cannot add custom headers to your request.
In fact, you cannot set custom headers in html forms without xhr plugins,
You have to use it with ajax. Something like this:-
<%= form_tag("/your_url", method: :post, :remote => true, :html => { id: "form-id" }) do |f| %>
...your form here...
<% end %>
and then you ajax code:-
$('#form-id').submit(function() {
var valuesToSubmit = $(this).serialize();
$.ajax({
type: "POST",
url: $(this).attr('action'),
data: valuesToSubmit,
headers: { 'Xmlrpc-Token': 'value' , 'Token': 'another_value'}
}).success(function(response){
//success code
});
return false;
});
Using only remote: true in rails will make ajax call, but you want to be able to customize it using the code above.

Browser will send only standard headers like cookies, contenttype, etc. You can not send Authorization header (or other custom) using HTML form submit. You should use AJAX to do that.

$("#idForm").submit(function(e) {
var url = "path/to/your/script.php"; // the script where you handle the form input.
$.ajax({
type: "POST",
url: url,
data: $("#idForm").serialize(), // serializes the form's elements.
success: function(data)
{
alert(data); // show response from the php script.
}
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});
<%= form_tag("/your_url", method: :post, :remote => true, :html => { id: "form-id" }) do |f| %>
...your form here...
<% end %>
$("#idForm").submit(function(e) {
var url = "path/to/your/script.php"; // the script where you handle the form input.
$.ajax({
type: "POST",
url: url,
data: $("#idForm").serialize(), // serializes the form's elements.
success: function(data)
{
alert(data); // show response from the php script.
}
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});

Related

Rails - update flash using an ajax post action

I have an action that calls a javascript file which contains an ajax method like this one:
$.ajax({
type: 'POST',
url: "<%= some_action(model) %>",
dataType: 'json',
data: { 'something': true },
success: function(received_data) {
// Do something with received_data
$('#notice').html("<%= escape_javascript(render 'layouts/flash_messages', flash: flash).html_safe %>");
}
});
The "some_action" tries to put some info into flash[:success], and I want to get it in the success function so that I can pass it to the render.
I have already tried the flash.now[:sucess], but nothing. It seems that it is only possible to do this if I write in the flash hash from the action that calls this javascript file - but I don't want this since "some_action" will generate dynamic content.
Is that something possible to to?
Thanks for the help!
you can send js request instead of json request .
and then in your "some_action.js.haml" file you can write
$('#notice').html("<%= escape_javascript(render 'layouts/flash_messages', flash: flash).html_safe %>");
what's happening here is that your javascript file is not getting refreshed hence content of html is not changing .

Executing a rails .js.erb file from a jquery mobile form

My form spans several jquery mobile pages all within one file and wrapped by this form
new.html.erb
<%= form_tag submit_path, :method => :post, :remote => true do%>
create.js.erb
alert("Hello");
<% debugger %>
$.mobile.changePage("#confirm");
The create.js.erb gets hit as my console stops on the debugger, but the alert never fires and neither does the jquery mobile command.
My url goes from /new#confirm to just /new
I can do the (seemingly) exact same thing in a normal rails form and I get the alert.
Apparently you need to do this completely with Ajax to get rails to respond properly and have the js.erb execute:
In your form add
"data-ajax" => "false"
then
$('#submit_button').click(function(){
handleSubmit();
return false
});
function handleSubmit() {
$.ajax({
url: "/post_url",
type: 'POST',
cache: false,
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); $.mobile.showPageLoadingMsg("a", "Submitting"); },
data: $("#the_form").serialize(),
success: function(data){
handleResponse(data):
}
});
}

how to send data to controller with :remote => true with jQuery

I want to send data to controller in Rails3 with :remote => true(Unobtrusive JavaScript), but without link_to or form_tag. I want to send data(something param) to controller with jQuery response.
How I can do that?
You can send data with ajax request using jQuery as below.
bind event depending upon class and
submit ajax request from jquery function
Code:
$(document).on('click',".ajaxRequestEvent",function(){
$.ajax({
type: 'POST'
url: url,
data: {'key1':'value1', 'key2':'value2'},
success: success,
dataType: dataType
});
});
where, 'ajaxRequestEvent' is the class of the element, on clicking which your request need to be sent. As above, you can send data with jquery ajax function's 'data' attribute

Rails select_tag - how to send ajax request?

I want to send an AJAX request once an option is selected (changed) from the select_tag in Rails 3.1. Can we use :remote=>true or :onchange => remote_function() or is there some other way ?
You should definitely do this with jQuery (with an unobtrusive approach to keep things as clean as possible). On your .js file you should have something like this...
$('#select_tag_id').change(function(){
$ajax({
url: "remote_action_in_your_controller",
type: "GET",
data: {select_tag_value: $('#select_tag_id option:selected').text()},
})
});
this is as simple as it should be if you just want to call a remote action on your controller (notice I passed the value of the selected option since you probably want that value to do something with it). If you need to do something after the ajax call is executed use the succes option. Hope this helps.
You must to do it with JQuery. Something like this, when the document is ready, :
$('#your_select_tag').change(function() {
$.ajax({ type: "GET",
url: "http://your_url/",
success : function(text) {
alert('success')
}
});
});
See the doc : http://api.jquery.com/change/ and http://api.jquery.com/jQuery.ajax/.
remote: true adds data-remote="true" to the html element. Just add this as a CSS class in the select_tag options.
<%= select '', '', #coaches, {}, { data: {remote: true } } %>
Please note the data: { remote: true } is used because "data-remote" is not Ruby friendly.

rails ajax request

I have a problem when sending the Ajax request. When you click on the link request is sent to the server 3 times and the answer did not come.
Why the request is sent three times to undermine?
Where did I go wrong in the formation of a query?
code:
run.html.erb
...
<%= link_to "Next", "#", :id => 'next', :class =>
...
run.js.erb
(function(){
$("#next").click(function(){
$.ajax({
type: 'POST',
url: '/engine/tff',
success: function(data){
alert("ok");
$("#question").html(data);
}
});
return false;
});
});
controller
def tff
respond_to do |format|
format.js render :text => "hello"
end
end
I am guessing the click event is being bound multiple times probably cos the script is being called multiple times. Not sure what is the reason for the multiple calls as I am not familiar with rails.
what you could do to avoid it is unbind the click event before binding it or use the on api.
function ajaxRequest(){
$.ajax({
type: 'POST',
url: '/engine/tff',
success: function(data){
alert("ok");
$("#question").html(data);
}
});
return false;
}
$("#next").unbind("click").bind("click",ajaxRequest);
or
$(document).on("click","#next",ajaxRequest);
also not sure if you were trying to bind on document ready and there is a typo in your code. but it should be wrapped like this:
$(function(){
$("#next").click(ajaxRequest);
});
One thing I ran into recently was that jquery tries to run the result, as the default dataType interprets the .js as a script, not text. You might need to add a dataType: "text" to the ajax call. I don't see how this translates into three calls though.
I thought returning false was supposed to prevent the click from moving on, but perhaps it is better form to use preventDefault() as apneadiving suggests.

Resources