How can I use jTable in Ruby on Rails? - ruby-on-rails

I would like to use jTable jQuery plugin in Ruby on Rails 4. What is the best way to do it? Turbolink compatibility is important for me.

I installed jTable js and css into the vendor directory (jQuery UI is needed, I used jquery-ui-rails gem)
I created a controller (called tables_controller), and used a little bit tricky way to make it easy to use and rails friendly.
See the following example. I used a special naming convention to make the process easier: the name of the fields contains the name of the table and the name of the column separated with ‘__’ - for example visitors__id. You will see how it helps to handle automatic ordering.
app/controllers/tables_controller.erb:
class TablesController < ApplicationController
def demo
respond_to do |format|
format.json {
page_size = params[:jtPageSize].to_i
start_index = params[:jtStartIndex].to_i
start_page = start_index / page_size + 1
sort_by = params[:jtSorting].gsub('__', '.')
filter = params[:filter]
if filter
#visitors_count = Visitor.joins(:city).
where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").size()
#visitors = Visitor.joins(:city ).
where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").order(sort_by).
paginate(:page => start_page, :per_page => page_size)
else
#visitors_count = Visitor.all.size()
#visitors = Visitor.joins(:city).order(sort_by).
paginate(:page => start_page, :per_page => page_size)
end
}
format.html {}
format.js {}
end
end
def demo_delete
#visitor = Visitor.find(params[:visitors__id])
if #visitor
if #visitor.destroy
render js: '{"Result":"OK"}'
end
end
end
end
app/views/tables/demo.json.jbuilder:
json.Result "OK"
json.TotalRecordCount #visitors_count
json.Records do
json.array!(#visitors) do |visitor|
json.visitors__id visitor.id
json.visitors__name visitor.name
json.visitors__age visitor.age
json.cities__name visitor.city.name
end
end
app/views/tables/demo.html.erb:
<div class="jtable-filter">
<form class="jtable-filter">
<input type="text" name="filter" id="filter"/>
<button type="submit" data-jtable-filter="demo">Filter</button>
</form>
</div>
<div id="demo" data-jtable-config="/demo">
</div>
app/views/tables/demo.js.erb:
var jtable_config = {
title: '',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'visitors__name ASC', //Set default sorting
defaultDateFormat: 'yy-mm-dd',
gotoPageArea: 'combobox',
actions: {
listAction: '/demo',
deleteAction: '/demo/delete'
},
fields: {
visitors__id: {
key: true,
list: false
},
visitors__name: {
title: 'Name',
width: '30%'
},
visitors__age: {
title: 'Age',
width: '20%'
},
cities__name: {
title: 'City',
width: '20%'
}
}
};
application.js:
(function ($) {
jQuery.fn.jtable_ou = function () {
return this.each(function () {
var $this = $(this);
var config_url=$this.attr("data-jtable-config");
$.getScript( config_url, function( data, textStatus, jqxhr ) {
$this.jtable(jtable_config);
$this.jtable('load');
});
});
};
})(jQuery);
$(document).on("page:change", function() {
$('[data-jtable-config]').jtable_ou();
$('button[data-jtable-filter]').click(function (e) {
e.preventDefault();
var target=this.getAttribute("data-jtable-filter");
$('#'+target).jtable('load', {
filter: $('#filter').val()
});
});
});
Gemfile:
match '/demo', to: 'tables#demo', via: [:get, :post]
match '/demo/delete', to: 'tables#demo_delete', via: [:post]
It is turbolink friendly and uses unobtrusive JavaScript.
You can find detailed description in this post.

Related

Wrong number of arguments -trying to implement an autocomplete with jQueryui

I am trying to implement an auto-complete form following this example How to set up jquery ui autocomplete in rails
When I go to http://localhost:3000/initiatives/10.json?term=Ion I get a "Wrong number of arguments 1 for 0".
In my initiatives#show I have the following code:
if params[:term]
Error points to this line - #people = User.all(:all, :conditions => ['name LIKE ?', "#{params[:term]}%"])
else
#people = User.all
end
respond_to do |format|
format.html
format.json { render :json => #people.to_json }
end
I am using PostgreSQL and I'm thinking the query is not made for this database.
This is the script for auto complete:
<script type="text/javascript">
$(function() {
$('#delegatee').autocomplete({
minLength: 2,
source: '<%= json_path %>',
focus: function(event, ui) {
console.log("xxxxxx");
console.log(ui);
$('#delegatee').val(ui.item.name);
return false;
},
select: function(event, ui) {
$('#delegatee').val(ui.item.name);
$('#delegatee_id').val(ui.item.id);
return false;
}
})
.data("uiAutocomplete")._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.name + "</a>" )
.appendTo( ul );
};
});
</script>
"<%= json_path %> " leads to /initiatives/:id.json which renders the data.. correctly I think.
When I try the form out it gives me a 500 Internal Server error in the console, which I believe is the one I described above and it points me to this line in the jquery script: xhr.send( ( options.hasContent && options.data ) || null );
I'm using Rails 4.2.0.beta4 and Ruby 2.0.0p195.
In Rails > 4.0, ActiveRecord's .all don't take multiple parameters as you are passing, and thus the Wrong number of arguments 1 for 0 error.
The query you are trying to setup would be just:
#people = User.where('name LIKE ?', "#{params[:term]}%")
Hope it helps!

