set value to devise form value with Javascript - javascript

I have this makeid function which returns a random string of 10 characters
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 10; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
I want to manually put this string to my devise form like this :
<div class="user_field">
<div class="email">`enter code here`
<%= f.label :email %><br />
</div>
<%= f.email_field :email, autofocus: true, autocomplete: "email" , value: <script>makeid();</script>%>
</div>
Any thoughts??

Rewrite your makeid function as a ruby method, and put it into app/helpers/application_helper.rb
def makeid
(('A'..'Z').to_a + ('a'..'z').to_a + (0..9).to_a).sample(10).join()
end
Then you can call that helper in your templates:
<div class="user_field">
<div class="email">`enter code here`
<%= f.label :email %><br />
</div>
<%= f.email_field :email, autofocus: true, autocomplete: "email" , value: makeid() %>
</div>

Related

How to convert object to list in javascript?

I need to convert this object into list in expressJS view (using EJS):
{https://ae01.alicdn.com/kf/HTB12Xa4ipGWBuNjy0Fbq6z4sXXa3/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg,https://ae01.alicdn.com/kf/HTB10xfciv9TBuNjy1zbq6xpepXaG/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg,https://ae01.alicdn.com/kf/HTB13AHqcfiSBuNkSnhJq6zDcpXav/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg}
I've tried :
<% const xx = result.data[0].galleryimages.replace('{',"['").replace('}',"']").split(',') %>
<% for (let j=0; j<xx.length; j++) { %>
<%= xx[j]%>
<% } %>
but it returns :
['https://ae01.alicdn.com/kf/HTB12Xa4ipGWBuNjy0Fbq6z4sXXa3/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg https://ae01.alicdn.com/kf/HTB10xfciv9TBuNjy1zbq6xpepXaG/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg https://ae01.alicdn.com/kf/HTB13AHqcfiSBuNkSnhJq6zDcpXav/Mickey-Mouse-Microwave-Glove-Potholder-Bakeware-Blue-and-White-100-Cotton-Oven-Mitts-and-Potholder-mat.jpg']
What you posted is not an object, it's a string - try:
const xx = result.data[0].galleryimages.replace(/[{}]/, '').split(',')
problem solved
<% let xx = result.data[0].galleryimages.slice(1,-1).split(",") %>
<% for (let j=0; j<xx.length; j++) { %>
<% let ha = xx[j].slice(1,-1); %>
<img src=<%= ha.replace("'","") %> width="10%"/>
<% } %>

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 multiplay two text_field and display in another text_field without submitting in Rails(using jQuery or Javascript)

Hi I am trying to mulitiplay two text_field(input) value and display it in another text_field(input) in Rails
for example like in jquery we do like this please test it http://jsfiddle.net/qw5xM/
I want this thing in rails how to do that, what i am missing here
my form is bellow
<%= form_for #fills, url: { action: "show"}, method: :get do |f| %>
//updated code
<div class="row text-center row-create" style="margin-left: 0%">
<div class="pull-right col-create" style="margin-right: 0%; border-radius: 50%;">
<div class="col-xs-1 col-sm-1">
<%= f.button "+" , class: 'btn btn-default bg-red', style: 'border-radius:50%' %>
</div>
</div>
// till here
<div class="col-xs-2 col-sm-2">
<div class="form-group has-feedback">
<%= f.hidden_field :price, value: #price_log.price %>
<%= f.text_field :quantity, value: 1, required: true, class:'form-control', id: 'quantiy', placeholder: 'Quantity' %>
</div>
</div>
<div class="col-xs-2 col-sm-2">
<div class="form-group has-feedback">
<%= f.text_field :amount, value: :total_price , class:'form-control', placeholder: 'Amount', id: 'total_price' %>
</div>
</div>
<% end %>
and my jquery code is
$('text_field[name="quantity"]').keyup(function() {
var a = $('hidden_field[name="price"]').val();
var b = $(this).val();
$('text_field[name="total_price"]').val(a * b);
});
Updated Question
creating the new fields by clicking plus button
<script type="text/javascript">
$(document).on('click','.col-create',function(e){
e.preventDefault();
var cont = $(this).closest('.row-create').clone();
$(cont).find(".col-create").remove().end().insertAfter($(this).closest('.row-create'));
e.preventDefault()*;
});
On click plus button it should be create new field same as above and the multiplying script should work separately for each new fields.
I want to create new one and save all new created values also.
But this one saving only first value.
please any help must appriceated
Thanks a lot
you can also write
$('input[name="textbox2"]').keyup(function() {
var first = $('input[name="textbox1"]').val();
var second = $(this).val();
$('input[name="textbox3"]').val(first * second);
});
Its always good practice to select an attribute with id or class instead of name attribute,
provide a id to hidden field price to get its value easily, rest all are good so far and try this: -
<%= f.hidden_field :price, value: #price_log.price, id: "price" %>
$('#quantiy').on('keyup', function(e) {
var price = parseFloat($('#price').val());
var quantity = $(this).val();
$('#total_price').val((price * quantity).toFixed(2));
});
You need to change your text_field into input because you cannot use attribute selector with class or id. With attribute selector you can do with following code.
$('input[name="quantity"]').keyup(function() {
var a = $('input[name="price"]').val();
var b = $(this).val();
$('input[name="total_price"]').val(a * b);
});
And with selector you need . for class and # for id. Here is the working code.
$("#quantity").keyup(function() {
var a = $("#price").val();
var b = $(this).val();
$("#total_price").val(a * b);
});
You should use parseInt or parseFloat like this:
$('.text_field[name="quantity"]').keyup(function() {
var a = $('hidden_field[name="price"]').val();
var b = $(this).val();
$('.text_field[name="total_price"]').val(parseFloat(a) * parseFloat(b));
});
Change the below code
$('text_field[name="quantity"]').keyup(function() {
var a = $('hidden_field[name="price"]').val();
var b = $(this).val();
$('text_field[name="total_price"]').val(a * b);
});
to
$('input[name="quantity"]').keyup(function() {
var a = $('input[name="price"]').val();
var b = $('input[name="quantity"]').val();
$('text_field[name="total_price"]').val(a * b);
});
Before writing code, inspect in your browser.
Also, there is something to consider in your logic.
If you enter '3' in first textbox and then enter '4' in second textbox, then the third box will get '12' as value.
But if you again, go to first textbox and change it to '5', it will not print '15'.
So you can change the code as below
$('input[name="quantity"]').keyup(function() {
var a = $('input[name="price"]').val();
var b = $('input[name="quantity"]').val();
$('text_field[name="total_price"]').val(a * b);
});
function multiply() {
var a = $('input[name="price"]').val();
var b = $(this).val();
$('text_field[name="total_price"]').val(a * b);
});
$('input[name="quantity"]').keyup(multiply);
$('input[name="price"]').keyup(multiply);

