Rails 3 Datatables JSON - aData undefined - ruby-on-rails

I know that this question has been asked many times before, but due to my inexperience I am unable to correct the problem using those responses. I had it working in a previous Rails project and cannot see what has changed. I started a new project using PostgreSQL rather than MySQL and I am now using Rails 3.2.8 (was 3.2.1).
Firebug showing:
TypeError: aData is undefined at:
var aData = _fnGetObjectDataFn( oSettings.sAjaxDataProp )( json );
for ( var i=0, iLen=aData.length ; i<iLen ; i++ )
I gather that this is probably caused by Datatables not getting the correct JSON. A snippet shows below, which validates in JSONLint.
[{"code":"STATE 30","created_at":"2012-12-10T06:01:34Z","id":1,"name":"ALBANY HIGHWAY","rank":null,"state":"WA","updated_at":"2012-12-10T06:01:34Z"},{"code":"ANNE BEADELL HIGHWAY","created_at":"2012-12-10T06:01:34Z","id":2,"name":"ANNE BEADELL HIGHWAY","rank":null,"state":"SA","updated_at":"2012-12-10T06:01:34Z"},...
I see that it doesn't include iTotalRecords, iTotalDisplayRecords and aaData. Is this the problem? I presume the JSON options are set by the def as_json, buy I don't explicity reference that in my render ??. The http get (as seen in Firebug) includes sEcho but not iTotalRecords.
My code is based on RailsCasts #340:
Controller: ( see the list action).
class HighwaysController < ApplicationController
respond_to :html, :json
def index
#highways = Highway.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #highways }
end
end
def list
#highways = Highway.all
logger.debug "Highway Count: #{#highways.size}"
respond_to do |format|
format.html # index.html.erb
format.json { render json: HighwaysDatatable.new(view_context)}
end
end
Associated Ruby code:
class HighwaysDatatable
delegate :params, :h,:link_to,:number_to_currency,to: :#view
def initialize(view)
#view = view
end
def as_json(options = {})
{
sEcho: params[:sEcho].to_i,
iTotalRecords: Highway.count,
iTotalDisplayRecords: highways.total_entries,
aaData: data
}
end
private
def data
highways.map do |highway|
[
h(highway.id),
h(highway.name),
h(highway.state),
h(highway.code),
h(highway.rank),
h(highway.created_at),
h(highway.updated_at)
]
end
end
def highways
#highways ||= fetch_highways
end
def fetch_highways
... (as per RailsCasts code - code wrapped and did not show properly)
end
highways
end
def page
params[:iDisplayStart].to_i/per_page + 1
end
def per_page
params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
end
def sort_column
columns = %w[name state code rank]
columns[params[:iSortCol_0].to_i]
end
def sort_direction
params[:sSortDir_0] == "desc" ? "desc" : "asc"
end
end
and the list view:
<% #page_title = "Highways List" %>
<h2>Highways</h2>
<%= javascript_tag do %>
window.highwaysURL = '<%= j highways_url %>';
<% end %>
<div id="EditLink">
<%= link_to "Edit Highway", :controller => :highways, :action => :edit, :id => 1 %>
</div>
<div>
</br>
<%= link_to 'Neighbours', '/neighbours/' %>
<%= link_to 'Localities', '/localities/' %>
</br>
</div>
<div id="tools">
</div>
<table id="highways" class="display" data-source="<%= highways_url(format: "json") %>">
<thead>
<tr>
<th>Id</th>
<th>Highway</th>
<th>State</th>
<th>Code</th>
<th>Rank</th>
<th>Created At</th>
<th>Updated At</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id=editarea class='result' ></div>
My gemfile (with comments removed):
source 'https://rubygems.org'
gem 'rails', '3.2.8'
gem 'pg'
group :assets do
gem 'sass-rails', '~> 3.2.3'
gem 'coffee-rails', '~> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end
gem 'libv8', '~> 3.11.8'
gem 'therubyracer', require: 'v8'
gem 'jquery-rails'
gem 'will_paginate'
gem 'debugger'
and application.js for Asset Pipeline:
//= require jquery
//= require jquery-ui
//= require jquery.dataTables
//= require TableTools
//= require ZeroClipboard
//= require datatable_highways
//= require datatable_localities
//= require datatable_neighbours
//= require_tree .
It's probably something simple, but it has been holding me up for some time. Thanks in anticipation.
UPDATE
The DataTables debugger bookmarklet indicates that the 'list' view is rendering the following which does not include the json parameters expected by DataTables.
http://localhost:3000/highways.json
and I believe it should be:
http://localhost:3000/highways/list.json.
I am not sure if this is a controller or a view problem.
UPDATE
I have made various changes but still have the same problem. BUT I see two things in the log which are significant:
Entering localhost:3000/highways/list shows that 2 views are rendered.
Processing by HighwaysController#list as HTML [1m[36mHighway Load (4.8ms)[0m [1mSELECT "highways".* FROM "highways" ORDER BY name
Highway Count: 229
Rendered highways/list.html.erb within layouts/highways (32.6ms)
then
Processing by HighwaysController#index as JSON
Parameters: {"sEcho"=>"1", "iColumns"=>"5", "sColumns"=>"", "iDisplayStart"=>"0",...
The first is HTML (via action 'list') the second as JSON (via action 'index').
So there are two problems:
The first render has an associated data request which causes an
'already initialised' warning from DataTables, and
My routes.rb explicit match statement is catching the HTML to render
the view, but the JSON response (from the AJAX call for the data rows) falls through
and is handled by resources :highways and it then uses the 'index'
action in the controller
routes.rb
match 'highways/list'=> 'highways#list'
...
resources :highways
How do I stop the data request when I just want the view (column headings etc) rendered?
What route do I need to send the JSON response to the 'list' action in the controller?

Resolved. Went back to a minimal set up, 1 table using Ryan Bates #340 code - so using index action/view to get around the 2 render issue above. Still not working. Removed gem to rweng github and loaded DataTables files to ./vendor/assets. Now works. The index or list action can probably be fixed with an explicit route, but I could not get past 'missing template' when I tried to coerce it through the list action.

Related

Ruby on Rails: export xlsx export all html page instead the requested data

I'm using rails 4.2, and using gems axlsx and axlsx_rails
I'm going to move to rails 5 soon but for now I use this version.
What I want: Export xlsx file from a query using axls_rails gem
What I get instead: it export the whole html file as data instead, see picture:
I followed 3 different guides as the git documentation exactly and already debugged it several times and didn't find the problem. Hope someone here can help me understand what causing it.
Gemfile:
gem 'rails', '4.2.11'
# import/export xlsx gems
gem 'write_xlsx'
gem 'rubyzip', '>= 1.2.1'
gem 'axlsx', git: 'https://github.com/randym/axlsx.git', ref: 'c8ac844'
gem 'axlsx_rails'
html file:
= link_to "<i class='icon icon-file-down'></i> Export</a></li>".html_safe, server_report_system_reports_path(format: :xlsx)
controller file:
def server_report
organization_id = params[:organization_id]
#accounts = Admin::Account.where("organization_id = ?", organization_id) unless organization_id.blank?
#accounts_paginated = #accounts.paginate(per_page: 10, page: params[:page] || 1 )
respond_to do |format|
format.html
format.xlsx {
response.headers['Content-Disposition'] = 'attachment; filename="server_report.xlsx"'
}
end
end
xlsx.axlsx file:
wb = xlsx_package.workbook
wb.add_worksheet(name: "Accounts") do |sheet|
sheet.add_row ["Account id", "Member id", "Member name", "Member email"]
#accounts_paginated.each do |account|
account.members.each do |member|
sheet.add_row [account.id, member.id, member.name, member.email]
end
end
end
EDIT:
I tried to call a different def called export and try to see if there's a problem with respond_to and use another query but it also did the same
I also tried to write in format.xlsx this line but still nothing changed:
EDIT 2:
I tried to render in respond_to the file instead in axlsx.xlsx file in format.xlsx but I got the same result
response.headers['Content-Disposition'] = 'attachment; filename="server_report.xlsx"'
I found the problem. I added layout: false when I render the xlsx file in the controller and it worked

render md file as partial in rails

I am using the markdown rails gem
https://github.com/joliss/markdown-rails
I have an md partial _privacy.html.md
#Privacy Policy
Privacy policy ....
Then when I render this partial file from an erb file
<%= render :partial => "privacy" %>
I get
<h1>Privacy Policy</h1> <p> Privacy policy ....
It actually renders the formatted html as a text and not as as an html interpreted code.
render md file as partial in rails
Try this one
require 'rubygems'
require 'nokogiri'
puts Nokogiri::HTML(my_html).text
Example:
require 'open-uri'
require 'rubygems'
require 'nokogiri'
uri = 'https://stackoverflow.com/questions/45279017/render-md-file-as-partial-in-rails'
doc = Nokogiri::HTML(open(uri))
doc.css('script, link').each { |node| node.remove }
puts doc.css('body').text.squeeze(" \n")
or simple way:
html = '<div class="asd">hello world</div><p><span>Happy</span><br> to help</p>'
puts ActionView::Base.full_sanitizer.sanitize(html)
and
html.gsub(/<\/?[^>]*>/, ' ').gsub(/\n\n+/, '\n').gsub(/^\n|\n$/, ' ').squish
Hope this will help you !

google_visualr chart rendering error

i am trying Google-Visualr gem and got the above error.
As described here.
i installed the gem and in MyModel (we can use controller/model) i copied the demo code for line-chart from here.
i have a UserMailer,where i wanted to render html page along with my chart and using pdfkit i am converting rendered html to pdf.
class UserMailer < ActionMailer::Base
def my_report
#chart =MyModel.line_chart
html_data = render :template => "user_mailer/my_report"
kit = PDFKit.new(html_data,:page_size => 'Letter')
pdf = kit.to_pdf
end
in my my_report view i included
<script src='https://www.google.com/jsapi'></script>
in <head>
included this in <body> part
<div id='chart'></div>
<%= render_chart(#chart, 'chart') %>
But it is leading to me to undefined method "render_chart" error.
Any suggestion that how can i render chart with my html data?
where i am going wrong?
i am using rails 4
and 'google_visualr', '>= 2.1'

gmap4rails in ActiveAdmin: maps does not appear

In try to use gmaps4rails in my ActiveAdmin / Rails app. To do so, I have added the following in my Gemfile:
gem 'gmaps4rails'
and ran a "bundle". I updated the 'show' method in app/admin/device.rb file with:
show do
attributes_table do
row :name
end
# Get device location
#markers = Location.all.to_gmaps4rails
div do
render "map"
end
end
In the app/views/admin/devices/_map.html.erb I have the following code:
<%= stylesheet_link_tag 'gmaps4rails' %>
<%= gmaps4rails(#markers) %>
<%= yield :scripts %>
In app/assets/javascripts/application.js:
//= require gmaps4rails/gmaps4rails.googlemaps
//= require gmaps4rails/gmaps4rails.base
//= require jquery
//= require jquery_ujs
//= require_tree .
And in my app/models/location.rb:
class Location < ActiveRecord::Base
acts_as_gmappable
attr_accessible :latitude, :longitude
def gmaps4rails_address
"#{self.latitude}, #{self.longitude}"
end
def location
[:latitude, :longitude]
end
end
When I go on the show page of a device, the map does not shows up (all blank). Is there any configuration I missed ?
UPDATE
I have checked with chrome developer tools and noticed the following error:
Uncaught SyntaxError: Unexpected token ;
that make reference to the line:
Gmaps.map.markers = ;
Fix with the following:
div do
markers = Location.all.to_gmaps4rails
render "map", { :markers => markers }
end
and :
<%= stylesheet_link_tag 'gmaps4rails' %>
<%= gmaps({
"map_options" => { "zoom" => 2, "auto_adjust" => false},
"markers" => { "data" => markers }
})
%>
<%= yield :scripts %>
You have to load the Javascript files in the /config/initializers/active_admin.rb; search for the section:
# To load a javascript file:
# config.register_javascript 'my_javascript.js'
Also, I think you should add the CSS files (if is not appearing) into the same file.
Remember that ActiveAdmin manages its own Javascript file, named active_admin.js; you can try loading the Javascript files in this JS; some time ago I had a similar problem and I only was able to solve it adding the files in the initializer.

How to generate code_128 barcode for string with Barby

I'm currently using Barby gem with wrapper gem has_barcode to generate a bar code for a string I have : j5xvvcz.
Gemfile gems (mostly for those who are new to this solution)
#for barcode generation
gem "barby", "~> 0.5.0"
gem "has_barcode", "~> 0.2.0"
gem "rqrcode", "~> 0.4.2" #for qr code support
Code i have in my model
include HasBarcode
has_barcode :barcode,
:outputter => :svg,
:type => :code_93,
:value => Proc.new { |p| "#{p.number}" }
Where i render it to screen:
If I try to generate a qr_code or a code_93, it all works, but nor code_128 or code_39 work, getting a data not valid message.
My worries is that code_93 won't get recognized in some devices since it seems it is not so widely adopted (from what i read here 128 would be the best solution for this)
This seems to be something i might be doing wrong, since the code is valid for code_128 aparently as i tested it here.
Anyone knows what might be wrong with my approach?
Apparently mode 'A' for code_128 doesn't suit for smallcaps with Barby.
So i had to had mode B working.
Current published gem version of has_barcode forces mode 'A', so I added a little "home-patch", while adding a suggestion to github.
Here is my final has_barcode.rb file :
require "rubygems"
require "i18n"
require "active_support"
require "active_support/hash_with_indifferent_access.rb"
require "active_support/inflector.rb"
require "barby"
require "has_barcode/configuration"
module HasBarcode
def self.included(base)
base.send(:extend, ClassMethods)
end
module ClassMethods
def has_barcode(*args)
options = args.extract_options!
##barcode_configurations ||= {}
##barcode_configurations[args.first] = HasBarcode::Configuration.new(options)
define_method args.first do
if options[:type] == :code_128
##barcode_configurations[args.first].barcode_class.new(options[:value].call(self), options[:code128])
else
##barcode_configurations[args.first].barcode_class.new(options[:value].call(self))
end
end
define_method "#{args.first}_data" do |opts|
if opts
send(args.first).send("to_#{options[:outputter]}", opts)
else
send(args.first).send("to_#{options[:outputter]}")
end
end
end
def barcode_configurations
##barcode_configurations
end
end
end
My model :
has_barcode :barcode,
outputter: :svg,
type: :code_128,
code128: 'B',
value: Proc.new { |p| "#{p.number}" }
and my view :
<%= my_model.barcode_data(xdim:2, height:60).html_safe %>
Do notice that at current date (2012-12-05) current gem isn't updated with latest changes that allow to pass outputter arguments like xdim and height.
This answer is based on latest code updates (issue related) and my own suggestion, and can be found here
While this solution isn't embedded into the has_barcode gem, i will be using Barby directly:
In my model added :
def get_barcode(number)
require 'barby'
require 'barby/barcode/qr_code'
require 'barby/outputter/svg_outputter'
barcode = Barby::Code128B.new("#{number}")
barcode.to_svg(xdim:2, height:60)
end
in the view :
<%= my_model.get_barcode(my_model.number).html_safe %>

Resources