I can't believe I haven't found other questions to answer this but I've searched high and low and can't find anything that really answers my question.
Basically, I have an Expenses page in which I want to display all Expenses in a given month in a table. I have a month and year select and right now I have it working by adding month and year parameters to the url and going to that href with a little javascript. I would like to avoid a page refresh however and just update the table when the select box value is changed. As I understand it, because I'm not using a form, I can't use :remote => true
and thus have to use AJAX. My research has brought me to set things up as the following.
This is my JQuery with an AJAX call:
$(document).ready(function() {
$('#monthSelect').change(function() {
// alert("yay");
var m = $(this).val();
var y = $("#yearSelect").val();
$.ajax({
type: "GET",
url: "/expenses",
data: { month : m, year : y } ,
success: function(data) {
},
dataType: "json"
});
});
});
#monthSelect
and #yearSelect
are the ids of my two select boxes. This part seems to work. When I change the value of the month select box, it sends the GET request to "/expenses"
with the correct month and year in the params
.
/expenses
naturally routes to my index
action. Here is the part where I'm confused.
def index
@expenses = # Code that gets the expenses that correspond to the month and year in the params.
# This part works. I've tested it and @expenses are all the records I want
respond_to do |format|
format.html
format.json { render json: @expenses, status: :ok } #?????
end
end
So I guess my primary question is how the json part works, and if I should even be using json in the AJAX. Tutorials and videos I've looked at all seem to imply that getting the response in json is the way you're supposed to do it, but I'm not sure what "rendering json" even means. My understanding is that passing @expenses
, it basically will render what @expenses.to_json
returns, which is just a bunch of json, key-value pairs. How do I take that and make a table?
A friend of mine that has done plenty of AJAX but no Ruby on Rails said that I can just write the HTML in the AJAX success function
...
success: function(data) {
$("#expenses-table").html("HTML of my Table");
}
But this just doesn't seem like the Rails way, to put a bunch of Javascript code that just puts HTML into a string. And then what does the render: json
do if I'm just putting the HTML in the AJAX? I did see an answer here on Stack Overflow that had
success: function(data) {
$("#expenses-table").html(data);
}
which would be nice, since data does have all the json I want. But obviously that doesn't just work like that.
So if I could get some clarification on this whole mess, if I'm even approaching it right with JSON, or if I should just write the HTML in the AJAX, that would be much appreciated.
EDIT 1: Here's my current table code:
<table id="expenses">
<thead>
<tr>
<th>Description</th>
<th>Amount</th>
<th>User</th>
<th>Date</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @expenses.each do |expense| %>
<tr id="expenses-row">
<td><%= expense.description %></td>
<td><%= number_to_currency expense.amount %></td>
<td><%= expense.user.name %></td>
<td><%= expense.date.strftime("%m/%Y") %></td>
<td><%= link_to 'Show', expense %></td>
<% if expense.user == @user %>
<td><%= link_to 'Edit', edit_expense_path(expense) %></td>
<td><%= link_to 'Delete', expense, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% else %>
<td></td>
<td></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
Basically just the standard scaffold table. Most of the changes were just css. Here's what the json looks like for one record
[{"id":8,"description":"This is a test","amount":"35.0","user_id":1,"date":"2014-10-01","created_at":"2014-10-03T07:07:53.412Z","updated_at":"2014-10-03T07:07:53.412Z","receipt_file_name":null,"receipt_content_type":null,"receipt_file_size":null,"receipt_updated_at":null}]
I guess I'd rather do the code in ERB/ruby as I'm more immediately familiar with it. Though it almost feels a little pointless to have the json since @expenses is what I already use in my current table code. However, wouldn't render :file "expenses_table.html.erb" refresh the whole page? Or how would it know where to render just that table and replace what was previously there? It almost sounds easier to respond to format.js
and make an index.js.erb
because I know I could replace the html with my partial. But I haven't tried that as all the examples I've seen respond to format.json
. If it sounds like I'm just confused and don't know what's going on it's because I am. I just need some clarification. Thanks for your help!