I want my Index to change according to Price descending and Price ascending just like Amazon.
Right now, I send an ajax request to the site, with the new value of the select requesting the data. The site gets the data from database and sorts it.
How can my javascript redraw the cards in my index page with the sorted book response?
BookController.rb
def index
if params.dig("book", "title").nil? && params.dig("users", "university").nil?
#books = Book.where({title: params.dig("book", "title")})
.joins(:user).where(users: {university: params.dig("users", "university")})
elsif !params.dig("book", "title").nil? && params.dig("users", "university").nil?
#books = Book.where({title: params.dig("book", "title")})
elsif params.dig("book", "title").nil? && !params.dig("users", "university").nil?
#books = Book.joins(:user).where(users: {university: params.dig("users", "university")})
else
#books = Book.all
end
case params[:sort]
when "Price Descending"
#books.order(price_cents: "DESC")
when "Price Ascending"
#books.order(price_cents: "ASC")
else
#books.sort_by(&:created_at)
end
end
Book Index.html.erb
<select id="priceSelect">
<option value="Best Results" selected="selected">Best Results</option>
<option value="Price Descending">Price Descending</option>
<option value="Price Ascending">Price Ascending</option>
</select>
.
.
.
<% #books.each do |book| %>
<div class="col-xs-12 selectable-card">
<%= link_to book_path(book.id) do %>
...
<% end %>
</div>
<% end %>
<script>
$('#priceSelect').change(function(){
$.ajax({
url: "books",
type: "GET",
data: {sort: $('#priceSelect :selected').val()},
success:function(result){
console.log(result);
},
})
});
</script>
And lastly my routes.rb
resources :books do
resources :users
end
This answer may have syntax errors or other issues as I have written it here, without testing. It's just a guide on how to do it. Take these ideas and correct any possible problem.
In your controller you could return a json object:
respond_to do |format|
format.html
format.json { render json: #books }
end
In your html, add a div to mark to area to replace:
<div class ="books-info">
<% #books.each do |book| %>
<div class="col-xs-12 selectable-card">
<%= link_to book_path(book.id) do %>
...
<% end %>
</div>
<% end %>
</div>
In your javascript you should process the json response and build the html to replace the original list:
<script>
$('#priceSelect').change(function(){
$.ajax({
url: "books",
type: "GET",
data: {sort: $('#priceSelect :selected').val()},
success:function(ret){
// new code;
var books = JSON.parse(ret); // Not sure if necessary or you can use 'ret'
var length = books.length;
var html = "";
for (var i = 0; i < length; i++) {
html += "<div class='col-xs-12 selectable-card'>";
html += "<a href='" + books[i].id + "'>" + books[i].name + "</a>";
html += "</div>";
}
$('.books-info').innerHTML = html
},
})
});
</script>
Related
I'm working on a RSS reader and I have to check every x time if a new article is arrived. So I create a function for that in javascript who goes to a controller, then a service, back controller and finish with a js.erb view.
My first issue is that I have an encoding problem on the js.erb file.
My second issue is that even when I don't have data I can't stop the function before goes to the view file. The js.erb then I got a error because the data is nil.
My javascript function :
var actu = setInterval(myTimer, 20000);
function myTimer() {
$.ajax({
url: '/fluxes/actu',
method: 'GET',
});
}
My controller action:
def actu
#fluxes = Flux.all
#new_hash_article = Actualisation.new(#fluxes).call
if #new_hash_article.length >= 1
#new_hash_article.each do |key, value|
#flux = key
#article = value
respond_to do |format|
format.js
end
end
end
end
My service:
require 'rubygems'
require 'simple-rss'
require 'open-uri'
class Actualisation
def initialize(fluxes)
#fluxes = fluxes
end
def call
new_hash_article = {}
#fluxes.each do |flux|
url = flux.Url
rss = SimpleRSS.parse open(url)
#array_items = []
rss.channel.items.each do |item|
#array_items << item
end
#first = #array_items.first
calculator = 0
flux.articles.each do |article|
if article.Publication == #first.pubDate.to_s
calculator += 1
else
calculator += 0
end
end
if calculator == 0
article = Article.new
article.Title = #first.title
article.Description = #first.description
article.Url = #first.link
article.Publication = #first.pubDate
article.Lu = 0
article.flux_id = flux.id
article.save
new_hash_article[flux] = article
end
end
return new_hash_article
end
end
My view actu.js.erb
jQuery('#flux<%= #flux.id %>').append('<%= j render 'articles/show',
article: #article %>');
I don't if it's usefull but it's my articles/show:
<li id="<%= article.id %>">
<div class="content">
<p><%= article.Title %></p>
<a href="<%= article.Url %>" target="_blank" data="<%= article.id
%>">Voir l'article <i class="fas fa-arrow-right"></i></a>
<div id="switchlu" class="display">
<% if article.Lu == 0 %>
<%= link_to "Afficher comme Lu", articles_marklu_path(id:
article.id), :remote => true %>
<% else %>
<p><i class="fas fa-check"></i>Lu</p>
<%= link_to "Afficher comme non Lu", articles_markpalu_path(id:
article.id), :remote => true %>
<% end %>
</div>
</div>
</li>
The issue :
[1]: https://i.stack.imgur.com/WTZBu.png
Thanks for your time, and your help :)
(Sorry for my english )
I realized 3 tabs that dynamically reload my activities, a GET request is made in order to display a specific list of activities (activity of a group / of the user / news)
However I have a jquery code that no longer runs when I click on one of these tabs,
With rails I return a collection to display the activities, a solution remains to put the jquery in this collection, but when I do this the jquery is executed for each activities loaded and is not that i want.
Activities :
<div class="activity-card-container" id="activity-cards">
<%= render partial: 'activities/activity', collection: #activities %>
</div>
$('.newness').on('mouseenter', function (event) {
event.preventDefault();
$(this).toggleClass('d-none');
let num = parseInt($.trim($('.body__activity_counter').html()));
$('.body__activity_counter').html(--num);
if (num == 0) {
$('.body__activity_counter').addClass('hover');
}
newnessId = $(this).data('id');
$.ajax({url: '/user_activities.json', method: 'POST', data: {user_activity: {activity_id: newnessId}}})
});
Partial Activity :
<div class="activity--js margin-card activity-card card card-body">
.......
<%= activity.title %>
<%= activity.content %>
.......
</div>
One of the Tab controller :
def fetch_activities
user = current_user
activities = []
user.groups.each do |group|
activities << Activity.where(group: group)
end
#all_activities = activities.flatten.sort_by(&:updated_at).reverse
respond_to do |format|
format.js
end
end
and his route :
get "/fetch_activities" => 'activities#fetch_activities', as: 'fetch_activities'
Thanks
I'm trying to display certain stats between two dates (two dropdowns).
My controller has the following method :
def data_stats
data_between_two_dates = Data.where(:created_at => params[:created_at1]..params[:created_at2])
#data_count = data_between_two_dates.count
#gold_data_count = data_between_two_dates.joins(:status).where(status: DataStatus.find(8)).count
puts(#data_count)
puts(#gold_data_count)
I want to be able to display the following variables : data_count and gold_data_count in my view, right after selecting two dates from the dropdowns which I populate from my database.
The view is as follows (/views/data_stats/data_stats.html.erb) :
<select class="my-date" id="created_at1">
<option value="" selected>-- Select Date --</option>
<% datadate = Data.order(created_at: :desc).all %>
<% datadate.each do |data| %>
<%= content_tag(:option, data.created_at, value: data.created_at) %>
<% end %>
</select>
<select class="my-date" id="created_at2">
<option value="" selected>-- Select Date --</option>
<% datadate = Data.order(created_at: :desc).all %>
<% datadate.each do |data| %>
<%= content_tag(:option, data.created_at, value: data.created_at) %>
<% end %>
</select>
<div id="data_stats">
<label class="col-sm-2 control-label">Data count</label>
<span id="data_count"><%= #data_count %></span>
<label class="col-sm-2 control-label">Gold Data count</label>
<span id="gold_data_count"><%= #gold_data_count %></span>
</div>
Within the same view, at the bottom I have the Ajax query :
<script type="text/javascript">
$(document).ready(function() {
$('.my-date').on('change', function() {
var data = {}
$('.my-date').each(function() {
if($(this).val()) {
data[$(this).attr("id")] = $(this).val();
}
});
console.log(data);
// After selecting the two dates
//the above print of `data` gives me this:
//`Object { created_at1: "2016-12-08 16:42:51 UTC", created_at2: "2017-05-23 06:11:02 UTC" }`
if(Object.keys(data).length > 1) {
$.ajax({
type: "GET",
url: "<%= admin_data_stats_path%>",
data: Object.keys(data),
success: function (data) {
console.log("<%= #data_count %>");
console.log("<%= #gold_data_count %>");
//Here when I just print the variables the count is always 0
}
});
}
});
});
</script>
The weird thing is that when I check my terminal after selecting the dates, I can clearly see the result of the puts I made in the controller (I get the count of data and gold data).. But I can't seem to figure out how I can display them in the view.
What am I missing?
Thanks in advance for your help!
Rails variables #data_count and #gold_data_count in console.log returns their value when page was loaded, but not when ajax is success.
Your controller can render json with partial, if you want
respond_to do |format|
format.js { render json: { html: render_to_string(partial: 'data_stats', locals: { data_count: #data_count, gold_data_count: #gold_data_count }) } }
end
Partial with stats _data_stats.html.erb:
<div id="data_stats">
<label class="col-sm-2 control-label">Data count</label>
<span id="data_count"><%= #data_count %></span>
<label class="col-sm-2 control-label">Gold Data count</label>
<span id="gold_data_count"><%= #gold_data_count %></span>
</div>
And use it in your js, such as
$.ajax({
type: "GET",
url: "<%= admin_data_stats_path%>",
data: Object.keys(data),
dataType: 'json'
}).done((response) => {
$('#data_stats').replaceWith(response.html)
})
Hey guys I need to know the answers to some questions. First of all how do I handle ajax call when I am not returning anything from the controller because it always ask me for the view for the called function but since I have called that function using ajax how can it have a view.(I am using it in ROR(ruby on rails))
bookmark.html.erb
<div class="row">
<div id="page-wrapper-lbms" class="small-12 medium-12 large-12 columns dashboard-page">
<input type="hidden" id="bookmarked_against_req_id" value=<%= #data2%> />
<%
if #requests != nil
#requests.each.with_index do |request,index|
if request != nil
%>
<header>
<div style="text-align:center">
</span>
</div>
<h2 style="text-align:center"><%= request.title %></h2>
<div style="text-align:center">
<h6 style="color:#aaaaaa"><strong><%= request.is_service%></strong></h6>
</div>
</header>
<div class ="row">
<div class="small-12 medium-12 large-8 columns">
<div id="request-content-lbms" class="panel">
<p>
<%= request.description%>
</p>
</div>
<div id="list-request-cat-lbms">
<span class="fa fa-tag"></span>
<% if #tag[index] != nil
#tag[index].each do |cat| %>
<%= cat.title %>
<%end%>
<%end%>
</div>
</div>
<aside class="small-12 medium-12 large-4 columns" style="padding-left:10%">
<h3 ><strong>Syed Muhammad Ali Gardezi</strong></h3>
<time><%= request.created_at %></time><br />
<%end%>
<button class="button tiny">Schedule Meeting</button>
</aside>
</div>
</div>
<%end%>
<%end%>
<script>
function ajax_bookmark(abc , cde){
var cde = $('#bookmarked_against_req_id').val();
$.ajax({
type: "GET",
url: 'bookmark_request',
data: {
d:abc,
d1:cde
},
error:function(){
},
dataType: 'json',
//beforeSend:function(){},
//complete:function(o,s){},
success:function(data){
location.href ="/requests/bookmark"
},
type: 'get'
});
}
</script
bookmark_request
def bookmark_request()
data = params[:d]
data1 = params[:d1]
data2 = data1#["$oid"]#.split('"' , 6)
#asd
request_bookmarked = Request.getRequest(data)
bookmarked_against_Request = Request.getRequest(data2)
request_bookmarked_2 = request_bookmarked
bookmarked_against_Request_2 = bookmarked_against_Request
#asd
if bookmarked_against_Request_2[:favourites]
bookmarked_against_Request_2[:favourites] << request_bookmarked[:id]
else
bookmarked_against_Request_2[:favourites] = Array.new
bookmarked_against_Request[:favourites] = Array.new
bookmarked_against_Request_2[:favourites] << request_bookmarked[:id]
end
if request_bookmarked_2[:favourites_of]
request_bookmarked_2[:favourites_of] << bookmarked_against_Request[:id]
else
request_bookmarked_2[:favourites_of] = Array.new
request_bookmarked[:favourites_of] = Array.new
request_bookmarked_2[:favourites_of] << bookmarked_against_Request[:id]
end
request_bookmarked.update(Hash['favourites' ,request_bookmarked_2[:favourites]])
bookmarked_against_Request.update(Hash['favourites' ,bookmarked_against_Request_2[:favourites]])
#asd
bookmarks = Bookmark.where(request_id: bookmarked_against_Request[:id]).first()
#asd
b = bookmarks
if bookmarks != nil
#bookmarks.each { |bookmark| bookmark.update_attributes(corsponding_requests: request_bookmarked[:id]) }
b[:corsponding_requests] << request_bookmarked[:id]
b.update(Hash['corsponding_requests' , b[:corsponding_requests]] )
else
bookmark = Hash.new
bookmark["owner_req"] = session[:user]
bookmark["request_id"] = bookmarked_against_Request[:id]
bookmark["corsponding_requests"] = Array.new
bookmark["corsponding_requests"] << request_bookmarked[:_id]
Bookmark.createBookmark(bookmark)
end
flash[:notice] = "Request has been bookmarked successfully."
end
Now when ever I run this function i need it to go into the success function of ajax in bookmark.html.erb but the problem is it says I can't find the view. What is it that I am doinf wrong over here
Second when ever I need to return something I have read that I need to make a html helper but I can't figure out what a html helper is. and how can I return a string back to ajax function
Any help will be appreciated (I am new to AJAX)
You'll probably want to take a look at the rails guides - they're a great source of general grounding: http://guides.rubyonrails.org. For returning different responses based on the request format (ajax vs. html), see http://guides.rubyonrails.org/action_controller_overview.html#rendering-xml-and-json-data and #davidwessman's answer above.
Generally, you'll typically return JSON data from an ajax request; so, for instance, in the controller you might say
respond_to do |format|
format.js {render json: #my_ojects.to_json}
end
Note that there are several ways to render json, including the gems like rabl. If you're returning json like that, you don't need to render a rails view (unless you're using a view to build your json, like rabl does or is hinted at in davidwessman's answer with js.erb).
Hope that helps.
Gonna try to answer you :
First:
If you have a special action for your ajax call you only need:
def custom_action
end
This will render the custom_action.js.erb if called with ajax, for example a form with remote: true.
If you call one of your CRUD-actions and need to be able to respond to multiple formats:
def show
#book = Book.find(params[:id])
respond_to do |format|
format.html # will render show.html.erb
format.js # will render show.js.erb
end
end
If you put a link in your view:
link_to('Remote Ajax Call', book_path(#book), remote: true)
This link will call the method show and render as :js.
It will look for app/views/books/show.js.erb which may look something like:
<% if #book.present? %>
$('#book-title').html("<%=#book.title%>");
<%end%>
And in your view, close to the link above, this will then change the text inside a html-tag with I'd book-title.
<div id="book-title">
</div>
Second:
I do not understand what you mean by
...need to return something...
Can you add an example?
Hope that this can help you a bit.
Edit:
This is my try to understand what you want to do:
In your view:
<%= hidden_field_tag :bookmarked_against_req_id, value: #data2 %>
<% if #requests != nil %>
<% #requests.each.with_index do |request,index| %>
<% if request.present? %>
<%= link_to 'Bookmark it', bookmark_request_path(request), remote: true %>
<%= request.title %>
<%= request.is_service%>
<%= request.description%>
<% if #tag[index].present? %>
<% #tag[index].each do |cat| %>
<%= cat.title %>
<%end%>
<%end%>
<%= request.created_at %>
<%end%>
<%end%>
<%end%>
In your controller:
def bookmark_request()
request_bookmarked = Request.getRequest(params[:id]) # the params[:id] should be set in the request.
bookmarked_agains_Request = Request.getRequest(params[:bookmarked_against_req_id) # This is defined in your hidden_field_tag
When your action bookmark_requestis done. If the request was AJAX you will render the JavaScript-file bookmark_request.js.erb
Here you should have the script you put in your view:
If the resource is saved, you should put JavaScript to render 'Success' or if it failed you should do otherwise.
The flash[:notice] = "Request has been bookmarked successfully."will not be understood by your AJAX-request.
I'm new to Rails and javascript. I've developed a small application in ruby on rails which searches for products in the database using solr's sunspot. I used to display the contents using kaminari's pagination. But now I want to take it off and use infinite scrolling instead. I'm referring to the infinite scroller below.
https://github.com/pklauzinski/jscroll
I want to integrate this into my rails app. How can I do it?
Here's my controller code:
def show
if params[:name].nil?
#search = []
else
#search = Sunspot.search(Clothes) do
fulltext params[:name]
paginate :page => params[:page], :per_page => 24
order_by :maxprice
end
#results = #search.results
end
flash[:alert] = "Enter something!"
end
def autocomplete
list=[]
#res = Clothes.search do
fulltext params[:term]
paginate :page => 1, :per_page => 100
order_by :maxprice
end
#rest = #res.results
#rest.each do |brand|
list << {"label"=>brand.name, "value"=>brand.name, "id"=>brand.id}
end
respond_to do |format|
format.json{render :json=>list.to_json, :layout=>false}
end
end
end
And here's my view code:
<div id="container">
<% for prod in #results %>
<div class="product">
<div class="image"><%= image_tag(prod.image, :alt => "logo", :size => "75x75") %> </div>
<div class="name"><h3> <%= prod.name %> </h3></div>
<div class="price"><h5>Old Price:</h5><%= prod.maxprice%></div><div class="price"> <h5>New Price:</h5><%= (prod.maxprice)-(prod.maxprice * prod.discount / 100) %></div>
</div>
<% end %>
<% else %>
<div class="notice"><%= flash[:alert] %></div>
<% end %>
</div>
Also the script code for my auto-complete and handling my ajax.
<script>
$(document).ready(function() {
$.ajax({
url : "shirts/first",
type : "GET"
});
$("#name").autocomplete({
source : "shirts/autocomplete",
autoFocus : false,
minLength : 1,
select : function(event, ui) {
document.getElementById("name").value = ui.item.value;
$.ajax({
url : "shirts/show?name=" + ui.item.value,
type : "GET"
});
}
});
});
</script>
hye man you can try it with this
http://railscasts.com/episodes/114-endless-page