acts_as_taggable_on and select2 returning weird results in Active Admin

So I have been playing around with acts_as_taggable_on in active admin, and for the most part everything is working as expected.
However, whenever I search for tags, and add an existing tag to a model, it seems to save it as the ID, rather than as the name. Creation of new tags returns the name fine, and when I go to edit the object again the tags remain tagged by the name. But when I try and add another tag, one that already exists in the database, it returns the name in the form, and seems to save OK, but when I go back to edit the onject again the tag shows up as an ID, rather than the name.
In admin/gift.rb:
controller do
def autocomplete_gift_tags
#tags = ActsAsTaggableOn::Tag
.where("name LIKE ?", "#{params[:q]}%")
.order(:name)
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
end
end
In tag-autocomlete.js:
$(document).ready(function() {
$('.tagselect').each(function() {
var placeholder = $(this).data('placeholder');
var url = $(this).data('url');
var saved = $(this).data('saved');
$(this).select2({
tags: true,
placeholder: placeholder,
minimumInputLength: 1,
initSelection: function(element, callback) {
saved && callback(saved);
},
ajax: {
url: url,
dataType: 'json',
data: function(term) {
return {
q: term
};
},
results: function(data) {
return {
results: data
};
}
},
createSearchChoice: function(term, data) {
if ($(data).filter(function() {
return this.name.localeCompare(term) === 0;
}).length === 0) {
return {
id: term,
name: term
};
}
},
formatResult: function(item, page) {
return item.name;
},
formatSelection: function(item, page) {
return item.name;
}
});
});
});
And in my _gift_form.html.erb:
<%= f.input :tag_list, label: "Tags", input_html: { data: { placeholder: "Enter tags", saved: f.object.tags.map{|t| {id: t.name, name: t.name}}.to_json, url: autocomplete_gift_tags_path }, class: 'tagselect' } %>
Can't work out why the new ones are working, but the existing tags are not.
change this:
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
to this:
respond_to do |format|
format.json { render :json => #tags.collect{|t| {:id => t.name, :name => t.name }}}
end

use select2 Auto Tokenization in rails

I use auto tokenization in my rails project.
I want read the tags from database and show to user. I use below code in controller and html file, but don't work for auto tokenization.(this code is ok for other select2, like ajax.)
problems_controller.rb
respond_to :html, :json
def index
#problem = Problem.order('status asc').all
respond_with #problem
end
index.html.erb
<script type="text/javascript">
$(document).ready(function(){
$("#e20").select2({
tags: {
url: "/problems.json",
dataType: "json",
results: function(data, page) {
return {
results: $.map( data, function(problem, i) {
return { id: problem.id, text: problem.status }
} )
}
}
},
tokenSeparators: [",", " "]
});
});
</script>
Where is the problem of my code? Why this code cannot read database information?

Rails Select2 initselection load data from database

I have data coming from sunspot to select2(shown list_styles method of controller). I can search and save multiple categories with select2 on new provider form without any problems however when I try to load the data from database on edit provider form it doesn't show up. Tried the initselection method and checked the documentation/stackoverflow for initselection method that fits to my application but could not sort it out. Created a new controller method called list_categories without success. Can anyone comment me on the correct way to do it?
Thank you.
Jquery
$('#provider_category').select2({
minimumInputLength: 3,
multiple: true,
ajax: {
url: "/categories/list_styles",
dataType: 'json',
quietMillis: 100,
data: function (term, page) {
return {
q: term,
page_limit: 10,
page: page,
};
},
results: function (data) {
var hashtable={};
var results = \[\];
$.each(data, function(index, item){
if (hashtable\[item.parent\]===undefined) {
hashtable\[item.parent\]={text:item.parent, children:\[\]};
results.push(hashtable\[item.parent\]);
}
hashtable\[item.parent\].children.push({id:item._id,text:item.title});
});
return {
results: results
};
},
initSelection: function(element, callback) {
return $.ajax({
type: "get",
url: "/categories/list_categories",
dataType: 'json',
data: function (term, page) {
return {
q: term,
page_limit: 10,
page: page,
};
},
success: function(data){
}
}).done(function(data) {
//console.log(data);
return callback(data);
});
}
}
});
Controller
class CategoriesController < ApplicationController
respond_to :html, :json
def list_styles
search = Category.search do
fulltext params[:q]
end
search = Category.search { keywords params[:q]; paginate :page => params[:page], :per_page => params[:page_limit] }
#categories = search.results
respond_with #categories
end
def list_categories
search = Provider.find "5299b5dcdd506322c4000091"
#category = search.category
x = Category.find #category
search = Category.search { keywords x.title; paginate :page => params[:page], :per_page => params[:page_limit] }
#categories = search.results
respond_with #categories
end
end
Thats the way it is baby!
jquery
},
initSelection : function (element, callback) {
var data1 = [];
jQuery(element.val().split(",")).each(function () {
$.ajax({
type: "get",
url: "/providers/list_categories",
async: false,
dataType: 'json',
data: { id: $("#provider_id").val()},
success: function(category){
$.each(category, function(i, obj) {
data1.push({id: this._id, text: this.title});
});
}
});
});
callback(data1);
}
});
contoller
def list_categories
#provider = Provider.find params[:id]
arr = #provider.category.split(",")
#category = Category.where(:_id.in => arr)
respond_to do |format|
format.json { render :json => #category}
end
end

How to add ajax to jquery-ui slider using ruby on rails 3.2

So I'm following this outdated tutorial on using the jquery-ui slider with rails 3 beta since it's the only one I've found.
My view which has the script
<p>
<p>Showing all stocks between <span id="x_low_selected"><%= #price_range.first %></span> and <span id="x_high_selected"><%= #price_range.last %></span></p>
</p>
<div id="x_slider"></div>
<ul id="x_stock_list">
<%= render 'map' %>
</ul>
<script type="text/javascript">
$(function() {
$("#x_slider").slider( {
range: true,
step: 1,
max: <%= #price_range.last %>,
min: <%= #price_range.first %>,
values: [<%= #price_range.first %>, <%= #price_range.last %> ],
stop: function(event, ui) {
var prices = $('#x_slider').slider('option', 'values');
$('#x_low_selected').html(prices[0]);
$('#x_high_selected').html(prices[1]);
$.ajax({
url: 'http://localhost:3000/users',
type: "GET",
data: { low: prices[0], high: prices[1] },
dataType: 'json'
});
}
});
});
</script>
model method for prices
def self.low_high_prices
[User.minimum(:start), User.maximum(:end)]
end
and the index method in the controller which the ajax should call
def index
#users = User.all
unless params[:low] && params[:high]
#users = User.all
#json = User.all.to_gmaps4rails do |user, marker|
marker.infowindow "<a href=/users/#{user.id}> #{user.name} </a>"
marker.title user.name
end
else
#json = User.where("start >= params[:low] AND end <= params[:high]).to_gmaps4rails do |user, marker|
marker.infowindow "<a href=/users/#{user.id}> #{user.name} </a>"
marker.title user.name
end
end
#price_range = User.low_high_prices
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
Does anyone know why the ajax call isn't being sent to the controller when the slider stops sliding? Not sure if I would be able to use :remote => true because the slider is generated inside the div.
Thanks
Also I am currently using rails 3.2 with ruby 1.9.7
I would guess that your call is going through to the controller, and the controller is returning JSON data.
The problem is that your $.ajax call is doing nothing with the JSON data received.
You need to add a callback function to handle the JSON data passed back in some way in the ajax call:
$.ajax({
url: 'http://localhost:3000/users',
type: "GET",
data: { low: prices[0], high: prices[1] },
dataType: 'json',
success: function (data) {
alert("Success: " + data);
//do something with the data here.
}
});
Also, looking at the controller code, it will only pass back the contents of #users in the JSON data, not the contents of #json or anything else - not sure if that was your intention or not.

Resources