Rails - update flash using an ajax post action - ruby-on-rails

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 .

Related

Ajax response in erb from ruby method defined in controller

I have a ruby controller file with various methods defined, i want to get response of one of the method in erb i.e frontend using ajax call.
I am a beginner in ruby, so doesn't have much experience of handling requests in ruby, when i try to run the below code it gives error 404 in console stating url not found.
I have added relevant code snippets instead of entire code.
=> appcontroller.rb file
def returnimage_url
image_url = "http://dfdabfyag.jpg" //random url
{ :success => true, :img_value => image_url }.to_json
end
=> loadimage.erb file
<script>
function showImage(){
$.ajax({
url: '/returnimage_url',
method: 'GET',
dataType: "json",
success: function(response){
let image_data = JSON.parse(response);
console.log(image_data);
}
});
}
showImage();
</script>
You need to map the path /returnimage_url to your appcontroller.rb file and the specific method.
That should be done in your config/routes.rb file using something like this:
get 'returnimage_url', to: 'app#returnimage_url'
That will work if you rename your appcontroller.rb to app_controller.rb
See routing documentation for more info.
There are more issues in your code, but this should point you in the right direction and resolve the 404.

Rails 5: How Can a Form Submit with Custom HTTP Headers?

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.
});

Rails AJAX partial not rendering properly

I have:
<p id="click">Click here</p>
In contorller:
#details=Family.find_by(famid: params[:famid])
respond_to do |format|
format.html
format.json {render :json => #details}
end
and:
$('#click').on('click',function(){
$.ajax({
type: "GET",
data: 'famid='+id,
dataType: "json",
url: "/map",
success: function(data){
document.getElementById('myModal').innerHTML = data.famid
}
});
}
<div id="myModal"></div>
This works fine. The myModal div tag is populated by the correct famid value. But I just want to post the data to the controller via ajax and query the database and use the #details variable instead. So I tried:
$('#click').on('click',function(){
$.ajax({
type: "POST",
data: 'famid='+id,
dataType: "json", //do I need this? should it be html?
url: "/map"
});
}
Now I want to use the #details variable like:
<div id="#myModal"> <%= #details.famid %> </div>
How do I do that?
UPDATE: Ok I did the following things and everything works fine (thanks to #Rich & #NitinJ) except the partial. It's not rendered properly.
map.js.erb
$("#myModal").html("<%= escape_javascript(render(#details))%>");
_details.html.erb
<h3><%= #details.famid %></h3>
map.html.erb
<div id="myModal">
<%= render #details %>
</div>
Update:
Now the partial is rendered correctly in the browser console. I can see the #myModal div being populated correctly. But it's showing only in the browser console and not on map.html.erb page. What is wrong here?
Ajax
$('#click').on('click',function(){
$.ajax({
type: "POST",
data: {famid: id}, //you need to serialize your data
dataType: "json", //do I need this? should it be html?
url: "/map"
});
}
AJAX is quite simple - it sends a request on your behalf. The $.ajax function is from JQuery, so to get it right, you just need to pass the right arguments to it
Routes
#config/routes.rb
post "map", to: "your_controller#map"
Because you're sending a POST request (rather than GET), you'll need a route to handle the request. And since you're sending to /map, you need to ensure you're going to catch that request & send to the right controller
Controller
#app/controllers/your_controller.rb
def map
#details = Family.find_by(famid: params[:famid])
respond_to do |format|
format.html
format.json {render :json => #details}
end
end
Response
Because you're dealing with JSON, I believe you'll be best handling the response in the view directly, like this:
$('#click').on('click',function(){
$.ajax({
type: "POST",
data: {famid: id}, //you need to serialize your data
dataType: "json", //do I need this? should it be html?
url: "/map",
success: function(data) {
details = jQuery.parseJSON(data)
$('#modal_body').html(details.famid);
}
});
}
To my knowledge, JSON is meant to pass data succinctly (with as few moving parts as possible), and consequently, we always handle the JSON response from the Ajax request; rather than a separate file
You can use the jQuery.parseJSON function to handle this, creating an object you can then append to the page
Update
I believe your problem is you're using JSON
You can't load a rails .js file with JSON - you have to load .json.erb, or process in the front-end view. You may wish to change your request to standard JS:
#JS
$('#click').on('click',function(){
$.ajax({
type: "POST",
data: {famid: id},
url: "/map"
});
}
#Controller
def map
#details = Family.find_by(famid: params[:famid])
respond_to do |format|
format.js
format.html
end
end
#app/views/controller/map.js.erb
$("#myModal").html("<%=j render(#details) %>");
You have to create a js.erb template than render this template. Now you can access this variable in your *.js.erb template
alert("<%=#details.famid%>")
you can also update your text of p tag by
$("modal-body").text("<%=#details.famid%>")

Rails and Ajax communication

I have on Java web app and another Rails web app.
I need to create a jquery ajax request from java to Rails app.
How to do this.
I tried with this in jquery
$.ajax({
type: "POST",
url:"someurl",
cache:false,
success: function(data) {
//alert here
}
How to give some response to this ajax request from rails?
Is the above code correct ?
In Rails,
def index
#var1 = "myname"
respond_to do |format|
format.js{}
end
end
In index.js.erb,
alert(#var1);
In the console ,
Rendered index.js.erb (0.2ms) Completed 200 OK in 26ms (Views: 6.2ms |
ActiveRecord: 0.1ms)
Normally you can do it in jquery post.
For example:-
$.post( yourURL, {data:data}, function(response){});
yourURL will be the url which should be a valid url to any of the controller method in rails app checked by rake routes.
Then you can create the action in the controller. Suppose you are posting to the 'your_method' of index controller.
action should respond as js .
for example:-
in index controller define
def your_method
#your code here
respond_to do |format|
format.js{}
end
end
Make one js.erb file of the action. After posting to the method from ajax correctly, it will provide some response. Capture it in your response value in jquery post. and make required changes.
Hope this will help you.
Issue was, Ajax does not work on cross domain.
Java is hosted in one domain and Rails in another domain... that was the issue in my case.
I handle Ajax in java side itself now. Works fine.
I think maybe you should add datatype option to your JQuery ajax.
And It's depends on what is the your rails response
dataType: 'script', dataType: 'json' or dataType: 'text' ...
Suppose for example your model name is Post and you are calling the post method in rails it will be something like that.
$('#Button').on('change', function(event) {
var selected_resource_id = $(this).val();
$.ajax({
type: 'POST',
url: "<%= post_path %>",
data: { id: selected_resource_id },
success: function (data) {
alert("Ajax success");
}
});
});

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