I'm working on a rails form where I need to send an array created in Jquery to my rails controller. I've had a hard time getting the data in the proper format.
I managed to get the Jquery array to send through AJAX when doing an update of this model. It sends the normal PATCH and an additional PATCH for the array parameter. So 2 updates. Everything works find for updates, it's a bit hacky but does what I need it to.
This doesn't work on create though since I can't send two POST requests to create the same object? Does that make sense?
So I guess my question is how can I get my AJAX data to tag along with the normal form submit?
Here's
$('#employer_job_submit_button').on('click',function(){
$.ajax({
url:"/jobs/<%= #job.id %>",
type:'PATCH',
dataType:'json',
data:{
job: {
benefits: tags_array
}
}
});
});
Here's my view (part of it)
<%= form_for #job, :html => {:class => 'profile_form'} do |f| %>
.....
<div>
<%= f.submit "Post Job", class: "btn btn-primary btn-block", id: "employer_job_submit_button" %></div>
</div>
<% end %>
I tried separate code just for creating new jobs. Like this:
$('#employer_job_submit_button').on('click',function(e){
e.preventDefault();
var form_data = $('form').serialize()
$.ajax({
url:"/jobs",
type:'POST',
dataType:'json',
data:{
job: form_data
}
});
});
That sends all my form data through AJAX but I can't figure out how to add the "benefits" array to the form data. Also this is not really what I want to do because it bypasses the standard Rails form.
I just want to add my Jquery created array along with the form data.
That sends all my form data through AJAX but I can't figure out how to add the "benefits" array to the form data.
You may simply add the stringified array version to your data.
From:
dataType:'json',
data:{
job: form_data
}
To:
data: {
job: form_data,
benefits: JSON.stringify(tags_array)
}
In this way you will receive on your server two variables like in the following example:
job:firstname=Mickey&lastname=Mouse
benefits:["Saab","Volvo","BMW"]
Instead, if you want to continue to add to your serialized form data your array you can use jquery param like in the following:
var form_data = $('form').serialize() + '&' + $.param({"benefits": tags_array});
In this last way you need to decode the job parameter in your server side in order to extract the **benefits" array.
Related
I am trying to send data through a get request using ajax but the param doesn't seem to be getting sent. I have a page that shows a random item from the db. You get to this page from a link in the navbar. Once on this page there is a link that allows you to skip the current item to find another random item making sure the next item isn't the one the user was just viewing.
routes.rb
get 'pending', to: 'items#pending'
view
<%= link_to 'Skip', '', class: "btn btn-default btn-xs",
id: "skip-btn",
:'data-item-id' => #pending_item.id %>
controller
def pending
#previous_pending_item_id = params[:id] || 0
#pending_items = Item.pending.where("items.id != ?", #previous_pending_item_id)
#pending_item = #pending_items.offset(rand #pending_items.count).first
respond_to do |format|
format.js
format.html
end
end
I have respond to both html and js because I am using the action for the navbar link as well as the link on the page. The link on the page is the skip button which should bring up another random item.
sitewide.js.erb
$('#skip-btn').on('click', function () {
$.ajax({
data: {id: $(this).data("item-id")},
url: "/pending"
});
});
When I look in the server log is says Started GET "/pending"... but doesn't make any mention of a param being sent. What am I missing?
The reason I'm using ajax for this is because I don't want the param showing in the url.
For clarification I need the url when visiting this page to always be /pending with no params or additional :id identified in the url. This page should always show a random record form the db. The only reason I need to send a param is to make sure no record is every repeated consecutively even though they are random.
I think you need to prevent default link action:
$('#skip-btn').on('click', function (event) {
event.preventDefault();
...
});
While you can do it the way you're attempting, I think it's worth pointing out that sending data in a GET request is a bit of an antipattern. So why not doing it the "correct" way!
Change your routes.rb to:
get 'pending/:id', to: 'items#pending'
and change sitewide.js.erb to:
$('#skip-btn').on('click', function () {
$.ajax({
url: "/pending/" + $(this).data("item-id")
});
});
I'd like you to check for the format its sending the the query to your controller. And the type of format you want to receive at the front end.
$('#skip-btn').on('click', function (e) {
e.preventDefault();
$.ajax({
dataType: 'json', //This will ensure we are receiving a specific formatted response
data: {id: $(this).data("item-id")},
url: "/pending"
});
});
In your controller maybe you want to pass it back as a json object.
def pending
##previous_pending_item_id = params[:id] || 0
#No need to make it an instance variable
previous_pending_item_id = params[:id] || 0
#Same goes for pending_items. No need to make it a instance variable, unless you're using it somewhere else.
pending_items = Item.pending.where("items.id != ?", previous_pending_item_id)
#pending_item = pending_items.offset(rand pending_items.count).first
respond_to do |format|
format.js
format.html
format.json { render json: #pending_item.as_json }
end
end
So that you can take value from response and append it to your page.
Similarly if you are expecting a js or html response back, you should mention that in your ajax call. Let me know if it does help you resolve your issue.
Update:
Let's say in your page, it shows the data of #pending_item object in a div,
<div id="pending_item">...</div>
When you're making a ajax request to your controller you want div#pending_item to show the a new random pending_item.
$('#skip-btn').on('click', function (e) {
e.preventDefault();
$.ajax({
dataType: 'html', //we'll receive a html partial from server
data: {id: $(this).data("item-id")},
url: "/pending",
success: function(res){
//We'll set the html of our div to the response html we got
$("#pending_item").html(res);
}
});
});
In your controller you do something like:
format.html { render partial: 'pending_item', layout: false }
And in your partial file "_pendint_item.html.erb" you'll access your instance variable #pending_item and display data
This will send the response to server as html, and there you'll only set your div's html to this.
Update 2
Your partial might look like this, or just however you want to display your pending item. The thing to know is it will be accessing the same instance variable #pending_item you have defined in your controller's method, unless you pass locals to it.
<div class="pending_item">
<h3><%= #pending_item.name %></h3>
<p><%= #pending_item.description %></p>
</div>
I suggest you do a console.log(res) in the success callback of your ajax call to see what you're getting back from server.
I have used ajax to get the object from controller.
$('#city').on('change',function(){
$.ajax({
url: "/courses/index",
type: "GET",
data: {city: $('#city').val() },
success: function(responseData) {
alert(responseData);
}
});
So the responseData is the json format collection of the courses.
Currently, I have a html code: <%= #courses.first.name %>
How to modify the #courses instance which the result is the responseData of ajax.
Thanks.
You can't change the instance variable, because that belongs to the instance of the Ruby class you're using.
Using ajax invokes a new instance of your respective classes (on the server); javascript only works with the front-end view (HTML code / DOM), so you have to populate that with the response:
$(document).on('change', '#city', function(){
$.ajax({
url: "/courses/index",
type: "GET",
data: {city: $('#city').val() },
success: function(responseData) {
course = JSON.parse(responseData);
$(".element").html(course.name);
}
});
});
Without knowing which data you're expecting back etc, it's kind of tough to know how to "parse" your data. However, the important thing to note is that you should not be trying to change the ERB, instead identify the html and replace it with the JSON you receive back.
Also, you'll need to use something like JSON.parse to create a workable object in your javascript (which you can then use to populate your page with).
Sounds like you want to POST the information back to the rails application via Ajax.
Hopefully this question isn't too similar to others out there. I've spent a number of hours researching it, but apparently I don't quite know the terms to search for.
Using Rails 4, I'd like to use an ajax request to load data from a database table and use it to update a chart. I have succeeded in doing this by making a controller method and view, populating the view with the data, and then fetching that via ajax. The question is: how can this be done without creating a view? My solution is not terribly elegant, and I'm hoping for some more excellent solutions. I need to make a few more charts, and I would rather not make new views for each one if possible.
user_controller.rb
def asset_allocations
#AAPL = ....
#GOOG = ....
end
asset_allocations.html.erb
<div id="AAPL">
<%= #AAPL %>
</div>
<div id="GOOG">
<%= #GOOG %>
</div>
assets.js.erb
$(document).ready(function() {
$.ajax({
type: 'GET',
url: "/allocations",
cache: false,
success: function(html) {
var AAPL = $(html).find('#AAPL').html();
var GOOG = $(html).find('#GOOG').html();
show_pie_chart(parseFloat(AAPL), parseFloat(GOOG));
}
});
});
use
head :no_content
in last line of action
where view not need
I have a following code that is part of the _form.html.erb code. Basically I have a form in which I have a observe_field function where on change, it will set fields' values without refreshing the page. Following is my html code:
<script type="text/javascript">
// When DOM loads, init the page.
$(function() {
// Executes a callback detecting changes with a frequency of 1 second
$("#id_element_placeholder").observe_field(1, function( ) {
$.ajax({
type: "GET",
dataType: "json",
url: "/students/get/" + this.value,
success: function(data){
$('#last_name').attr('value', data.student.last_name);
$('#building').attr('value', data.student.building);
$('#room').attr('value', data.student.room);
}
});
});
});
</script>
Problem here is that I'm exposing lot of my code in javascript. Is there a better way to do it without exposing code in javascript?
Here is what my controller looks like:
def get
#student = Student.find(params[:id])
respond_to do |format|
format.html
format.json { render :json => #student }
end
end
Basically I get an id in a form and from there I have to get the corresponding object and update the fields on the page.
Assuming your design requires you to make AJAX calls to query student info by id, then you need to expose a URL for the call. If you don't want to expose a JSON data structure, you could return a chunk of HTML (instead of JSON), and replace the contents of the container of all of the controls you mention above.
I'm trying to save dynamically created elements in my application.js file to the database. Would the code look something like this?:
$.ajax({
type: "POST",
data: { title: 'oembed.title', thumbnail_url: 'oembed.thumbnail_url'}
});
Is there anything I'm missing? Assume that oembed.title and oembed.thubnail_url hold the values I want to save, and that title and thumbnail are the database columns.
First problem I see is your data is strings. Get rid of the ' quotes
$.ajax({
type: "POST",
data: { title: oembed.title, thumbnail_url: oembed.thumbnail_url}
});
I'm going to assume you need to incorporate some user-supplied data into the new DB object - otherwise, it would be way easier to just create it from Rails.
If you're using entirely user-supplied data, you can use the serialize() method (use hidden fields for server-generated stuff):
jQuery.ajax({
url: '/path/to/whatever',
data: $('#MyForm').serialize(),
type: 'POST'
});
Or you could use the jQuery Form Plugin - it'll let you easily combine user-supplied data with server-generated data. For example:
$('#MyForm').ajaxForm({
//Hardcoded/server-generated stuff goes in here
//(and will be added to the data from the form inputs):
data: {title: oembed.title},
type: 'POST'
});
The ajaxForm() function will set up the form and its defaults, and sends an AJAX call when the user hits the submit button (see also: ajaxSubmit()).
On the Rails side, everything should work exactly the same as if the user had submitted the form normally (though you might want to just respond with a status code/message - no call for a redirect or page render).
Hope this helps!
PS: From your example, it looks like you might be able to use data: oembed in your AJAX calls. This will submit all oembed's attributes...