I'm trying to make a mini-calculator for my form. My html-form is based on data-prototype, so it renders an unlimited amount of forms with 2 inputs : date and duration.
This inputs are rendered with ID-s like loan_charge_0_date , loan_charge_1_duration ; next one : loan_charge_1_date, loan_charge_1_duration` and so on.
I already wrote a code that with regex creates an array with all ids of date, and an another array with all ids of durations. So, when I click on + button that adds a new form, my dateIdsArray = [loan_charge_0_date] and durationIdArray = [loan_charge_0_duration]. When I click it again, it pushed one more element to each array, the loan_charge_1_date in dateIdsArray and loan_charge_1_duration to durationIdsArray`.
Now, I need to each pair (form) to bind a function with 2 parameters like date.value and duration.value ... and in this function to make my endingDateCalculator.
In this order, I made some easy statements that first...concat this 2 arrays, and after that make them as a pair ... so, result array is a bidimensional array :
pairValuesArray = [
[loan_charge_0_date, loan_charge_0_duration],
[loan_charge_1_date, loan_charge_1_duration],
[loan_charge_2_date, loan_charge_2_duration]
];
How can I append an function to every this pair, so when I onkeyup the duration of input, it will call the endingDateCalculator function with 2 parameters (this.date, this.duration) and perform calculations?
I tried smth like :
pairArray.forEach( x => document.getElementById(x).setAttribute('onkeyup', 'endingDateCalculator(this.value, this.value);'));
but it show me ... can not run setAttribute to a null :/
My entire script is here :
<script>
var bodyText = document.getElementsByClassName('panel-group')[0].innerHTML;
var durationIds = bodyText.match(/id="(.*duration)"/g);
var durationIdArray = durationIds.map(y => y = y.split('\"')[1]);
var dateIds = bodyText.match(/id="(.*date)"/g);
var dateIdArray = dateIds.map(x => x = x.split('\"')[1]);
var concatArray = new Array();
for (var i = 0; i < durationIds.length; i++) {
concatArray.push(dateIdArray[i]);
concatArray.push(durationIdArray[i]);
}
var pairArray = new Array ();
var i,j,temparray,chunk = 2;
for (i=0,j=concatArray.length; i<j; i+=chunk) {
temparray = concatArray.slice(i,i+chunk);
pairArray.push(temparray);
}
console.debug(pairArray);
pairArray.forEach( x => document.getElementById(x).setAttribute('onkeyup', 'endingDateCalculator(this.value, this.value);'));
//dateIdArray.forEach( x => document.getElementById(x).setAttribute('onkeyup', 'endingDateCalculator(this.value);'));
function endingDateCalculator(valueOfDate, valueOfDuration) {
alert(valueOfDate + valueOfDuration);
}
</script>
Related
I'm trying to get the values of 4 columns (N, P, R, T) and store them in one column.
Also, I thought of doing the same thing but for rows ( So like concatenate 4 cells in 4 columns and store them in a variable via a for loop). I think I would start doung that when I figure the columns first.
for example:-
so here i want to store the values of each column and store them in one variable and then sum all 4 values to get the value of all four columns which is (14+12+11+7) which is 44.
I wrote this code but it doesn't seem to me like its storing the values.
function percentage(){
const thisSheet = SpreadsheetApp.openByUrl(THIS).getSheetByName('WP_Data');
var range=thisSheet.getRangeList(['N3:N', 'P3:P', 'R3:R', 'T3:T']);
var rangeN= thisSheet.getRange("N3:N");
var valueN=rangeN.getValues();
var rangeP= thisSheet.getRange("P3:P");
var valueP=rangeP.getValues();
var rangeR= thisSheet.getRange("R3:R");
var valueR=rangeR.getValues();
var rangeT= thisSheet.getRange("T3:T");
var valueT=rangeT.getValues();
console.log()
var val =valueN + valueP + valueR + valueT;
}
would really appreciate the help.
If you need more info please let me know
This might do the works for you
function percentage(){
const thisSheet = SpreadsheetApp.openByUrl(THIS).getSheetByName('WP_Data');
var range=ss.getRangeList(['N3:N', 'P3:P', 'R3:R', 'T3:T']);
var rangeN= ss.getRange("N3:N");
var valueN=rangeN.getValues();
var rangeP= ss.getRange("P3:P");
var valueP=rangeP.getValues();
var rangeR= ss.getRange("R3:R");
var valueR=rangeR.getValues();
var rangeT= ss.getRange("T3:T");
var valueT=rangeT.getValues();
//you can use concat or creat a new array to store these values.
const array = valueN.concat(valueP,valueR,valueT).flat();
//then use array.reduce function to sum all the items in the array.
const sum = array.reduce((value,sum) => value+sum)
// you will get the out put as 44
console.log(sum)
}
Is that what you asking for?
const string = array.toString();
console.log(string)
Something like this?
function percentage(){
const thisSheet = SpreadsheetApp.openByUrl(THIS).getSheetByName('WP_Data');
var values = thisSheet.getRange(3,14,thisSheet.getLastRow()-2,7).getValues(); // N3:T??
var results = [];
var i = 0;
for( i=0; i<values.length; i++ ) {
results.push([values[i][0]+values[i][2]+values[i][4]+values[i][6]]); // index 0 = column N, etc.
}
// don't know what you want to do with it but you could use setValues(results)
thisSheet.getRange(??,??,results.length,1).setValues(results);
}
So I have combinations of names to tasks in a table where several different task are associated with the same name. But I need to put the task into one cell next to the associated name. Using JavaScript. Heres what I got;
function Unique(){
var ss = SpreadsheetApp.openById("ID");
var dataRaw = ss.getSheetByName("Sheet1");
var destination = ss.getSheetByName("Sheet2");
var names2 = dataRaw.getRange(2,10,dataRaw.getLastRow(),1).getValues();
var names1 = names2.flat(1);
var names = names1;
//var names = ["name1","name1","name2", "name3", "name3"];
var uniqueNames = []; //empty array
var count = 0;
var found = false;
for (i = 0; i < names.length; i++){
for(y =0; y < uniqueNames.length; y++){
if(names[i] == uniqueNames[y]){
found = true;
}
}
count++;
if(count == 1 && found == false){
uniqueNames.push(names[i]);
}
count = 0;
found = false;
}
/* can I use this??? maybe it's not needed
var uniqueNames2 = uniqueNames.map(function(obj) {
return Object.keys(obj).sort().map(function(key) {
return obj[key];
});
});
*/
var dest = destination.getRange(1,2,uniqueNames.length,uniqueNames[0].length);
dest.setValue(uniqueNames); //maybe this is not needed
console.log(uniqueNames[0].length);
}
My approach is to;
take in names and output the unique names so there is no doubles
once i have unique names use some type of for() loop or map() function to find tasks and pair with names? maybe im wrong?
and then setValues() to the range that I need.
The problems that I'm running into are that My Unique() function needs a regular array not array of arrays, which i fix using
array.flat(1)
but then to paste the values javaScript needs the array or arrays to be just an array which I COULD fix with
Object.keys(obj).sort().map(function(key)
in the commented out section? to turn an array of arrays back into an array... but then my "width" is not consistent for my array, columns, and I get the error that my range is not the same number of columns as my data. I feel that this is fairly simple and I am grossly over complicating things. Any help would be great thank you. My google sheet below https://docs.google.com/spreadsheets/d/1rbz52kkzhVAGX21MUVoexzPUvWxjk-RCw-5PrRLoBBc/edit?usp=sharing
I believe your goal as follows.
You want to achieve the following conversion.
From
Task Names
Task 1 name one
Task 2 name one
Task 3 name one
Task 4 name one
Task 5 name one
Task 1 name two
Task 2 name two
Task 3 name two
Task 1 name three
Task 2 name three
Task 3 name three
To
task names
Task 1
Task 2
Task 3
Task 4
Task 5 Name one
Task 1
Task 2
Task 3 name two
Task 1
Task 2
Task 3 name three
For this, how about this answer?
Modification points:
In your script, for example, about var names2 = dataRaw.getRange(2,10,dataRaw.getLastRow(),1).getValues();, I thought that you might misunderstand the row and column for getRange. And, in this case, only one row Names of column "B" on "Sheet1" is retrieved. The row of Task is not retrieved in your script. And also, from dest.setValue(uniqueNames);, you might misuderstood setValue and setValues.
When above points are reflected to your script, it becomes as follows.
Modified script:
In this modification, at name2, the values from the cells "B2:B12" are retrieved, and the unique values are retrieved using your script. Then, the values from the cells "A2:B12" are retrieved, and the values for putting to Spreadsheet are created using the created unique values. Then, the created values are put to the Spreadsheet.
Modified script:
function Unique_org2(){
var ss = SpreadsheetApp.openById("ID");
var dataRaw = ss.getSheetByName("Sheet1");
var destination = ss.getSheetByName("Sheet2");
var names2 = dataRaw.getRange(2,2,dataRaw.getLastRow()-1,1).getValues(); // <--- Modified
var names1 = names2.flat(1);
var names = names1;
var uniqueNames = [];
var count = 0;
var found = false;
for (i = 0; i < names.length; i++){
for(y =0; y < uniqueNames.length; y++){
if(names[i] == uniqueNames[y]){
found = true;
}
}
count++;
if(count == 1 && found == false){
uniqueNames.push(names[i]);
}
count = 0;
found = false;
}
// --- I added below script.
var values = dataRaw.getRange(2, 1, dataRaw.getLastRow() - 1, 2).getValues(); // Added
var uniqueNames = uniqueNames.reduce((ar, e) => {
var temp = "";
values.forEach(([a, b]) => {
if (e == b) temp += a + "\n";
});
ar.push([temp.trim(), e]);
return ar;
}, []);
// ---
var dest = destination.getRange(2,1,uniqueNames.length,uniqueNames[0].length); // <--- Modified
dest.setValues(uniqueNames); // <--- Modified
}
Other pattern:
In this pattern, in order to achieve your goal, I would like to propose the other sample script of following flow. This flow might be able to reduce the process cost from above modified script.
Retrieve values from the cells "A2:B12" of "Sheet1".
Create an object from the retrieved values.
Convert the object to an array for putting to Spreadsheet.
Put the values to Spreadsheet to the destination sheet.
Sample script:
function Unique(){
var ss = SpreadsheetApp.openById("ID");
var dataRaw = ss.getSheetByName("Sheet1");
var destination = ss.getSheetByName("Sheet2");
// 1. Retrieve values from the cells "A2:B12" of "Sheet1".
const values = dataRaw.getRange(2, 1, dataRaw.getLastRow() - 1, 2).getValues();
// 2. Create an object from the retrieved values.
const obj = values.reduce((o, [a, b]) => Object.assign(o, {[b]: (o[b] ? o[b] + a : a) + "\n"}), {});
// 3. Convert the object to an array for putting to Spreadsheet.
const res = Object.entries(obj).map(([k, v]) => [v.trim(), k]);
// 4. Put the values to Spreadsheet to the destination sheet.
destination.getRange(2, 1, res.length, res[0].length).setValues(res);
}
References:
getRange(row, column, numRows, numColumns)
setValue(value)
setValues(values)
I am new to JS.
I set up a Saved Search in NetSuite that gives us the image fields (containing URLs) of our items. I am now setting up a script in NS which tests these fields to see what item fields return 404 (i.e. need to be fixed).
My question is, how to set up function imageURLValidator to iterate through the field values of function searchItems?
Below is my start to the process but obviously has much incorrect syntax.
function imageURLValidator() {
var searchResults = searchItems('inventoryitem','customsearch529');
var url = '';
var item = '';
var field = '';
//insert loop here to iterate over items in searchResults array
//loop through items
for (var i = 0, i > searchResults[inventoryObject].length, i++) {
item = searchResults.[inventoryObject].[i];
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
function searchItems(type, searchid) {
//defining some useful variables that we will use later
var inventoryArray = [];
var count = 0;
//loading the saved search, replace the id with the id of the search you would like to use
var inventoryItemSearch = nlapiLoadSearch(type, searchid);
//run the search
var inventoryItemResults = inventoryItemSearch.runSearch();
//returns a js array of the various columns specified in the saved search
var columns = inventoryItemResults.getColumns();
//use a do...while loop to iterate through all of the search results and read what we need into one single js object
do {
//remember the first time through the loop count starts at 0
var results = inventoryItemResults.getResults(count, count + 1000.0);
//we will now increment the count variable by the number of results, it is now no longer 0 but (assuming there are more than 1000 total results) will be 1000
count = count + results.length;
//now for each item row that we are on we will loop through the columns and copy them to the inventoryObject js object
for (var i=0; i<results.length; i++){
var inventoryObject = {};
for (var j=0; j<columns.length; j++){
inventoryObject[columns[j].getLabel()] = results[i].getValue(columns[j]);
}
//then we add the inventoryObject to the overall list of inventory items, called inventoryArray
inventoryArray.push(inventoryObject);
}
//we do all of this so long as the while condition is true. Here we are assuming that if the [number of results]/1000 has no remainder then there are no more results
} while (results.length != 0 && count != 0 && count % 1000 == 0);
return inventoryArray;
}
function checkURL(url) {
var response = nlapiRequestURL(url);
var code = response.getCode();
return code;
}
function createErrorRecord(code,item,field) {
if (code == 404){
//create error record
var errorRecord = nlapiCreateRecord('customrecord_item_url_error');
errorRecord.setFieldValue('custrecord_url_error_item', item);
errorRecord.setFieldValue('custrecord_url_error_image_field', field);
}
}
Here I can see searchResults variable will be empty while looping. As your call to searchItems function is async. Which will take some time to execute because I guess it will fetch data from API. By the time it returns value, your loop also would have bee executed. You can test this by putting an alert(searchResults.length) or console.log(searchResults.length). For that you need to use callback function
Also even if you get the results in searchResults. The loop you are doing is wrong. The array you will get is like [{},{},{}] i.e. array of objects.
To access you'll need
for (var i = 0, i > searchResults.length, i++) {
var inventoryObject = searchResults[i] // your inventoryObject
for(var key in inventoryObject){
item = inventoryObject[key]; // here you will get each item from inventoryObject
//loop through fields in item
for (var f = 2, f > item.length, f++) {
field = item[f];
//check URL via item field's value
var code = checkURL(item[field].getvalue([field]));
//generate error based on code variable
createErrorRecord(code,item,field)
}
}
}
And yes welcome to Javascript
Can someone show me the javascript I need to use to dynamically create a two dimensional Javascript Array like below?
desired array contents:
[["test1","test2","test3","test4","test5"],["test6","test7","test8","test9","test10"]]
current invalid output from alert(outterArray):
"test6","test7","test8","test9","test10","test6","test7","test8","test9","test10"
JavaScript code:
var outterArray = new Array();
var innerArray = new Array();
var outterCount=0;
$something.each(function () {
var innerCount = 0;//should reset the inner array and overwrite previous values?
$something.somethingElse.each(function () {
innerArray[innerCount] = $(this).text();
innerCount++;
}
outterArray[outterCount] = innerArray;
outterCount++;
}
alert(outterArray);
This is pretty cut and dry, just set up a nested loop:
var count = 1;
var twoDimensionalArray =[];
for (var i=0;i<2;i++)
{
var data = [];
for (var j=0;j<5;j++)
{
data.push("Test" + count);
count++;
}
twoDimensionalArray.push(data);
}
It sounds like you want to map the array of text for each $something element into an outer jagged array. If so then try the following
var outterArray = [];
$something.each(function () {
var innerArray = [];
$(this).somethingElse.each(function () {
innerArray.push($(this).text());
});
outterArray.push(innerArray);
});
alert(outterArray);
A more flexible approach is to use raw objects, they are used in a similar way than dictionaries. Dynamically expendables and with more options to define the index (as string).
Here you have an example:
var myArray = {};
myArray[12]="banana";
myArray["superman"]=123;
myArray[13]={}; //here another dimension is created
myArray[13][55]="This is the second dimension";
You don't need to keep track of array lengths yourself; the runtime maintains the ".length" property for you. On top of that, there's the .push() method to add an element to the end of an array.
// ...
innerArray.push($(this).text());
// ...
outerArray.push(innerArray);
To make a new array, just use []:
innerArray = []; // new array for this row
Also "outer" has only one "t" :-)
[SEE IT IN ACTION ON JSFIDDLE] If that $something variable is a jQuery search, you can use .map() function like this:
var outterArray = [];
var outterArray = $('.something').map(function() {
// find .somethingElse inside current element
return [$(this).find('.somethingElse').map(function() {
return $(this).text();
}).get()]; // return an array of texts ['text1', 'text2','text3']
}).get(); // use .get() to get values only, as .map() normally returns jQuery wrapped array
// notice that this alert text1,text2,text3,text4,text5,text6
alert(outterArray);
// even when the array is two dimensional as you can do this:
alert(outterArray[0]);
alert(outterArray[1]);
HTML:
<div class="something">
<span class="somethingElse">test1</span>
<span class="somethingElse">test2</span>
<span class="somethingElse">test3</span>
</div>
<div class="something">
<span class="somethingElse">test4</span>
<span class="somethingElse">test5</span>
<span class="somethingElse">test6</span>
</div>
Here you can see it working in a jsFiddle with your expected result: http://jsfiddle.net/gPKKG/2/
I had a similar issue recently while working on a Google Spreadsheet and came up with an answer similar to BrianV's:
// 1st nest to handle number of columns I'm formatting, 2nd nest to build 2d array
for (var i = 1; i <= 2; i++) {
tmpRange = sheet.getRange(Row + 1, Col + i, numCells2Format); // pass/fail cells
var d2Arr = [];
for (var j = 0; j < numCells2Format; j++) {
// 1st column of cells I'm formatting
if ( 1 == i) {
d2Arr[j] = ["center"];
// 2nd column of cells I'm formatting
} else if ( 2 == i ) {
d2Arr[j] = ["left"];
}
}
tmpRange.setHorizontalAlignments( d2Arr );
}
So, basically, I had to make the assignment d2Arr[index]=["some string"] in order to build the multidimensional array I was looking for. Since the number of cells I wanted to format can change from sheet to sheet, I wanted it generalized. The case I was working out required a 15-dimension array. Assigning a 1-D array to elements in a 1-D array ended up making the 15-D array I needed.
you can use Array.apply
Array.apply(0, Array(ARRAY_SIZE)).map((row, rowIndex) => {
return Array.apply(0, Array(ARRAY_SIZE)).map((column, columnIndex) => {
return null;
});
});`
i have a array with numbers. i need that array value to be generated once i click on the button, while i click on the button i need to get the value random wise from the array, but the value should not be repeated.
ex, if i get a 2 from out of 5, then i should not get the 2 again. for this i wrote this function, but the values are repeating... any idea?
var ar = [0,1,2,3,4,5];
var ran = Math.floor(Math.random()*ar.length);
ar.splice(ran,1);
alert(ar.splice);
the array values should not be removed. because if i click the button again, i need to get the values like before.
i did my work like this : but the rand values are repeating, any one can correct this to get unrepeatable values to get?
$(document).ready(function(){
var myArray = [1,2,3,4,5];
var mySize = 5;
x = 0;
while(mySize>=1){
var rand = Math.floor(Math.random()*mySize);
mySize--;
alert(rand);
}
})
You need your array to be in an outer scope for this like:
(function(){
var ar = [0,1,2,3,4,5];
document.getElementById('thebutton').onclick = function(){
alert(ar.splice(Math.floor(Math.random()*ar.length), 1));
};
})();
JSFiddle Example
If you create your array inside the onclick function then you are just recreating the entire array every time the button is clicked.
Take a look at this demo. In this it randomizes the array values and will repeat only after all the values are utilized.
Demo
Based on the update in your question here it is take a look.
http://jsfiddle.net/MbkwK/2/
var ar = [0, 1, 2, 3, 4, 5];
document.getElementById('thebutton').onclick = function() {
var shuffle = [];
var copyarr = ar.slice(0);
var arlength = copyarr.length;
for (i = 0; i < arlength; i++) {
shuffle.push(copyarr.splice(Math.floor(Math.random() * copyarr.length), 1));
}
alert(shuffle.join(","));
};
Working demo - http://jsfiddle.net/ipr101/qLSud/1/