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!
Related
I´m trying to save a movie title to my database using Angular and Rails, but I´m getting some errors, and I think I know what the problem is, but I don´t know how to fix it.
The setup,
This is my search template. When a user clicks on the addMovie div the addMovieCtrl fires and tries to save the input.
%div{"ng-controller" => "searchCtrl", :id => "container_search"}
#addMovie{"ng-controller" => "addMovieCtrl"}
%div{"ng-click" => "addMovie()"}
%input{:type => "text", "ng-model" => "title"}
addMovie action.
This is the movieController.js,
angular.module('addMovieseat', ['ui.router', 'templates'])
.controller('addMovieCtrl', ['$scope', 'movies',
function($scope, movies){
$scope.movies = movies.movies;
$scope.addMovie = function(){
console.log ("Hello")
if(!$scope.title || $scope.title === '') { return; }
movies.create({
titles: $scope.title,
});
$scope.title = 'Star wars';
};
}
])
And this is the movieService.js
angular.module('addMovieseat')
.factory('movies', ['$http', function($http){
var o = {
movies: []
};
o.create = function(movie){
return $http.movie('/movies.json', movie).success(function(data){
o.movies.push(data);
});
};
return o;
}])
The movie.rb model in Rails
class Movie < ActiveRecord::Base
def as_json(options = {})
end
end
my app.js.coffee,
#myApp = angular.module('myApp',[]);
#flapperNews = angular.module('flapperNews',[]);
#app = angular.module('movieseat', ['addMovieseat','myApp', 'flapperNews', 'ui.router', 'Devise']);
# for compatibility with Rails CSRF protection
#app.config([
'$httpProvider', ($httpProvider)->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
])
#app.run(->
console.log 'angular app running'
)
When I click on the addMovie div I get this error,
TypeError: $http.movie is not a function
at Object.o.create
I've folled the Angular/Rails tutorial on thinkster.io and something I've noticed is that when I go to localhost:3000/posts.json I get a page with all the posts I've created (during the tutorial). But when I go the localhost:3000/movies.json I get a No route matches [GET] "/movies.json"
Of course its not.
Replace
$http.movie('/movies.json', movie)
With:
$http.post('/movies.json', movie)
Sidenote, haml lets you write nice html props like:
%div( ng-click="addMovie()" )
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.
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?
I have an ajax call to fetch information from Flickr API which returns JSON data. I want to display values from JSON data in my view. I do this by editing some innerHTML with jQuery. The problem I am having is that the data is undefined, so it looks like a scoping problem.
photo.js
jQuery(function() {
$('#<%=p[:id]%>').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '<%=p[:id]%>';
var fetch_secret = '<%=p[:secret]%>';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id, 'secret' : fetch_secret },
success: function(data){
console.log(data) //returns Object
console.log(data.title) //returns appropriate title
//edit innerHTML of basic_modal
$('.basic_modal').html(
"<div id='modal_image'><%= escape_javascript(image_tag p[:url]) %></div><div id='photo_title'><%=data.title %></div>"
);
//load modal
$('.basic_modal').modal({
overlayClose:true
});
} //end success: function(result)
});
When I print data.title to console, I get the appropriate title. However, when I try to edit HTML and render <%=data.title %>, I get an undefined variable/method error.
Any tip on how I can display the data in my modal in the view?
Here is my controller:
def fetch_info
#info = flickr.photos.getInfo(:photo_id => params[:id], :secret=> params[:secret])
respond_to do |format|
format.json { render :json => #info }
end
end
var result = jQuery.parseJSON(data);
You donot need to do this, Because datatype:JSON already parse the data
$('.basic_modal').html(
"<div id='modal_image'><%= escape_javascript(image_tag p[:url]) %>
</div><div id='photo_title'><%="+data.title+" %></div>"
);
this might help you
I'm trying to ajaxify my will_pagniate pagination in rails. I want to have the old page fade out and the new one fade in.
Here's the relevant part of my controller:
respond_to do |format|
format.html # new.html.erb
format.js {
render :update do |page|
page.replace 'page', :partial => 'cur_page'
end
}
format.xml { render :xml => #branch }
end
The aforementioned partial:
<div id="page">
<%= will_paginate %>
<div id="posts">
<%= render #posts %>
</div>
<%= will_paginate %>
</div>
And the relevant part of application.js:
document.observe("dom:loaded", function() {
// the element in which we will observe all clicks and capture
// ones originating from pagination links
var container = $(document.body)
if (container) {
var img = new Image
img.src = '/images/spinner.gif'
function createSpinner() {
return new Element('img', { src: img.src, 'class': 'spinner' })
}
container.observe('click', function(e) {
var el = e.element()
if (el.match('.pagination a')) {
el.up('.pagination').insert(createSpinner())
target = $('posts')
new Effect.fade(target, { duration: 0.3, afterFinish: function()
{
new Ajax.Request(el.href,
{
method: 'get',
onSuccess: function(){ new Effect.Appear(target, {duration:0.3})}
})
}})
e.stop()
}
})
}
})
The script seems to get killed on this line,
new Effect.fade(target, { duration: 0.3, afterFinish: function()
because I see the spinner.gif start, then no fading and the page is refreshed normally. I have got the ajax working before I tried to add Effect.Fade and Effect.Appear.
Is this the right way to go about this? Should I put the effects in the controller instead?
Here is what I did using jQuery and working well too :)
Put your will_paginate helper view call in a div
#tickets_pagination
= will_paginate #tickets
In application.js
$("#tickets_pagination .pagination a").live("click", function() {
$.get("/users/?"+this.href.split("?")[1], null, null, "script");
return false
});
The javascript above will convert the pagination links in #tickets_pagination to ajax links
In your controller as usual
def index
#tickets = Ticket.all.paginate({:page => params[:page], :per_page => 10 })
respond_to do |format|
format.js
format.html
end
end
Now finally in index.js.erb
$("#tickets_list_table").fadeOut('slow');
$("#tickets_list_table").html("<%= escape_javascript(render :partial =>'tickets/tickets_table', :locals => {:tickets => #tickets}) %>");
$("#tickets_list_table").fadeIn('slow');
Here tickets/ticket_table has a table that lists all tickets. The partial is rendered in a div #ticket_list_table
Hope this will work for you as well.
I tried putting more of the work into the javascript helpers:
respond_to do |format|
format.html # new.html.erb
format.js {
render :update do |page|
page.visual_effect :fade, 'posts', :afterFinsh => "function(){" +
page.replace 'page', :partial => 'cur_page' +
page.visual_effect(:appear, 'branches') + "}"
end
}
format.xml { render :xml => #branch }
end
Then removed this part of the javascript:
new Effect.fade(target, { duration: 0.3, afterFinish: function()
I get the effect I want, but all out of order. The request completes and the html is replaced, then the div fades out and then reappears!
Not very familiar with RoR, does it generate its own client-side JS that may possibly be battling your code?
If not, I would say the problem is somewhere in your own client-side code. For testing, get rid of the HREF attribute from the anchor tag and place the URL as a string literal in the Ajax request. If nothing happens, there is a problem with the Ajax request itself. If the page loads as expected, then the event in the original scenario is not being completely stopped.
Also, clean up your JS a bit just to be sure, line-ending semi-colons where needed.
You seem to mix up things a bit.
Either you write $('posts').fade or new Effect.fade('posts').
Secondly, i can't seem to find the afterFinish option in the documentation.
So i would suggest something along the following lines:
container.observe('click', function(e) {
var el = e.element()
if (el.match('.pagination a')) {
el.up('.pagination').insert(createSpinner())
target = $('posts')
new Effect.fade('posts', { duration: 0.3});
setTimeout("new Ajax.Request(el.href, { method: 'get',
onSuccess: function(){
new Effect.Appear('posts', {duration:0.3})
} })", 1000);
e.stop();
}
})
Hope this helps.