wait for ajax request till user stops typing - ajax

I have a live search field which makes ajax call while typing. My problem is that it makes the call for every letter being typed.
Here is my code
in js file
$(document).ready(function(){
$("#employees_search input").keyup(function() {
$.get($("#employees_search").attr("action"), $("#employees_search").serialize(), null , "script");
return false;
});
});
in html file
<div align="center" id="empName">
<%= form_tag employees_path, :method => 'get', :id => "employees_search" do %>
<p>
<%= text_field :search, params[:search], placeholder: 'Search Employees Here', id: 'search_field' %>
</p>
<% end %>
</div>
in controller
#employees = Employee.where("department='Delivery'").paginate(:per_page => 6, :page => params[:page]).searchByEmp(params[:search][0]).order('name ASC')
in model
def self.searchByEmp(search)
if search
where('name LIKE ?', "#{search}%")
else
scoped
end
end
Actually I need to send ajax request only after the user stops typing the word other than for every letter typed. How can I do that?
Thanks in advance.

var liveSearchTimer;
$liveSearchInput.keyup(function() {
clearTimeout(liveSearchTimer);
liveSearchTimer = setTimeout(liveSearchDoAjax, 500);
});
The request will be sent only when there has been half a second in which no key has been pressed.

Related

Sending form input to controller function

I'm trying to let user enter an id, then see the children of that ID (via a self-join association). My children function works in the rails console, but not in the controller, because I suspect I'm sending the form input to the controller wrong.
Controller:
def index
..............
if params[:children]
#guideline = Guideline.find(params[:seeChildren])
#guideline.children
else
#guidelines = Guideline.all
end
end
Form:
<%= form_tag(guidelines_path, :method => "get", id: "search-form") do %>
<td><%= label_tag(:seeChildren, "See Immediate Children")%></td>
<td><%= text_field_tag :seeChildren, params[:seeChildren], placeholder: "Enter ID" %></td>
<td><%= submit_tag "Search", :name => nil %></td>
<% end %>
routes:
Prefix Verb URI Pattern Controller#Action
guidelines GET /guidelines(.:format) guidelines#index
POST /guidelines(.:format) guidelines#create
new_guideline GET /guidelines/new(.:format) guidelines#new
edit_guideline GET /guidelines/:id/edit(.:format) guidelines#edit
guideline GET /guidelines/:id(.:format) guidelines#show
PATCH /guidelines/:id(.:format) guidelines#update
PUT /guidelines/:id(.:format) guidelines#update
DELETE /guidelines/:id(.:format) guidelines#destroy
root GET / welcome#index
I appreciate the help! I'm sure it's a stupidly simple solution, but I can't seem to find the answer myself
I suspect I'm sending the form input to the controller wrong.
text_field_tag :seeChildren, params[:seeChildren], placeholder: "Enter ID" %>
Do this instead:
text_field_tag :seeChildren, nil, placeholder: "Enter ID" %>
which will create this html:
<input id="seeChildren" type="text" placeholder="Enter ID" name="seeChildren">
When the user submits the form, one of the name/value pairs sent to the server will be seeChildren="some text", where seeChildren is the name attribute of the textfield, and "some text" is whatever the user entered.
params[:seeChildren] won't exist until after the user submits the form. When the browser sends the request created by the form to the server, rails extracts all the name/value pairs into the params Hash.

Ruby rails - text field change event and ajax

