I am using the ajax-datatables-rails. Below is the JS for my datatable. I want to convert the javascript into equivalent Opal.rb.
jQuery(document).ready(function() {
var table = $('#organizations-datatable');
var token = $('meta[name=csrf-token]').attr('content');
table.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "/organizations/datatable.json",
"type": 'POST',
"beforeSend": function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', token)
}
},
"pagingType": "full_numbers",
"destroy": true,
"columns": [
{"data": "name"},
{"data": "desc"},
{"data": "industry"},
{"data": "tags"}
],
"iDisplayLength": 25
});
});
It includes adding the CSRF token to the ajax request for data.
I would like all of our javascript to be written as opal for readability, etc. Please don't debate that choice, I only care to understand how to get this working as Opalrb via opal/rails-ujs/opal-jquery
The below Opal does not achieve the same as the above JS. Can anyone help me understand why?
Element.expose :DataTable
Document.ready? do
token = Element['meta[name=csrf-token]'].attr('content');
settings = {
"processing": true,
"serverSide": true,
"ajax": {
"url": "/organizations/datatable.json",
"type": 'POST',
"beforeSend": lambda do
xhr = `new window.XMLHttpRequest()`
xhr.setRequestHeader('X-CSRF-Token', token)
end
},
"pagingType": "full_numbers",
"destroy": true,
"columns": [
{"data": "name"},
{"data": "desc"},
{"data": "industry"},
{"data": "tags"}
]
}
Element['#organizations-datatable'].DataTable(settings.to_n)
end
What am I missing here? Why isn't this Opal any good?
Edit: This is what my route for this looks like, this ensures POST works for this:
Rails.application.routes.draw do
concern :with_datatable do
post 'datatable', on: :collection
end
resources :organizations, concerns: [:with_datatable]
end
This is my related controller and datatable code using the gem:
class OrganizationsController < ApplicationController
def index
@title = "Organizations"
@page_description = "Organization data warehouse"
@page_icon = "institution"
@organization = Organization.new
@load = {data_table: true}
@menu = Menu.new
respond_to do |format|
format.html
format.json { render json: OrganizationDatatable.new(params) }
end
end
def datatable
logger.ap "datatable params: #{params}"
respond_to do |format|
format.json { render json: OrganizationDatatable.new(params) }
end
end
def get_raw_records
Organization.all
end
def create
end
def edit
end
def destroy
end
def show
end
def update
end
def new
end
end
Here is the datatable
class OrganizationDatatable < AjaxDatatablesRails::ActiveRecord
extend Forwardable
include ActionView::Helpers::TextHelper
def_delegator :@view, :link_to
def view_columns
# Declare strings in this format: ModelName.column_name
# or in aliased_join_table.column_name format
@view_columns ||= {
# id: { source: "Organization.id" },
name: { source: "Organization.name",cond: :like, searchable: true, orderable: true },
desc: { source: "Organization.description",cond: :like, searchable: true, orderable: true },
industry: { source: "Organization.industry",cond: :like, searchable: true, orderable: true },
tags: { source: "Organization.tag_list", searchable: false, orderable: false }
}
end
def data
records.map do |record|
{
id: record.id,
name: record.name,
desc: truncate(record.description,length: 240, separator: ' '),
industry: record.industry,
tags: record.decorate.buttonize_tags,
DT_RowId: record.id
}
end
end
def get_raw_records
Organization.all
end
end
I will start with pointing few mistakes in your code ,
The code in beforeSend is problematic please refer to supplying-an-xhr-method, change it to the below code,
"beforeSend": lambda do |xhr|`xhr.setRequestHeader('X-CSRF-Token', token)`enclose xhr statements in ( ` ) backticks like above statement
columns should have two dimensional array rather than array of objects,
"columns": [ ["data": "name"], ["data": "desc"], ["data": "industry"], ["data": "tags"] ]Rest of the code looks fine.
Below is the tested code,
Make sure you have
data.jsonfile in public folder of rails app, and contents as follows,add
opaltoGemfile,application.js.rbcontents,add
datatables.min.jsfile toapp/assets/javascriptsfolderhtml,
NOTE :- If you want it to work with POST you have to adjust your
config/routes.rb,Add the following entry in routes.rb for your json file,
For me it was,
For you it will be,
Full code here https://gitlab.com/shoyebsheikh/opal-datatables
Ajax datatables rails gem solution:
You can add the following line to your routes assuming thats the data source,
Your controller should be like,
And your datatable as follows,
In your
organizations.js.rbgoes the opal code,And in html,
organizations_index_pathcan beorganizations_pathor in singular likeorganization_index_pathororganization_pathdepending on your controller namePlease refer to https://gitlab.com/shoyebsheikh/ajax-datatables-rails-with-opal for more info.
Note: