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 :)
Related
Hello I have 3 lists on one page that will display and each list has a load more button. I want to be able to click the loadmore button and load 3 items per click.
The problem that I am facing is that when i click the load more button, the second page doesnt show up but on the 2nd click it populates only the last page.
Another is when for instance the button is clicked on completed and then clicking the button on expired creates duplicates of the expired list.
So pretty much the all of the buttons are changing all of the lists eventhough they are not corresponding to them.
I realize that im using url_for which may be the reason im in this problem. perhaps there is a better way to achieve this?
When clicking load more button on the console i get:
www.mywebsite.com/your_essays?page_completed=2".
www.mywebsite.com/your_essays?page_completed=3".
www.mywebsite.com/your_essays?page_expired=2".
This shows what the current page is based on the url, however if i have multiple lists how can i achieve this to make each list separate from each other? is there a better way to do this??
reservations_controler.rb:
def your_essays
user = current_user
#reservations = user.reservations.where("user_id = ?", current_user.id).where("status = ?", true)
#pending
#reservations_pending = user.reservations.where("turned_in = ?", false).where("completed = ?", false).where("due_date >= ?", DateTime.now).order(created_at: :desc).page(params[:page_pending]).per_page(3)
#reservations_pending1 = user.reservations.where("turned_in = ?", false).where("completed = ?", false).where("due_date >= ?", DateTime.now).order(created_at: :desc)
#completed
#reservations_completed = user.reservations.where("turned_in = ?", true).where("completed_doc_updated_at <= due_date", true).order(created_at: :desc).page(params[:page_completed]).per_page(3)
#reservations_completed1 = user.reservations.where("turned_in = ?", true).where("completed_doc_updated_at <= due_date", true).order(created_at: :desc)
#expired
#reservations_expired = user.reservations.where("due_date <= ?", DateTime.now).where("turned_in = ?", false).where("completed = ?", false).order(created_at: :desc).page(params[:page_expired]).per_page(3)
#reservations_expired1 = user.reservations.where("due_date <= ?", DateTime.now).where("turned_in = ?", false).where("completed = ?", false).order(created_at: :desc)
end
my_essays.html.erb:
<div id="content-load-more-completed">
<%= render 'your_essays_completed', reservations_completed: #reservations_completed %>
</div>
<% unless #reservations_completed.current_page == #reservations_completed.total_pages %>
<div id="view-more-completed" class="center" style="min-width:100%;" >
<%= link_to('View More', url_for(page_completed: #reservations_completed.current_page + 1), remote: true, class: 'btn btn-back', style: 'min-width:100%;') %>
</div>
<% end %>
<div id="content-load-more-expired">
<%= render 'your_essays_expired', reservations_expired: #reservations_expired %>
</div>
<% unless #reservations_expired.current_page == #reservations_expired.total_pages %>
<div id="view-more-expired" class="center" style="min-width:100%;" >
<%= link_to('View More', url_for(page_expired: #reservations_expired.current_page + 1), remote: true, class: 'btn btn-back', style: 'min-width:100%;') %>
</div>
<% end %>
my_essays.js.erb:
$('#view-more-completed').click(function (event) {
$('#content-load-more-completed').append("<%=j render 'your_essays_completed', reservations_completed: #reservations_completed, format: 'html' %>");
});
<% if #reservations_completed.current_page == #reservations_completed.total_pages %>
$('#view-more-completed').remove();
<% else %>
$('#view-more-completed a').attr('href', '<%= url_for(page_completed: #reservations_completed.current_page + 1) %>');
<% end %>
$('#view-more-expired').click(function (event) {
$('#content-load-more-expired').append("<%=j render 'your_essays_expired', reservations_expired: #reservations_expired, format: 'html' %>");
});
<% if #reservations_expired.current_page == #reservations_expired.total_pages %>
$('#view-more-expired').remove();
<% else %>
$('#view-more-expired a').attr('href', '<%= url_for(page_expired: #reservations_expired.current_page + 1) %>');
<% end %>
partials for _your_essays_completed.html.erb and _your_essays_expired.html.erb:
<% reservations_completed.each do |reservation| %>
<!-- content -->
<% end %>
<% reservations_expired.each do |reservation| %>
<!-- content -->
<% end %>
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
I'm trying to do an Ajax call on Ruby on Rails. When I select 2 collection_select's the third has to be rendered by Ajax. I'm new to Ruby on Rails, so if anybody could help me, I'd be thankful.
_form.html.erb:
<%= form_for(#preco_servico) do |f| %>
<div class="field">
<%= f.label :produto %>
<%= collection_select(:preco_servico, :produto, Produto.order('tipo'), :tipo, :tipo) %>
</div>
<div class="field" >
<%= f.label "Análise" %>
<%= collection_select(:preco_servico, :analise, TipoAnalise.order('tipo'), :tipo, :tipo) %>
</div>
<div class="field" id="parametro-select", :remote >
</div>
...
<% end %>
application.js:
jQuery(function($) {
$("#preco_servico_analise").change(function() {
var produto_id = $('select#preco_servico_produto :selected').val();
var analise_id = $('select#preco_servico_analise :selected').val();
$.get('/preco_servicos/update_parametro/' + produto_id + '/' + analise_id, function(data){
$("#parametro-select").html(data);
})
return false;
});
})
The method on controller:
def update_parametro
#precos = PrecoServico.where(:analise => params[:analise], :produto => params[:produto])
#sub_parametros = []
#precos.each do |preco|
#sub_parametros = Parametro.where("nome NOT IN (?)", preco.parametro)
end
respond_to do |format|
format.js
end
end
I've already included the code below on application.html.erb:
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
And the file update_parametro.js.erb:
sub_parametro <%= collection_select(:preco_servico, :parametro, #sub_parametros, :nome, :nome) %>
On console I get this:
Started GET "/preco_servicos/update_parametro/produto2/analise2"
for 127.0.0.1 at 2014-01-28 23:25:21 -0200 Processing by
PrecoServicosController#update_parametro as / Parameters:
{"preco_servicos"=>"preco_servicos",
"update_parametro"=>"update_parametro", "produto"=>"produto2",
"analise"=>"análise2"} PrecoServico Load (0.2ms)
SELECT preco_servicos.* FROM preco_servicos WHERE
preco_servicos.analise = 'análise2' AND preco_servicos.produto
= 'produto2' Rendered preco_servicos/update_parametro.js.erb (0.5ms) Completed 200 OK in 8ms (Views: 6.0ms | ActiveRecord: 0.2ms)
It tells me it is rendered, but nothing changes on screen and nothing appears in firebug.
The submit button works only for validating the javascript in the question.js file, but it doesnt do the basic function, which is submiting the form itself! Your help is very appreciated.
`Ruby page code containing the form element
<script type="text/javascript">
loadScript("/javascripts/questions.js",function() {});
</script>
<h1 class="hdr1">Ask question</h1>
<%= link_to Profile.find(session[:user_id]).firstname,{},{:id=>"person"} %>
<% form_for(#question) do |f| %>
<%= f.error_messages %>
<br>
<table id="newQuesTable" width="100%" cellpadding="5" border="1">
<tr>
<td width="25%"><label>Your Question </label> - </td>
<td><%= f.text_area :content, :rows=>5, :cols=>35, :maxlength=>500, :id=>"newQuesTxtA"%> </td>
<td width="30%"><i><label id="newQuesLabel" style="color:red;background-color:yellow;visibility:visible;"></label></i></td>
</tr>
<tr>
<td width="25%"><%= f.label :tags %> -</td>
<td><%= f.text_field :tags, :maxlength=>48, :id=>"tagsNewQuesTxt" %></td>
<td width="30%"><i><label id="nquesTagsLabel" style="color:red;background-color:yellow;visibility:visible;"></label></i></td>
</tr>
<tr>
<td>Question Scope -</td>
<!--the open id for the hierarchy comes here-->
<!-- the select box comes here -->
<td> <%= f.text_field :ID_string %></td>
</tr>
</table>
<br>
<%= f.submit 'Post Question' %> <%= f.submit 'Cancel', :id=>'docNewCancelButton', :type=>'reset' %>
<% end %>
<br>
<hr>
<br>
<%= link_to 'Back', questions_path %>
Javascript code present in question.js file
Event.observe(window, 'load', function(){
$('new_question').observe('submit', submitQuestionCreate);
$('quesNewCancelButton').onClick('resetquesform')
});
function resetquesform()
{
event.preventDefault();
reset($('new_question'));
return;
}
function submitQuestionCreate(event)
{
//event.preventDefault();
var quesfield = $('newQuesTxtA');
var tagsfield = $('tagsNewQuesTxt');
var labelnques = $('newQuesLabel');
var labelnquestags = $('nquesTagsLabel');
if((quesfield.value == "") && (tagsfield.value == ""))
{
event.preventDefault();
//alert('Question and Tags field cannot be empty');
labelnques.innerHTML = 'Question field cannot be empty!';
labelnquestags.innerHTML = 'Please enter (some) relevant tags...';
probchk = true;
return;
}
if((quesfield.value == "") || (tagsfield.value == ""))
{
event.preventDefault();
if (quesfield.value == "")
{
labelnques.innerHTML = 'Question field cannot be empty!';
labelnquestags.innerHTML = "";
probchk = true;
return;
}
if (tagsfield.value == "")
{
labelnquestags.innerHTML = 'Please enter (some) relevant tags...';
labelnques.innerHTML = "";
probchk = true;
if (quesfield.value.length > 500)
{
labelnques.innerHTML = 'Question too long (should be 500 characters or less)';
probchk = true;
}
return;
}
}
if (quesfield.value.length > 500)
{
event.preventDefault();
labelnques.innerHTML = 'Question too long (should be 500 characters or less)';
probchk = true;
return;
}
}
***question controller file***
# GET /questions/1
# GET /questions/1.xml
def show
#question = Question.find(params[:id])
if !session[:user_id].nil?
##owner = Document.is_owner(params[:id],session[:user_id])
#fav_count = FavouriteQuestion.count(:all,:conditions=>["question_id = ? AND profile_id = ?",#question.id,session[:user_id]])
if FavouriteQuestion.count(:all,:conditions=>["question_id = ? AND profile_id = ?",#question.id,session[:user_id]]) > 0
#fav_status = 1
else
#fav_status = 0
end
else
#owner = Document.is_owner(params[:id],nil)
#fav_status = 0
end
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #question }
end
end
# GET /questions/new
# GET /questions/new.xml
def new
#question = Question.new
if !session[:user_id].nil?
#question.profile_id = session[:user_id]
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #question }
end
end
It appears as if you are doing a, ruby on rails form with javascript validations. While you can do that, I would recommend starting with a basic MVC structure. I highly recommend running through a some basics that will orient you to this. http://guides.rails.info/ is a great place to start. I wish that it had been there when I got started, it would have saved me a great deal of pain :)
The you will want to move your validations into the model.
in app/models/question.rb
class Question < ActiveRecord::Base
validates_presence_of :question
end
more baked in validation options here.
then you want to have a controller to respond to your create events. in app/controller/question_controller.rb:
class QuestionsController < ApplicationController
def new
#question = Question.new
end
def create
#question = Question.new(params[:question])
if #question.save
flash[:confirm] = "You have asked a question"
redirect_to questions_path
else
flash[:error] = #question.errors.full_messages.join(",")
render :action => :new
end
end
end
And then your config/routes.rb
map.resources :questions
Your form should look similar to what you have:
<%= flash[:error] %>
<% form_for(#question) do |f| %>
<%= f.text_field :content ...
<% end %>
the flash is crude, I haven't used it in a while. I use the message_block plugin. You can also read more about how the flash works here
There are plugins to shorten some of this, but I recommend cutting your teeth my doing some of this first. It helps you get oriented. Best of luck!