Call a javascript function dynamically from controller - javascript

I am using jquery autocomple mechanism. It needs an array on which this javascript will run and show the result on typing.Thats why I need the availableTags array. But problem is that javascript is loading only the time of page loading and it is capturing the initial array but I need the javascript to be called dynamically during the type of each keyword typing...so how can I resolve this?
Actually I want to call this javascript function from my controller function.
My controller code is:
class EmployeesController < ApplicationController
skip_before_action :verify_authenticity_token
def new
#emp=Employee.new
#emps=Employee.all
#check=params[:pt]
puts #check
x_dynamic=check_ultimate(#check)
puts "return value"
puts x_dynamic
y=string_include(x_dynamic,#emps)
puts y
end
def string_include(substring,data_ref)
loo=0
#firstname_array=Array.new
data_ref.each do |d_ref|
puts "in the loop of string_include method"
my_string=d_ref.compact_string
if my_string.include? substring
puts "String "+ my_string+" includes "+substring
loo=loo+1
puts loo
puts d_ref.firstname
#firstname_array && #firstname_array.push(d_ref.firstname)
end
end
puts "This is the array"
puts #firstname_array
return 1
end
def create
#emp=Employee.new(u_params)
ret_val=string_check(params[:employee][:firstname])
if ret_val == 1
ret_one=convert(params[:employee][:firstname],#emp)
if ret_one == 1
#emp.save
redirect_to new_employee_path , :notice => "Inserted!!!"
end
elsif ret_val == 0
redirect_to new_employee_path , :notice => "Match,Not inserted!!!"
else
redirect_to new_employee_path , :notice => ret_val.to_s
end
end
def u_params
params.require(:employee).permit(:firstname)
end
def convert(entered_name,ref)
count =0
txt=entered_name.chomp
size1=txt.to_s.length
arr1=Array.new
for j in 0..size1
arr1 && arr1.push(txt && txt[j])
end
for i in 0..size1
if arr1
if arr1[i]==" " || arr1[i]=="#" || arr1[i]=="#" || arr1[i]=="{" || arr1[i]=="}" || arr1[i]=="(" || arr1[i]==")" || arr1[i]=="[" || arr1[i]=="]" || arr1[i]=="." || arr1[i]==";" || arr1[i]=="," || arr1[i]=="%" || arr1[i]=="&" || arr1[i]=="*" || arr1[i]=="!" || arr1[i]=="?" || arr1[i]=="$" || arr1[i]=="^" || arr1[i]==":" || arr1[i]=="-" || arr1[i]=="/"
count=count+1
arr1 && arr1[i]=""
end
end
end
temp=arr1 && arr1.join
final1=temp.gsub(/\s+/, "").downcase
ref.compact_string=final1
ref.save
return 1
end
def string_check(first_name)
count =0;
temp1=first_name
supplied_val=temp1
flag=100
puts "Entered in string_check method"
#employees=Employee.all
t1=Employee.all.count
puts t1
#employees.each do |employee|
puts "in the loop"
temp2=employee
table_val=temp2.compact_string
size1=supplied_val.to_s.length
# size2=table_val.to_s.length
puts table_val
puts supplied_val
arr1=Array.new
for k in 0..size1
arr1 && arr1.push(supplied_val && supplied_val[k])
end
for i in 0..size1
if arr1
if arr1[i]==" " || arr1[i]=="#" || arr1[i]=="#" || arr1[i]=="{" || arr1[i]=="}" || arr1[i]=="(" || arr1[i]==")" || arr1[i]=="[" || arr1[i]=="]" || arr1[i]=="." || arr1[i]==";" || arr1[i]=="," || arr1[i]=="%" || arr1[i]=="&" || arr1[i]=="*" || arr1[i]=="!" || arr1[i]=="?" || arr1[i]=="$" || arr1[i]=="^" || arr1[i]==":" || arr1[i]=="-" || arr1[i]=="/"
count=count+1
# puts count
arr1 && arr1[i]=""
end
end
end
temp_st=arr1 && arr1.join
final_st=temp_st.gsub(/\s+/, "").downcase
if final_st==table_val
puts "Entered in if"
flag=0
break
else
puts "Entered in else"
flag=1
end
end
puts #employees.count
return flag
end
def check_ultimate(get_val)
puts "Entered in check_ultimate method"
puts get_val
remove_data=get_val.to_s.chomp
#puts remove_data
si1=remove_data.to_s.length
puts si1
arr3=Array.new
for p in 0..si1
arr3 && arr3.push(remove_data && remove_data[p])
end
puts arr3
puts "array end,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
count=0
for i in 0..si1
puts i
if arr3
#if arr3[i]=='#'
if arr3[i]==" " || arr3[i]=="#" || arr3[i]=="#" || arr3[i]=="{" || arr3[i]=="}" || arr3[i]=="(" || arr3[i]==")" || arr3[i]=="[" || arr3[i]=="]" || arr3[i]=="." || arr3[i]==";" || arr3[i]=="," || arr3[i]=="%" || arr3[i]=="&" || arr3[i]=="*" || arr3[i]=="!" || arr3[i]=="?" || arr3[i]=="$" || arr3[i]=="^" || arr3[i]==":" || arr3[i]=="-" || arr3[i]=="/"
count=count+1
puts count
arr3 && arr3[i]=""
end
end
end
temp_st_two=arr3 && arr3.join
final_st_two=temp_st_two.gsub(/\s+/, "").downcase
puts final_st_two
puts "..............the ajax string"
return final_st_two
end
end
My view file is:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(document).ready(function(){
$("input").keyup(function(){
var box = document.getElementById("tags");
document.getElementById("abc").innerHTML = box.value;
$.getScript('/employees/new?pt=' + encodeURIComponent(box.value))
});
});
$(function() {
var availableTags=<%= #firstname_array.inspect.html_safe %>;
availableTags.toString();
document.getElementById("aaa").innerHTML = availableTags;
// document.getElementById("abc").innerHTML = availableTags;
$( "#tags" ).autocomplete({
source: availableTags
});
});
</script>
</head>
<body>
<div class="ui-widget">
<hr>
<%= form_for #emp do |f| %>
Firstname: <%= f.text_field :firstname, id: 'tags' %></br></br>
<%= f.submit %>
<%end%>
<hr>
<h5><%=#msg%></h5>
<h3>Display all employee information</h3></br>
<% if !#emps.blank? %>
<% for item in #emps %>
<%= item.firstname %> </br>
<%end%>
<%else%>
<%end%>
</div>
<div id="abc"></div>
<div id="aaa"></div>
</body>
</html>

Related

Dynamically insert content for a full text user search with JS and Rails

I have a search input-field and I want to display content dynamically depending on what the User types in it.
The Database hast 1,5k slots and I can allready search by giving a parameter
?search_for=SOMETHING_TO_SEARCH_FOR
where SOMETHING_TO_SEARCH_FOR is just a string. It does a full text search over the database and gives me the results.
I would like to replace the search results with the current shown elements inside
<div class = 'slots-container' id = 'dynamic'>...</div>
index.html.erb
<div class = "index-body">
<%= link_to 'home', root_path, id: 'home', hidden: true %>
<div class = "search_bar" id = 'search'>
<input type="text" placeholder="Search..">
</div>
<div id = 'slots'>
<div class = 'slots-container' id = 'dynamic'>
<%= render #slots %>
</div>
</div>
<%= will_paginate #slots, hidden: true %>
</div>
index.js.erb
appends the next elements to the div with the id: dynamic and removes the .pagination div which is included by will_paginate statement if we have no more pages so that my script for loading more pages gets a null reference
$('#dynamic').append('<%= j render #slots %>');
<% unless #slots.next_page %>
$('.pagination').remove();
<% end %>
main.js
Loads a new page if User is only 100px away from the end of the document,
with the url: next_page from the link with the .next class
var ready = true;
$( document ).on('turbolinks:load', function() {
$("img").lazyload();
document.onscroll = function(){loadNextPage()};
})
function loadNextPage(){
var window_top = $(window).scrollTop();
var doc_height = $(document).height();
var window_height = $(window).height();
var window_bottom = window_top + window_height;
var should_scroll = doc_height - window_bottom < 100;
var next_page = $('.next_page').attr('href');
if (ready && should_scroll && next_page) {
ready = false;
$.getScript(next_page).done(function() {
$("img").lazyload();
ready = true;
});
}
}
function loadSearch(){
var root_page = $('#home').attr('href');
...
}
As you see my loadSearch() function should set the param search_for and append it to my root_page url and my index.js.erb should replace the current content of the document with the search results and also being able to still do infinite scrolling feature.
I think the controller is of no interest jsut be sure that #slots has the right paginated slot elements that needs to be drawn
I solved it now as follows:
index.html.erb
<div class = "index-body">
<%= link_to 'home', root_path, id: 'home', hidden: true %>
<div class = "search-bar">
<input class = "search-input" type="text"
placeholder="Search..."
id = "search-input">
</div>
<div id = 'slots-container'>
<div class = 'slots-container' id = 'slots'>
<%= render #slots %>
<%= will_paginate #slots, hidden: true,id: "paginate" %>
</div>
</div>
</div>
index.js.erb
#identical_search indicates that last search result is the same as the current one so dont do anything
<% unless #identical_search %>
if (dirty) {
dirty = false;
$('#slots').empty();
}
$('#slots').append('<%= j render #slots %>');
<% if #slots.next_page %>
if(document.getElementById("paginate") === null)
$('#slots').append('<%= j will_paginate #slots, hidden: true, id: "paginate" %>');
$('#paginate').replaceWith('<%= j will_paginate #slots, hidden: true, id: "paginate" %>');
<% else %>
$('#paginate').remove();
<% end %>
<% end %>
main.js
var documentLoaded = false;
var dirty = false;
var pending = false;
var loadSearchTimer = null;
$( document ).on('turbolinks:load', function() {
...
documentLoaded = true;
document.getElementById("search-input").addEventListener("input", startTimerForUserInput);
})
...
function startTimerForUserInput(){
if (loadSearchTimer !==null)
clearTimeout(loadSearchTimer);
loadSearchTimer = setTimeout(loadSearch, 300);
}
function loadSearch(){
if (documentLoaded){
documentLoaded = false;
dirty=true;
var search_input = document.getElementById("search-input");
var search_for = search_input.value;
var root_page = $('#home').attr('href');
if(search_for && search_for !== '')
root_page += "?search_for=" + search_for;
$.getScript(root_page).done(function() {
$("img").lazyload();
documentLoaded = true;
if(pending){
pending = false;
loadSearch();
}
});
}
else
pending = true;
}
In main.js I use a Timer to only search 300 ms after last user input to limit the calls so that it doesnt search after every input. When the getScript returns success I am checking if a search request was submitted while the current request was processed to send a new request via pending variable.
dirty is set to true when the user search so that the index.js.erb knows to empty out the div containing the elements.
This runs smooth and I like it how it is.
I hope this will help someone in the future...
If it helps to udnerstand the whole picture, here is the controller:
class SlotsController < ApplicationController
require 'will_paginate/array'
##last_search_content = nil
def index
#identical_search = false
#hashtags = Hashtag.all
if params[:search_for]
search_str = params[:search_for].gsub(/\s\s+/, ' ').strip
#slots = Slot.where("LOWER(slot_name) LIKE LOWER('%#{search_str}%') ")
if ##last_search_content.to_set == #slots.to_set && (params[:page] == nil || params[:page] == 1)
#identical_search = true
end
elsif params[:hashtags]
#slots = slotsWithAtLeastOneOfThose(params[:hashtags])
else
#slots = Slot.all
end
##last_search_content = #slots
unless #identical_search
#slots = #slots.paginate(page: params[:page])
end
respond_to do |format|
format.html
format.js
end
end
def show
#slot = Slot.find(params[:id])
end
private
def slotsWithAtLeastOneOfThose(hashtags)
slots=[]
hashtags.split(' ').each do |h|
slots += Slot.joins(:hashtags).where("hashtags.value LIKE ?", "%#{h}%")
end
return slots.uniq
end
end

How to call a JS function from rails form submit

I want to call a JS function when a button in my Rails form is clicked. The function is defined in the .js.erb file found below.
When I click the button, Chrome's JS console throws the following error:
Uncaught ReferenceError: logTime is not defined
I know this means it can't find the function, but I don't see why. Especially since I added <%= javascript_include_tag "track.js.erb" %> to the file. Any ideas?
Apologies up-front, but my Google-fu yielded no results.
_track_time_form.html.erb
<div id="countdown-timer"></div>
<div id="playback-button">►</div>
<div id="track-time-form">
<%= form_for #project, :url => { :action => "log_time" }, remote: true do |p| %>
<ul>
<li><%= p.label :project, "Project:"%><br>
<%= p.collection_select(:id, current_user.projects, :id, :name) %></li>
<%= p.hidden_field :time_logged, :value => 0 %> <!-- value set by script in log_time.js.erb -->
<li><%= p.submit "Log time", id: "log-time-button", :onclick => "logTime()" %></li>
</ul>
<% end %>
</div>
The function the handler is calling can be found here:
track.js.erb
//initialise form
timeTrackingForm = window.open("", "", "height=700,width=500");
$(timeTrackingForm.document.body).html("<%= j render( :partial => 'track_time_form' ) %>");
//assign variables
var timer = $("#countdown-timer", $(timeTrackingForm.document));
var playbackControls = $("#playback-button", $(timeTrackingForm.document));
var form = $("#track-time-form", $(timeTrackingForm.document));
var formUl = $("#track-time-form ul", $(timeTrackingForm.document));
var formLi = $("#track-time-form li", $(timeTrackingForm.document));
var logTimeButton = $("#log-time-button", $(timeTrackingForm.document));
var timerPaused;
//initialise timer
$(timeTrackingForm.document).ready(function(){
initialiseTimer();
style();
$(playbackControls).click(function() {
playOrPause();
});
});
function initialiseTimer() {
$(timer).timer({
format: '%H:%M:%S'
});
$(timer).timer('pause');
timerPaused = true;
}
function style() {
$(timer).css({'color':'black','font-size':'50px', 'margin':'auto', 'width':'180px'});
$(playbackControls).css({'color':'#290052', 'font-size':'50px', 'margin':'auto', 'width':'55px'});
$(form).css({'width':'300px','margin':'auto'});
$(formUl).css({'list-style-type':'none'});
$(formLi).css({'margin':'0 0 25px 0','font-sizeL':'18px','font-family':'Arial'});
$(logTimeButton).css({'width':'180px','font-size':'18px','background-color':'green','color':'white','margin-top':'15px'});
}
function playOrPause() {
if (timerPaused == true) {
$(timer).timer('resume');
timerPaused = false;
}
else {
$(timer).timer('pause')
timerPaused = true;
}
}
function logTime() {
$(timer).timer('pause');
var secondsTracked = $(timer).data('seconds');
$('input:hidden').val(secondsTracked);
$('#countdown-timer').timer('reset');
}
For any future readers interested in the solution, here's how I got around the issue (huge thanks to the helpful commenters above).
I added an event listener to the form in track.js.erb, which is triggered when the button is clicked (but before the form actually submits and sends data to the controller). Here it is:
var actual_form = $("#new_project", $(timeTrackingForm.document));
$(actual_form).submit(function(){
$(timer).timer('pause');
timerPaused = true;
var secondsTracked = $(timer).data('seconds');
$(hidden).val(secondsTracked);
resetTimerDisplay();
});

How to select all from multiple kaminari pages

I am using Kaminari for paging in my rails application. I need to select all for items on the current page or every page. The current page is rather simple bundle how can I select all the items on other pages.
file_items_controller.rb
def index
account = Account.includes(:credentials).find params[:account_id]
#page = page_param.to_i
#tab = 'Files'
#sort_by = sort_by
#credential = if params[:credential_id].blank?
account.credentials.first || nil
else
account.credentials.find(params[:credential_id])
end
return unless #credential
file_items = FileItem.file_item_list(#credential.root_folder, sort_by)
#total_count = file_items.count
#max_per_page = file_items.count <= 15 ? 'all' : max_per_page.to_i
file_items_scope = Kaminari.paginate_array(file_items.select(&:file?), total_count: file_items.count).page(page_param)
#file_items = if max_per_page == 'all'
file_items_scope.per(file_items.count) || []
else
file_items_scope.per(max_per_page) || []
end
end
file_items.js
$('a.select-all-current').click(function(e){
e.preventDefault();
$('input:not(:checked)').each(function(_, element){
$(element).click();
});
});
$('a.select-all-files').click(function(e){
e.preventDefault();
$('a.select-all-current').click();
});
index.html.slim
...
.row
ul.file-list
- #file_items.each do |file_item|
li.row.file-item
.col-lg-9
p.label
= "#{file_item[:path]}/#{file_item[:name]}"
p.file-size
= "#{number_to_human_size(file_item[:size]).downcase} | "
.col-lg-1.pull-right
= check_box_tag "file_id_#{file_item[:id]}", file_item[:id], false, class: 'file-box'
...
This example assumes ActiveRecord but you should be able to adapt it to your situation:
class ItemsController < ApplicationController
def index
#items = if params[:per_page] == 'all'
Item.all
else
Item.page( params[:page] ).per( params[:per_page] )
end
end
end

Accessing specific member of an ArrayList using Javascript

So, I have a table in a jsp page which shows the data fetched from a database via an ArrayList forwarded to the page. Each row of the table has a radio button corressponding to it. Now, I would like to access the elements in the row (the ArrayList's members on the selection of the corresponding radio button and then click of an 'edit' button)
Any thoughts as to how to achieve this would be very much appreciated. Here's my code for a bit intro.
<%
ArrayList<requestbean> reqjsp = new ArrayList<requestbean>();
reqjsp = (ArrayList<requestbean>) (request.getAttribute("reqdb"));
%>
<script type ="text/javascript">
function x() {
var ele = document.getElementsByName('reqradio');
var i = ele.length;
for ( var j = 0; j < i; j++ ) {
if ( ele[j].checked ) {
document.getElementById("edireq").disabled = false;
alert('request ' + ( j + 1 ) + ' selected');
//Here is where the functionality is desired to access reqjsp.get(j)
}
}
}
</script>
<input type="button" name="edireq" id="edireq" onclick="x()" value="Edit Request">
These are a few columns in my table.
<%
for ( int i = 0; i < reqjsp.size(); i++ ) {
%>
<tr>
<td> <input type="radio" name="reqradio" id="req<%=(i+1) %>"></td>
<td><%= reqjsp.get(i).getRequestid() %></td>
<td><%= reqjsp.get(i).getRequestor() %></td>
<td><%= reqjsp.get(i).getApprover() %></td>
</tr>
<%} %>
You could generate a JavaScript array with JSP code and then access this generated variable in your JavaScript. But you would not be able to change anything in the underlying Java object this way:
<script type ="text/javascript">
<%
ArrayList<requestbean> reqjsp = new ArrayList<requestbean>();
reqjsp = (ArrayList<requestbean>) (request.getAttribute("reqdb"));
%>
var myJsArray = new Array();
<%
for ( int i = 0; i < reqjsp.size(); i++ ) {
%>
myJsArray.push('<%= reqjsp.get(i) %>');
<%
}
%>
// JavaScript code to access the myJsArray array
</script>
The JSP code will generate this kind of code:
<script type ="text/javascript">
var myJsArray = new Array();
myJsArray.push('value1');
myJsArray.push('value2');
myJsArray.push('value3');
// JavaScript code to access the myJsArray array
</script>

Get the selected option/value of a dynamic select field in RAILS

I have here a select_field with a dynamic ID.
Why dynamic? Because I used a nested field/form.
<%= f.select :category_id, Category.all.map{ |c| [c.code, c.id] }, {prompt:""},{class:"cat-code"} %>
I have here a JS code that simply gets the dynamic id per select field.
<%= javascript_tag do %>
$(function() {
$(".cat-code").change(function(){
var getID = this.id;
var value = $("getID").val()
alert(value);
if (value == "1"){
$(".div1").show();
$(".div2").hide();
}
else if (value == "2"){
$(".div1").hide();
$(".div2").show();
}
});
});
<% end %>
I can get the id using..
alert(getID);
But getting the selected value turns undefined which results the show() and hide() divs for not working too.
Any workarounds will be appreciated. Thanks.
var value = $("#" + getID).val()
var element = $(this);
var value = element.val()
Thank you guys, already solved this using.
$(".cat-code").change(function(){
var getID = this.id;
var value = document.getElementById(this.id).value;
console.log(getID + "with a value of" + value);
if (value == ){
$(".div1").show();
$(".div2").hide();
}
else if (value == "2"){
$(".div1").hide();
$(".div2").show();
}
});

Categories

Resources