问题
For my app, I have a datatable that uses ajax to retrieve records. The datatable allows the user to sort, search and I have added an extra custom field which allows the users to filter based on a category.
Now, when I use the HTML5 method provided by datatables to export to CSV/Excel, I only get the records that are displayed in the browser in the export. So, my only option is to do a server side export. I have a working export function, but I am struggling to find the proper way to also pass my filters to this export function.
I'm not sure what the best way is to get my parameters to my export method in my model. I thought about including jQuery to add the parameter to my link_to, but I'm not sure how to do this and if this is considered 'good practise'.
My code:
Table
<%= link_to "Download CSV", vendor_skus_path(format: "csv") %>
<%= select_tag "vendor-select", options_from_collection_for_select(@vendors, "id", "name"), include_blank: true, class:"vendor-select form-control" %>
<table id="vendor-skus-table" class="table table-striped table-bordered table-hover" data-source="<%= vendor_skus_path(format: :json) %>">
<thead>
<tr>
<th>Name</th>
<th>Vendor</th>
<th>Inventory Quantity</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
$('#vendor-select.vendor-select').on('change', function() {
$('#vendor-skus-table').DataTable().ajax.reload();
});
Coffeescript
$ ->
$('#vendor-skus-table').DataTable
processing: true
serverSide: true
retrieve: true
pagingType: 'full_numbers'
ajax: data: (d) ->
d.sku = $('#vendor-skus-table').data('source')
d.vendor_id = $('#vendor-select').val();
return
Datatable
class VendorSkuDatatable < AjaxDatatablesRails::Base
def_delegators :@view, :params, :link_to, :vendor_skus_path, :vendor_path
def sortable_columns
@sortable_columns ||= ['VendorSku.name', 'Vendor.name', 'VendorSku.inventory_quantity' ]
end
def searchable_columns
@searchable_columns ||= ['VendorSku.name', 'Vendor.name']
end
private
def data
records.map do |record|
[
link_to(record.name, record),
link_to(record.vendor.name, record.vendor),
record.inventory_quantity
]
end
end
def get_raw_records
# insert query here
if params[:vendor_id].present?
VendorSku.joins(:vendor).where(vendor_id: params[:vendor_id])
else
VendorSku.joins(:vendor).all
end
end
end
Controller action
def index
@vendor_skus = VendorSku.order(:name)
@vendor_sku = VendorSku.new
@vendors = Vendor.all
respond_to do |format|
format.html
format.csv { send_data @vendor_skus.to_csv }
format.json { render json: VendorSkuDatatable.new(view_context, { vendor_id: params[:vendor_id] }) }
format.xls # { send_data @vendor_skus.to_csv(col_sep: "\t") }
end
end
Model method
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |product|
csv << product.attributes.values_at(*column_names)
end
end
end
回答1:
If you aren't already committed to the idea of writing a custom serverside export, you can simply add a length menu. You mentioned that when you use the export button it exports only the visible rows, but have you tried allowing the user to change the number of visible rows before exporting? That seems like a much easier solution since it sounds like you wanted to use the export button in the first place.
$('#example').dataTable( {
"lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, "All"] ]
} );
The above code block will give 4 options for number of records to display; 10, 25, 50, and all records. You can add or remove whatever pagination options you want, but it seems to me that if you at least had the [-1]
and the ["All"]
part of each array you could allow users to show all records before exporting to get them all in the excel file. You could even change the excel export confirmation window to let the user know to do this before exporting.
来源:https://stackoverflow.com/questions/38067826/best-way-to-export-ajax-serverside-datatable