Ok.. I am running into this types of issues more often. Most of my html is ajax rendered and I use fields and values from rendered page to make new ajax requests. But none of the events seem to fire. Need to understand this why is that.
This is a simple form with text field which I want to make ajax call on a change event, to skip the form/button. And it is not working. What do I change here?
<div><%= form_tag users_search_path, :remote => true, :id => 'search_form' do %>
<%= text_field_tag :keyword, nil, :maxlength => 11, :size => 20 %># Tried this putting outside of this form, didn't work.
<%= submit_tag " Search ", :id => "search_button", :onclick => "javascript:user_search()"%>
<% end %></div>
<%= text_field_tag :keyword, nil, :maxlength => 11, :size => 20 %> Tried this putting outside of this form, didn't work.
$(function(){
$("#keyword").change(function() {
alert('ok');
$.post('/users/search', function(data) {
$("#search").html(data);
});
});
}
Because the last jquery code is a function, it's not executed until you call it. Remove the first and last line, then it will be run when the page is loaded so it will attach the function defined inside to your text box.

Multiple pagination with kaminari via Ajax

I want to apply multiple pagination with Kaminari via Ajax now here is my code for controller
def user_note
#user = current_user
#notes = Bookmark.where('user_id = ? && note is not NULL',current_user.id).order('created_at DESC').page(params[:page_1]).per(4)
#bookmarks = Bookmark.where('user_id = ? && note is NULL',current_user.id).order('created_at DESC').page(params[:page_2]).per(4)
respond_to do |format|
format.html
format.xml{ render :xml => #user}
end end
now for views i have two partials to render this arrays
<div id="bookmarks">
<%= render :partial =>"users/bookmark",:locals => { :bookmark => #bookmarks} %>
</div>
<%= paginate #bookmarks,:remote => true, :param_name => 'page' %>
inner partial is
<% bookmark.each do |bookmar| %>
<%= render :partial => 'show_bookmark.html.erb' , :locals => { :bookma => bookmar} %>
<%end%>
script for pagination update is being handled in a separate file
$('#bookmarks').html('<%= escape_javascript render(:partial =>"users/bookmark",:locals => { :bookmark => #bookmarks}) %>');
$('#paginator').html('<%= escape_javascript(paginate(#bookmarks, :remote => true).to_s) %>');
But by doing every thing it is not updating to state of page neither the contain in the page.
you are missing to pass params at this line
$('#paginator').html('<%= escape_javascript(paginate(#bookmarks, :remote => true).to_s) %>');
i think it should be like this
$('#paginator').html('<%= escape_javascript(paginate(#bookmarks, :remote => true, :param_name => 'page_2').to_s) %>');
and you are also passing wrong param at this line
<%= paginate #bookmarks,:remote => true, :param_name => 'page' %>
it should be like this
<%= paginate #bookmarks,:remote => true, :param_name => 'page_2' %>
and please also check that whether you are sending the response correctly to the JS file or not.
I found this question searching for paginating multiple models on the same page. It's not clear to me how the pagination for the #notes collection is intended to work, but as presented, the solutions will only paginate the #bookmarks collection via AJAX.
There will be issues if you want to maintain pagination for both collections via html OR if you change the js file to render both collections.
I implemented a solution to my similar problem like this:
An html view that renders a template with two partials: one for #notes (including its pagination helper) and another that renders #bookmarks with its pagination helper
Pagination links marked with remote: true
One js view that re-renders the two partials, something like
$('#notes_container').html('<%= j(render partial: 'paginated_notes_list') %>');
$('#bookmarks_container').html('<%= j(render partial: 'paginated_bookmarks_list'); %>');
This is the key: Pagination links that take the current page of the other model as a parameter. This way you do not "lose" which page you are on in the other model.
<%= paginate #notes, param_name: 'page_1', params: {page_2: params[:page_2]} %>
<%= paginate #bookmarks, param_name: 'page_2', params: {page_1: params[:page_1]} %>
Again, I'm not really clear on how the asker's system is supposed to function, but this solution will allow user to page through both models without losing their "place" in the other model via AJAX or html.

rails3 ajax: What is the best way of persisting local variables via ajax?

This is how my view looks (please ignore the opening and closing tags):
#obj1.leaves.each do |l|
<div id = "form">
if <some_condition>
render :partial => 'shared/view1', :locals => { :l => l }
else
render :partial => 'shared/view2', :locals => { :l => l }
end
</div>
end
And the final action on view1 causes view2 to display and vice versa thru ajax. But when view1 or view2 are rendered the local variable 'l' is not recognized anymore and throws an error causing the forms not to display (except on manual page refresh). What do I do to make the forms work and persisting my 'l'?
Thanks for your help in advance.
EDIT: My create.js.erb file for view1 (view2 i actually the destroy method so vice versa):
$("#form").replaceWith("<%= escape_javascript(render('shared/view2')).html_safe %>")
And my actual view:
<%= form_for([l, l.likes.build], :remote => true) do |f| %>
<div class="actions"><%= f.submit "Like" %></div>
<% end %>
(Not an answer.)
#obj1.leaves.each do |l|
partial = <some_condition> ? 'shared/view1' : 'shared/view2'
render :partial => partial, :locals => { :l => l }
end
Locals are just that; local. It's not clear to me what Ajax you're talking about--replaceWith just replaces content, it doesn't make a request. If it's all in the same request, you could make l an instance variable (#l) and see if that clears things up.

link_to remote=>true not updating with ajax

Using rails3 and prototype (rails.js)
I have a simple list of products with edit and delete links as images.
When deleting a product, the list is not updated. Refreshing the page shows that the product has indeed been deleted.
/app/views/products/list.rhtml
<div id="product_list">
<%= render :partial => 'list' %>
</div>
/app/views/products/_list.rhtml
<%= link_to image_tag("delete.png"), { :controller => 'products', :action => 'destroy', :id => product }, :method => :delete, :confirm => "Are you sure?", :remote => true %>
/app/controllers/products.rb
def destroy
Product.find(params[:id]).destroy
#products = Product.all
end
/app/views/products/destroy.rjs (not sure what to do with that...)
$(document).ready(function() {
$("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>");
});
So the remote link seems to work fine.
I'm not sure how to use the ajax callback to update #product_list
I tried to put the following in the head of the page:
$(document).ready(function(){
$('#product_list').bind("ajax:success", function(evt, data, status, xhr){
alert('hello');
})
});
But it's not executed (that's probably not a valid code for prototype) and I wouldn't know anyway what code to put inside so that my list gets updated after destroying a product
Any help (other than "use jQuery") is greatly appreciated!
EDIT: Here is the server log for the delete action (after I moved the javascript above to destroy.js.erb)
Started POST "/products/destroy/3" for 127.0.0.1 at .....
Processing by ProductsController#destroy as JS
Parameters: {"_"=>"", "id"=>"3"}
[1m[36mProduct Load (0.0ms)[0m [1mSELECT `products`.* FROM `products` WHERE (`products`.`id` = 3) LIMIT 1[0m
[1m[35mSQL (0.0ms)[0m BEGIN
[1m[36mSQL (0.0ms)[0m [1mDELETE FROM `products` WHERE (`products`.`id` = 3)[0m
[1m[35mSQL (78.1ms)[0m COMMIT
[1m[36mProduct Load (0.0ms)[0m [1mSELECT `products`.* FROM `products`[0m
Rendered products/destroy.js.erb within layouts/standard (31.2ms)
Completed 200 OK in 312ms (Views: 62.5ms | ActiveRecord: 78.1ms)
Processing by ProductsController#destroy as JS so the remote link works
[36mProduct Load (0.0ms)[0m [1mSELECT products. FROM products* The #products = Product.all is executed
Rendered products/destroy.js.erb within layouts/standard the javascript fie is rendered
So now I guess it's a problem with the javascript code:
$(document).ready(function() {
$("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>");
});
Is that kind of code supported by prototype? I don't use jQuery...
Found the answer on my own:
/app/controllers/products.rb
def destroy
Product.find(params[:id]).destroy
#products = Product.all
respond_to do |format|
format.js { render :layout=>false }
end
end
/app/views/products/destroy.js.erb
$("product_list").update("<%= escape_javascript(render(:partial => "list")) %>");
Why is there NO tutorial, code example or anything clear about the ajax thingy in rails3?
I had to use code parts from 5 different blogs, forums and casts, and mix them all together until I find the right combination... sigh
on repecmps lines,
just insert :content_type to represent part of content downloaded, like this:
format.js { render :layout=>false, :content_type => 'application/javascript' }
with complete part of repecmps responses:
def destroy
Product.find(params[:id]).destroy
#products = Product.all
respond_to do |format|
format.js { render :layout=>false, :content_type => 'application/javascript' }
end
end
/app/views/products/destroy.js.erb:
$("product_list").html("<%= escape_javascript(render(:partial => "list")) %>");
and, I found this to night.
I think your destroy action is doing too much, as it is destroying the product and list all the products. You could do something like:
/app/controllers/products.rb
class ProductsController < ApplicationController
respond_to :html, :js
def destroy
#product_id = params[:id]
Product.find(#product_id).destroy
respond_with do |format|
format.html { redirect_to posts_path }
end
end
end
/app/views/products/destroy.js.erb
$("#product_<%= #product_id %>").remove()
As long as your product element in the index uses something like dom_id, here's an example:
<ul id="products">
<% #products.each do |product|
<li id=<%= dom_id product %>>...</li>
<% end %>
</ul>
This way your destroy action will only destroy the intended product, and if the client has no JS it fallback the HTML request which will redirect to the products index which will be updated accordingly.
Hum... I'm going to try to help you.
Are you sure after clicking on the delete link, the request is handled as JS ?
Check on the log.
Is you file "app/views/products/destroy.rjs" is rendered ?
Rjs doesn't exist anymore in rails3. The new name is UJS.
Try to rename the file to destroy.js.{haml or erb}
Is it better ?

Resources