Generate .click functions inside for loop - javascript

Inside my for loop that loops through 15 "box" objects, code below:
for (var i = 0; i < boxesLength; i++) {
I'm trying to generate these click events automatically, they used to be like this: (all the way up until 15)
$("#box0").click(function(){
var rw = 462;
var input = $('#rw');
input.val(rw);
var rh = 310;
var input = $('#rh');
input.val(rh);
calculateRectangle();
calculateRectangle2();
});
Right now I am trying to auto-generate these in the for loop by doing this:
$("#box" + i).click(function(){
var rw = allBoxes[i].width;
var input = $('#rw');
input.val(rw);
var rh = allBoxes[i].length;
var input = $('#rh');
input.val(rh);
calculateRectangle();
calculateRectangle2();
});
What am I doing wrong? When I console log "#box" + i I am getting the expected result..

This is an exemple of closures. When you're trying to click one button then your alghorithm will use the last value of i variable which is boxesLength.
To solve this, just use letkeyword.
for (let i = 0; i < boxesLength; i++) {
^^^

Another solution will be like this:
$("#box" + i).click(function(i){
return function(){
var rw = allBoxes[i].width;
var input = $('#rw');
input.val(rw);
var rh = allBoxes[i].length;
var input = $('#rh');
input.val(rh);
calculateRectangle();
calculateRectangle2();
}}(i));

Related

How to get random images from an array and show name of image in alert without repeat of same image using JQUERY

I am developing one project in that i have requirement of get images randomly so i want alert of 9 images every time alert should show random image and it should not repeat but in my case i am getting alert of Repetative image and instead of 4 times alert I am getting 8 alerts, here i want count_time=4 which i have declared in variable below my jquery code to get random image in each alert without repeat.
<script>
//alert shoud get only 4 times because count_time is 4
$("body").on('click','.cell',function(){
var images_var = ["1.jpg", "2.jpg","3.jpg","4.jpg"];
var count_time=4;
var test = [];
var useNumbers = {};
for (i = 1; test.length < count_time; i++) {
var rng = Math.floor((Math.random() * count_time) + 1);
var random = images_var[Math.floor(Math.random()*images_var.length)];
alert(random);
if (!useNumbers[rng]) {
test.push(rng);
useNumbers[rng] = true;
}
}
});
</script>
Finally solved my issue after observing carefully and applying conidtions
<script>
$("body").on('click','.cell',function(){
var images_var = ["1.jpg", "2.jpg","3.jpg","4.jpg"];
var count_time=4;
var test = [];
var img_push=[];
var useNumbers = {};var random_img={};
for (i =1; test.length < count_time; i++) {
var rng = Math.floor((Math.random() * count_time));
var random = images_var[Math.floor(Math.random()*images_var.length)];
if ((!useNumbers[rng]) && (!random_img[random])) {
test.push(rng);
img_push.push(random);
useNumbers[rng] = true;
random_img[random] = true;
alert(random);
}
}
});
</script>

Javascript- Dynamic variable loop

I'm trying to reduce the amount of code I repeat.
Currently I have the below:
var item1H = $(".item-1").height();
var item1W = $(".item-1").height();
$(".item-1 .text").css('margin-left', -item1W/2);
$(".item-1 .text").css('margin-bottom', -item1H/2);
var item2H = $(".item-2").height();
var item2W = $(".item-2").height();
$(".item-2 .text").css('margin-left', -item2W/2);
$(".item-2 .text").css('margin-bottom', -item2H/2);
I'm looking to put this into a for loop where the variable number would count up to whatever number I needed it to stop.
You can make function like this and use whenever you want
toSetMargin(".item-2")
toSetMargin(".item-2")
function toSetMargin(objStr){
var widthTmp = $(objStr + ' .text').height();
var heightTmp = $(objStr + ' .text').height();
obj.css('margin-left', -widthTmp/2);
obj.css('margin-bottom', -heightTmp/2)
}
This code not impact any other code.
You could use $('[class^="item-"]') to get all the elements that have a class that starts with item-, and the loop over them
$('[class^="item-"]').each(function(){
var $elem = $(this);
var item1H = $elem.height();
var item1W = $elem.width();
$elem.find('.text').css({'margin-left': -item1W/2,'margin-bottom':-item1H/2});
});
Ooh boy, one of these problems. This should help (untested):
for(i=1;i<=STOPPING_NUMBER;i++){
window["item"+i+"H"] = $(".item-"+i).height();
window["item"+i+"W"] = $(".item-"+i).width(); //Was height, accident?
$(".item-"+i+" .text").css('margin-left', 0-window["item"+i+"W"]/2); //Hope this works lol
$(".item-"+i+" .text").css('margin-bottom', 0-window["item"+i+"H"]/2);
}
Guessing these lines:
var item1W = $(".item-1").height();
var item2W = $(".item-2").height();
Should have been:
var item1W = $(".item-1").width();
var item2W = $(".item-2").width();
You could do something like:
function setCSS(item,attr,val) {
$(item +" .text").css(attr, (val * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,"margin-left",$(".item-"+ i).width());
setCSS(".item-"+ i,"margin-bottom",$(".item-"+ i).height());
}
Or something less flexible within the function:
function setCSS(item,w,h) {
$(item +" .text").css("margin-left", (w * -1)/2);
$(item +" .text").css("margin-bottom", (h * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,$(".item-"+ i).width()),$(".item-"+ i).height());
}
Something like this should be pretty acceptible in your case, I guess:
for (var i = 1, len = someN; i < len; i++) {
var $item = $('.item-' + i);
$item.find('.text').css({
'margin-left': -$item.width() / 2,
'margin-bottom': -$item.height() / 2
});
}

Run javascript on multiple selected checkboxes

Hello I am currently writing a web application that calculates a number based on what a user has checked.
You can see it here.
If you go to the link you can see that a person will check a checkbox first and enter a value from the dropdown and type 2 values to get an output.
What I need help with is being able to calculate the value for more than one checkbox at a time.
Right now I can only calculate the value for a checkbox one at a time even if multiple are selected. So basically I need help try to figure how to calculate for more than one checkbox at a time.
I was using an if statement inside my javascript file but thats not giving me the result that I want.
Just remove else if statements, change for IF only. But I have to say that's solution its not that scalable, and for a big application could turns into a nightmare.
I recommend you try to use $("input:checked").each(function() {}); if you dont want to store it and just show the values on the client to avoid further problems and bad code. With your line of thought, you'll need everytime make copy and paste those IF's everytime you want to implement new form labels.
$(document).ready(function(){
function check(){
if($('#checkbox1').is(':checked')){
var pokemonCount = parseInt($("#pokecount1").val());
var candyCount = parseInt($("#candycount1").val());
var reqCandy = parseInt($("#dropdown1 :selected").val());
var evolveAmount = 0;
evolveAmount = Math.floor(((candyCount + pokemonCount) - 1) / (reqCandy));
$("#p1").html(evolveAmount);
}
if($('#checkbox2').is(':checked')){
var pokemonCount2 = parseInt($("#pokecount2").val());
var candyCount2 = parseInt($("#candycount2").val());
var reqCandy2 = parseInt($("#dropdown2 :selected").val());
var evolveAmount2 = 0;
evolveAmount2 = Math.floor(((candyCount2 + pokemonCount2) - 1) / (reqCandy2));
$("#p2").html(evolveAmount2);
}
if ($('#checkbox3').is(':checked')){
var pokemonCount3 = parseInt($("#pokecount3").val());
var candyCount3 = parseInt($("#candycount3").val());
var reqCandy3 = parseInt($("#dropdown3 :selected").val());
var evolveAmount3 = 0;
evolveAmount3 = Math.floor(((candyCount3 + pokemonCount3) - 1) / (reqCandy3));
$("#p3").html(evolveAmount3);
}
}
$("#compute").click(function(){
check()
});
});
Just remove Else if to if only
$(document).ready(function(){
function check(){
if($('#checkbox1').is(':checked')){
var pokemonCount = parseInt($("#pokecount1").val());
var candyCount = parseInt($("#candycount1").val());
var reqCandy = parseInt($("#dropdown1 :selected").val());
var evolveAmount = 0;
evolveAmount = Math.floor(((candyCount + pokemonCount) - 1) / (reqCandy));
$("#p1").html(evolveAmount);
}
if($('#checkbox2').is(':checked')){
var pokemonCount2 = parseInt($("#pokecount2").val());
var candyCount2 = parseInt($("#candycount2").val());
var reqCandy2 = parseInt($("#dropdown2 :selected").val());
var evolveAmount2 = 0;
evolveAmount2 = Math.floor(((candyCount2 + pokemonCount2) - 1) / (reqCandy2));
$("#p2").html(evolveAmount2);
}
if ($('#checkbox3').is(':checked')){
var pokemonCount3 = parseInt($("#pokecount3").val());
var candyCount3 = parseInt($("#candycount3").val());
var reqCandy3 = parseInt($("#dropdown3 :selected").val());
var evolveAmount3 = 0;
evolveAmount3 = Math.floor(((candyCount3 + pokemonCount3) - 1) / (reqCandy3));
$("#p3").html(evolveAmount3);
}
}
$("#compute").click(function(){
check()
});
});
You've used elseif, so if the first checkbox is checked then it runs that code and stops. You need a series of if blocks:
if(1.isChecked){
}
if(2.isChecked){
}
You are using else if statements in your code, which means that the code of only one of the 3 if statements can be executed. More info here.
You need to replace them with simple if statements, like this:
$(document).ready(function(){
function check(){
if($('#checkbox1').is(':checked')){
var pokemonCount = parseInt($("#pokecount1").val());
var candyCount = parseInt($("#candycount1").val());
var reqCandy = parseInt($("#dropdown1 :selected").val());
var evolveAmount = 0;
evolveAmount = Math.floor(((candyCount + pokemonCount) - 1) / (reqCandy));
$("#p1").html(evolveAmount);
}
if($('#checkbox2').is(':checked')){
var pokemonCount2 = parseInt($("#pokecount2").val());
var candyCount2 = parseInt($("#candycount2").val());
var reqCandy2 = parseInt($("#dropdown2 :selected").val());
var evolveAmount2 = 0;
evolveAmount2 = Math.floor(((candyCount2 + pokemonCount2) - 1) / (reqCandy2));
$("#p2").html(evolveAmount2);
}
if ($('#checkbox3').is(':checked')){
var pokemonCount3 = parseInt($("#pokecount3").val());
var candyCount3 = parseInt($("#candycount3").val());
var reqCandy3 = parseInt($("#dropdown3 :selected").val());
var evolveAmount3 = 0;
evolveAmount3 = Math.floor(((candyCount3 + pokemonCount3) - 1) / (reqCandy3));
$("#p3").html(evolveAmount3);
}
}
$("#compute").click(function(){
check()
});
});

Accessing Excel's Object Model from Javascript

I have excel as an activeX object in javascript. I seem to be missing something with reards to how to interact with the object model from there. My watch window shows the value of the "Value" property of the range I am trying to pull data from as "undefined" when I try to assign "range.Value" to an array.
Unfortunately I am unable to update the outdated browsers on my machine at work so I cannot upload pictures.
My script:
function open_files(A, B, C)
{
var excel = new ActiveXObject("Excel.Application");
excel.Visible=true;
excel.DisplayAlerts = false;
var wbA = excel.Workbooks.Open(document.getElementById(A).value);
var wbB = excel.Workbooks.Open(document.getElementById(B).value);
var wbC = excel.Workbooks.Open(document.getElementById(C).value);
excel.EnableEvents = false;
excel.ScreenUpdating = false;
excel.Calculation = -4135 //xlCalculationManual enumeration;
var wb_collection = [wbA, wbB, wbC];
excel.Application.Run("'" + wbA.name + "'" + '!update_links');
var CLIN_list = [wbA.Sheets("Control Form").Range("B62:B141").value(1)]
for (i = 0; i = CLIN_list.length; i++)
{
if (CLIN_list(i) > 0)
{
var CLIN_list_count = i
}
}
var decrement_range_start = wbA.Sheets("Fee & Decrement Table").Range("AJ14")
//for (i = 0; i < 80; i++){
//Sheets("Fee & Decrement Table").Cells(decrement_range_start.column+i
// Model Setup for VBA
wbA.Sheets("CONTROL FORM").Activate
wbA.Sheets("CONTROL FORM").OLEObjects("TextBox21").Object.Text = wbB.fullname
wbA.Sheets("CONTROL FORM").OLEObjects("TextBox22").Object.Text = wbC.fullname
excel.Application.Run("'" + wbA.name + "'" + '!Run_JPO');
I found an answer on another forum. A Range cannot be assigned directly to a js array, it has to be converted. The line below works to fill my CLIN_list variable.
var CLIN_list = new VBArray(wbA.Sheets("Control Form").Range("B62:B141").value).toArray();

Google Apps Script: How to get this code run after UI is closed?

This may seem a very newbie question, but I'm stuck with it. I've got this code to show a check list in a UI and insert the paragraphs of one or more documents into another target document:
var fact_list = [ ["Kennedy Inauguration", "politics", "tZwnNdFNkNklYc3pVUzZINUV4eUtWVWFSVEf"], ["Pericles’ Funeral Oration", "politics", "sdgrewaNkNklYc3pVUzZINUV4eUtW345ufaZ"], ["The Pleasure of Books", "culture", "1234rFszdgrfYc3pVUzZINUV4eU43usacd"], ["I Am The First Accused (Nelson Mandela)", "law", "34rsgadOsidjSZIswjadi95uydnfklsdks"] ];
function showList() {
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i][0]);
var hidden = app.createHidden('checkbox_value_'+i, fact_list[i]);
panel.add(checkbox).add(hidden);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
var numberOfItems = e.parameter.checkbox_total;
var itemsSelected = [];
// for each item, if it is checked / selected, add it to itemsSelected
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
itemsSelected.push(e.parameter['checkbox_value_'+i]);
}
}
var app = UiApp.getActiveApplication();
ScriptProperties.setProperties({'theses': itemsSelected}, true);
app.close();
return app;
}
function importTheses(targetDocId, thesesId, thesesType) { // adapted from Serge insas
var targetDoc = DocumentApp.openById(targetDocId);
var targetDocParagraphs = targetDoc.getParagraphs();
var targetDocElements = targetDocParagraphs.getNumChildren();
var thesesDoc = DocumentApp.openById(thesesId);
var thesesParagraphs = thesesDoc.getParagraphs();
var thesesElements = thesesDoc.getNumChildren();
var eltargetDoc=[];
var elTheses=[];
for( var j = 0; j < targetDocElements; ++j ) {
var targetDocElement = targetDoc.getChild(j);
// Logger.log(j + " : " + type);// to see targetDoc's content
eltargetDoc[j]=targetDocElement.getText();
if(el[j]== thesesType){
for( var k = 0; k < thesesParagraphs-1; ++k ) {
var thesesElement = thesesDoc.getChild(k);
elTheses[k] = thesesDoc.getText();
targetDoc.insertParagraph(j, elTheses[k]);
}
}
}
}
But when I call these functions inside my main function, I got a red message (in my language): service not available: Docs and, after the UI from showList() is closed, nothing more happens with my code (but I wanted the main functions continues to run). I call these functions this way:
if (theses == 1){
showList();
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
}
showURL(docName, link); // Shows document name and link in UI
So, how can I fix that? How can I get the code run until the line showURL(docName, link);?
showList();
This function creates only Ui.
You are setting the script properties only in the Server Handler which executes on the click of submit button. Since then:
ScriptProperties.getProperty('theses');
will hold nothing. So you need to call these lines:
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
Inside server handler or put them inside a method and call the method from the server Handler.

Categories

Resources