function to get position in two arrays

In javascript or EJS
Hi, I have the followings arrays
ID totales: 76,76,76,78,17,37,30,177,30,177,1,2,3,5,64,30,31,35,36,17,17,37,76,1,2,3,5,35,37,33,30,31,35,36,17,17,37,17,37,35,37,80,35,37,1,2,3,5,1,2,3,5,1,2,3,5,81,76,30,31,35,36,17,1,2,3,5,81,0,76,64,61,21,22,18,24,19,26,35,37,17,37,17,37,17,37
Porcantes Totales: 70,70,100,100,70,70,85,60,100,100,66.7,100,100,50,100,70,80,70,50,90,90,40,100,66.7,100,100,50,70,90,60,30,90,60,50,60,80,40,60,60,40,60,11.1,80,80,66.7,100,100,50,66.7,100,100,50,66.7,100,100,50,0,100,40,60,40,50,70,66.7,100,100,50,100,60,0,0,50,70,70,100,70,80,60,80,80,20,50,50,70,60,50
ID propios: 30,177
I need to get the position in "ID totales" where are "ID propios" that is to say 30 and 177,
with the purpose of get the same position in "Porcantes Totales" and may to make a sum with the values in the position of 30 and position of 177, this by separate parts and store them in a variable
thanks
In javascript or EJS
the code is
result.forEach(function(results){ %>
<%long=(results.category_results.length)
for(i=0; i<long; i++){ %>
<%results.category_results[i].category_id%>
<%listRP.push(results.category_results[i].category_id)%>
<%listResPropio=listRP%>
<br><br><br>
<% } %>
<% }) %>
<%
listR=[]
listP=[]
allResult.forEach(function(allR){ %>
<%long=(allR.category_results.length)
for(i=0; i<long; i++){ %>
<%allR.category_results[i].category_id%>
<%listR.push(allR.category_results[i].category_id)%>
<%listP.push(allR.category_results[i].percentage)%>
<%listaResultados=listR%>
<%listaPorcentajes=listP%>
<% } %>
<% }) %>
<%aaaa = []
var a
var b
%>
ID totales: <%=listaResultados%><br>
Porcantes Totales: <%=listaPorcentajes%><br>
ID propios: <%=listResPropio%><br>
<% for(i=0; i<listaResultados.length; i++){ %>
<% for(a=0; a<listResPropio.length; a++){ %>
<% if(listaResultados[i]==listResPropio[a]){ %>
<% a=listaResultados[i] %>
<%= a %>
<% } %>
<% } %>
<% } %>
This should do the work
var ID_totales = [76,76,76,78,17,37,30,177,30,177,1,2,3,5,64,30,31,35,36,17,17,37,76,1,2,3,5,35,37,33,30,31,35,36,17,17,37,17,37,35,37,80,35,37,1,2,3,5,1,2,3,5,1,2,3,5,81,76,30,31,35,36,17,1,2,3,5,81,0,76,64,61,21,22,18,24,19,26,35,37,17,37,17,37,17,37]
var Porcantes_Totales = [70,70,100,100,70,70,85,60,100,100,66.7,100,100,50,100,70,80,70,50,90,90,40,100,66.7,100,100,50,70,90,60,30,90,60,50,60,80,40,60,60,40,60,11.1,80,80,66.7,100,100,50,66.7,100,100,50,66.7,100,100,50,0,100,40,60,40,50,70,66.7,100,100,50,100,60,0,0,50,70,70,100,70,80,60,80,80,20,50,50,70,60,50]
function ID_propios(ID){
return ID.map(a=>Porcantes_Totales[ID_totales.indexOf(a)]).reduce((a,b)=>a+b)
}
console.log(
ID_propios([30, 177])
)

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();
});

Categories

Resources