How to get modified column in this app script function - javascript

I had a function working qute well but I can not modify something. I need this cell to add new values once I select a new option in the drop down. This only for the 9th and 11th columns, but is not working well.
function onEdit(e){
addValue(e);
}
function addValue(e) {
// Vairables
var ws = "HR Support";
var identifiedBy = 9;
var impDimension = 11;
// Get modified column
var col = e.range.getColumn();
if( col === identifiedBy || col === impDimension || e.oldValue == null || e.value == null
&& e.source.getActiveSheet().getName() === ws) return;
e.range.setValue(e.oldValue+", "+e.value);
}

I probably need a little more information but this does something close what I think you're looking for. Let me know what else you need.
function onEdit(e) {
//e.source.toast('entry');
const sh = e.range.getSheet();
if (sh.getName() == "HR Support" && (e.range.columnStart == 9 || e.range.columnStart == 11) && e.range.rowStart > 2) {
//e.source.toast('cond');
e.range.setValue(e.oldValue + ", " + e.value);
}
}
I think maybe you want this:
function onEdit(e) {
e.source.toast('entry');
const sh = e.range.getSheet();
sh.getRange('A1').setValue(JSON.stringify(e));
if (sh.getName() == "HR Support" && (e.range.columnStart == 9 || e.range.columnStart == 11) && e.range.rowStart > 2) {
e.source.toast('cond');
if (!e.hasOwnProperty('oldValue')) {//checks to see if oldValue is a property of event object
e.range.setValue(e.value);
} else {
e.range.setValue(e.oldValue + ", " + e.value);
}
}
}

Related

What is the best way to deal with multiple else if statements to increase speed in Google Apps Script?

I have a function that is supposed to unhide certain columns, but only if other filters that relate to the columns are not in use. Because there are 4 other filters that it needs to check to see if they are in use (either 'true' or 'false'), there are 16 possibilities that the function needs to run through.
I've used else if statements to accomplish this and it does work, but it is incredibly slow. I was wondering if there is a more appropriate way to deal with all the possible options that is faster.
This is the code I currently have (sorry if I've shown too much, not sure how much I need to include):
function Unfilter(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var numCols = sheet.getRange(1,3).getValue(); //gets the number of columns to loop through
var xRow = sheet.getRange(1,5).getValue() + 16; //gets the target row to run the blank check on
// check filter statuses
var nameShow = sheet.getRange(1,1).getValue();
var statusShow = sheet.getRange(2,1).getValue();
var dateShow = sheet.getRange(3,1).getValue();
var evidenceShow = sheet.getRange(4,1).getValue();
//loop through all target columns and unhide all columns that are not filtered
for (var i=10; i<=numCols; i++) {
if (sheet.getRange(xRow,i).getValue() == "") {
var catType = sheet.getRange(16,i).getValue();
if (nameShow == true && statusShow == true && dateShow == true && evidenceShow == true) {
sheet.showColumns(i)
} else if (nameShow == false && statusShow == true && dateShow == true && evidenceShow == true) {
if(catType !== "Name") {
sheet.showColumns(i);
}
} else if (nameShow == false && statusShow == false && dateShow == true && evidenceShow == true){
if (catType == "Date" || catType == "Evidence") {
sheet.showColumns(i);
}
} else if (nameShow == false && statusShow == true && dateShow == false && evidenceShow == true) {
if (catType == "Status" || catType == "Evidence") {
sheet.showColumns(i);
}
} else if (nameShow == false && statusShow == true && dateShow == true & evidenceShow == false){
if (catType == "Status"|| catType == "Date") {
sheet.showColumns(i);
}
} else if (nameShow == false && statusShow == false && dateShow == false && evidenceShow == true){
if (catType == "Evidence") {
sheet.showColumns(i);
}
} else if (nameShow == false && statusShow == false && dateShow == true && evidenceShow == false){
if (catType == "Date") {
sheet.showColumns(i);
}
}
//...etc for all 9 remaining possibilities
}
}
}
Even if you can't speed up showColumns() function you can significantly accelerate your script if you will use getValue() or getValues() as few as it possible. For example here you invoke these functions more than 7 times on the same sheet with static data. It's far from best practices:
You could use getValues() just once to get all data from the sheet and analyze the array instead. It would be much faster. getValue() / getValues() are quite slow and intentionally limited functions.
For example:
var data = sheet.getRange(1,1,10,10).getValues(); // get the array
var numCols = data[0][2];
var xRow = data[0][4] + 16;
var nameShow = data[0][0];
var statusShow = data[1][0];
var dateShow = data[2][0];
var evidenceShow = data[3][0];
// etc
I think it will be about five seconds faster already.
And it will even more faster if you change getRange(xRow,i).getValue() to data[xRow-1][i-1] in the loop.

How to make function simple

Maybe delete some logical Operators, make a "Check function "?
Or connect some logical in one piece?
// Function
function getTicketPrice(childNumber,adultNumber){
if (childNumber > 2 && adultNumber > 2) {
return "-";
}
if (childNumber == 2 && adultNumber == 3) {
return "-";
}
if (childNumber == 3 && adultNumber == 2) {
return "-";
}
var sheet = SpreadsheetApp.openByUrl(url).getSheetByName("Ticket");
var row = getTicketPriceChild(childNumber, sheet);
var col = getTicketPriceAdult(adultNumber, sheet);
if (row >-1 && col === undefined) {
return "-";
}
if (row === undefined && col >-1) {
return "-";
}
var value = sheet.getRange(row, col).getValue();
if(value > 1){
return value;
} else {
return '-';
}
}
Something like this:
function getTicketPrice(childNumber, adultNumber) {
if ((childNumber > 2 && adultNumber > 2) || (childNumber == 2 && adultNumber == 3) || (childNumber == 3 && adultNumber == 2))
return "-";
const sheet = SpreadsheetApp.openByUrl(url).getSheetByName('Ticket');
const row = getTicketPriceChild(childNumber, sheet);
const col = getTicketPriceAdult(adultNumber, sheet);
if ((row > -1 && col === undefined) || (row === undefined && col > -1))
return "-";
const value = sheet.getRange(row, col).getValue();
return value > 1 ? value : "-"
}

Making a date mask react with javascript: If i press simultaneous numbers i lost the mask

I'm trying to make a mask react date dd/mm/yyyy to a custom date input.
If i press the keys slow, the mask is setted correct dd/mm/yyyy, but supposing i press the numbers rapid, my mask is breaking
This is my component:
<DateInput
name="date"
placeholder="Data"
value={this.props.data}
dateFormat="DD/MM/YYYY"
onChange={this.props.changeDataTarefa}
animation="none"
onKeyUp={() => this.props.changeDataTarefaMask(this.fixDatePattern(this.props.data))}/>
this is my functions:
fixDatePattern(currDate) {
var currentDate = currDate;
if (currentDate){
var currentLength = currentDate.length;
var lastNumberEntered = currentDate[currentLength - 1];
}
if (!this.isNumber(lastNumberEntered) && currentDate) {
return currentDate.substring(0, currentLength - 1);
}
if (currentLength > 10) {
return currentDate.substring(0, 10);
}
let dateCountTracker = 0
if (currentLength == 1 && currentDate > 1) {
var transformedDate = "0" + currentDate + '/';
dateCountTracker = 2;
currentLength = transformedDate.length;
return transformedDate;
} else if (currentLength == 4 && currentDate[3] > 3) {
let transformedDate = currentDate.substring(0, 3) + "0" + currentDate[3] + '/';
dateCountTracker = 5;
currentLength = transformedDate.length;
return transformedDate;
} else if (currentLength == 2 && (dateCountTracker != 2 && dateCountTracker != 3)) {
dateCountTracker = currentLength;
return currentDate + '/';
} else if (currentLength == 5 && (dateCountTracker != 5 && dateCountTracker != 6)) {
dateCountTracker = currentLength;
return currentDate + '/';
}
dateCountTracker = currentLength;
return currentDate;
}
isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
Instead of using keyup, use keypress event on input. And you could also use react input mask plugin for same.
You can use below code for key press event and please check working stackblitz demo.
render() {
return (
<div>
<span>Date : </span>
<input type="text" maxLength="10" placeHolder="dd/mm/yyyy" onKeyPress={this.onKeyPress}/>
</div>
)
}
onKeyPress(e){
let input = e.target;
if(e.charCode < 47 || e.charCode > 57) {
e.preventDefault();
}
var len = input.value.length;
if(len !== 1 || len !== 3) {
if(e.charCode == 47) {
e.preventDefault();
}
}
if(len === 2) {
input.value += '/';
}
if(len === 5) {
input.value += '/';
}
}
You could use below react input mask plugins to achieve requirement.
imaskjs and react-input-mask

Input | Get the new value set by a JavaScript function into a Controller public function

I have created a CRUD to edit existing table rows.
One of its input contain already a value="19.00" saved at the creation of the row :
<input type="number" step="1" title="Prix" class="form-control" name="productprice" id="productprice" value="19.00">
I'm overriding the value in my CRUD with a javascript function when the value of a select list is changed by the user, for example if one of the product property is changed and impact the price :
$('#form').on('change', function() {
var d1 = document.getElementById('ordersdetailproducttype_ID').value; // producttypeID
// console.log('producttype ID:', d1);
var d2 = document.getElementById('ordersdetailproductname').value; // productnameID
// console.log('product ID:', d2);
var d3 = document.getElementById('ordersdetaildessertservingID').value; // dessertservingID
// console.log('Servings:', d3);
var pl1 = document.getElementById('ordersdetailID_portion').value; // partyloafportionID
// console.log('pl1:', pl1);
var pl2 = document.getElementById('ordersdetailpartyloafweightID').value; // partyloafweightID
// console.log('pl2:', pl2);
if (d1 == '' && d2 == '' && d3 == '' && pl1 == '' && pl2 == '') { $('#ordersdetailproductprice').val('0.00'); }
else if (d1 == 1 && d2 == 1 && d3 == 1 && pl1 == '' && pl2 == '') { $('#ordersdetailproductprice').val('19.00'); }
else if (d1 == 1 && d2 == 1 && d3 == 2 && pl1 == '' && pl2 == '') { $('#ordersdetailproductprice').val('24.00'); }
...
In this case the user sees the new value (price) into the input,
value which I don't see by inspecting the element structure :
<div class="form-group header-group-0 " id="form-group-productprice" style="display: block;">
<label class="control-label col-sm-2">Prix
</label>
<div class="col-sm-10">
<input type="number" step="1" title="Prix" class="form-control" name="productprice" id="productprice" value="19.00">
<div class="text-danger"></div>
<p class="help-block"></p>
</div>
If I look at the element with the inspector, I can see that the value of the input is still
value="19.00"
I need to retrieve the new value set by my JavaScript function in my controller in order to be able to update accordingly my table row column with a controller public function.
First time I'm confronted with this kind of issue, I have no clue how to solve this. Would appreciate your expertise. Thanks, Marc
When you have a default value for input field, changing it via val() wouldn't impact it.
You need to use attr(), so instead of lines like:
$('#ordersdetailproductprice').val('0.00');
Use:
$('#ordersdetailproductprice').attr('value', '0.00');
And then you can easily fetch the input value to send to your Controller (via AJAX I believe) as:
let value = $('#ordersdetailproductprice').val();
I hope it helps you
SOLUTION AJAX CALL IN JS SCRIPT :
...
else if (d1 == 4 && d2 == 27 && d3 == '' && pl1 == 2 && pl2 == 2) { $('#productprice').val('59.00'); }
else if (d1 == 4 && d2 == 27 && d3 == '' && pl1 == 3 && pl2 == 3) { $('#productprice').val('69.00'); }
else if (d1 == 4 && d2 == 27 && d3 == '' && pl1 == 4 && pl2 == 4) { $('#productprice').val('79.00'); }
else if (d1 == 4 && d2 == 27 && d3 == '' && pl1 == 4 && pl2 == 5) { $('#productprice').val('89.00'); }
var rowID = rowid;
var orderID = $('#orderID').val();
var productprice_new = $('#productprice').val();
console.log(productprice_new,rowID,orderID);
$.ajax({
type: 'post',
url: '/assets/ajax/ajaxupdate.php',
data: {
'rowid' : rowid,
'orderID' : orderID,
'productprice_new' : productprice_new,
},
success: function (data) {
console.log('worked!');
},
error: function (data) {
console.log('Error:', data);
}
})

how can I correct this JavaScript adding function?

I have a form which takes six inputs (there are more but only these matter for now)
original fare
original tax
new fare
new tax
fee
number of guests
when "Calculate" is pressed I use javascript to add original fare
and original tax to get the original total
then I add new fare and new tax to get the new total
now I compare original total to new total
if original total is greater than new total it should use one if several methods to finish doing the math I need and set the results to the display
i was originally testing everything using these values:
original fare = 1000
original tax = 200
new fare = 800
new tax = 200
fee = 150
number of guests = 3
which can bee seen here https://pnrbuilder.com/_popups/exchangeMyPNR_MATH_TEST_2.php
(page only works in chrome)
the above works exactly as expected but when I change the values to:
original fare = 949.83
original tax = 321.18
new fare = 453.91
new tax = 143.91
fee = 150
number of guests = 3
seen here https://pnrbuilder.com/_popups/exchangeMyPNR_MATH_TEST.php
(page only works in chrome)
this test uses the wrong if statement to finish out the rest of the math
I dont understand why this is happening as original total is still > new total so it should use the same method as the first example. I put in alerts to let me know exactly which if statement is being used to do the math and clearly the wrong one is used here but I just cant figure out why.
I know this is convoluted but could someone please help me figure out where my logic goes wrong?
Here's the full function:
function addMe(frm) {
var orBase = Number(frm.box1.value);
var orTax = Number(frm.box2.value);
var nwBase = Number(frm.box3.value);
var nwTax = Number(frm.box4.value);
var fee = Number(frm.fee.value);
var gsts = Number(frm.guests.value);
var fltrd_orBase = orBase * 100;
var fltrd_orTax = orTax * 100;
var fltrd_orTtl = fltrd_orBase + fltrd_orTax;
var orTtl = fltrd_orTtl / 100;
var final_orTtl = orTtl.toFixed(2)
frm.result.value = orTtl.toFixed(2)
var fltrd_nwBase = nwBase * 100;
var fltrd_nwTax = nwTax * 100;
var fltrd_nwTtl = fltrd_nwBase + fltrd_nwTax;
var nwTtl = fltrd_nwTtl / 100;
var final_nwTtl = nwTtl.toFixed(2)
frm.result2.value = nwTtl.toFixed(2)
var e = document.getElementById("residual");
var selectVal = e.options[e.selectedIndex].value;
if (final_orTtl <= final_nwTtl) {
document.getElementById("forfeitTable").style.display="none";
document.getElementById("MCOtable").style.display="none";
var undiff = final_nwTtl - final_orTtl;
var diff =undiff
document.getElementById("differenceDisplay").innerHTML=diff.toFixed(2);
frm.difference.value = diff.toFixed(2);
var ppCost = diff + fee;
frm.pptotal.value = ppCost.toFixed(2);
document.getElementById("ppDisplay").innerHTML=ppCost.toFixed(2);
var ttlCost = ppCost * gsts;
frm.totalcost.value = ttlCost.toFixed(2);
document.getElementById("grandTotalDisplay").innerHTML=ttlCost.toFixed(2);
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 1 was used');
}
}
else if (final_orTtl > final_nwTtl) {
if (selectVal == "residualX" || selectVal == "residualN") {
document.getElementById("MCOtable").style.display="none";
var diff = final_orTtl - final_nwTtl;
var displayDiff = diff* -1;
document.getElementById("differenceDisplay").innerHTML= displayDiff.toFixed(2);
frm.difference.value = displayDiff.toFixed(2);
document.getElementById("forfeitInfo").innerHTML = "Beyond the cost above";
frm.lost.value = diff.toFixed(2);
document.getElementById("ppForfeitedDisplay").innerHTML = diff.toFixed(2);
var ttlfForfeited = diff * gsts;
frm.lostTTL.value = ttlfForfeited.toFixed(2);
document.getElementById("totalForfeitedDisplay").innerHTML=ttlfForfeited.toFixed(2);
var ppCost = fee;
frm.pptotal.value = ppCost.toFixed(2);
document.getElementById("ppDisplay").innerHTML=ppCost;
var ttlCost = fee * gsts;
frm.totalcost.value = ttlCost.toFixed(2);
document.getElementById("grandTotalDisplay").innerHTML=ttlCost;
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
document.getElementById("forfeitTable").style.display="table";
}
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 2.1 was used');
}
}
// this is the method that should be used below
else if (selectVal == "residualA" ) {
document.getElementById("MCOtable").style.display="none";
var diff = final_orTtl - final_nwTtl;
var displayDiff = diff* -1;
document.getElementById("differenceDisplay").innerHTML= displayDiff.toFixed(2);
frm.difference.value = diff.toFixed(2);
if ( diff > fee) {
var residual = diff - fee ;
document.getElementById("forfeitInfo").innerHTML = "No additional cost. However,";
frm.lost.value = residual.toFixed(2);
document.getElementById("ppForfeitedDisplay").innerHTML = residual.toFixed(2);
var ttlfForfeited = residual * gsts;
frm.lostTTL.value = ttlfForfeited.toFixed(2);
document.getElementById("totalForfeitedDisplay").innerHTML=ttlfForfeited.toFixed(2);
//document.getElementById("differenceDisplay").innerHTML=0;
frm.difference.value = diff;
document.getElementById("ppDisplay").innerHTML=0;
document.getElementById("grandTotalDisplay").innerHTML=0;
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
document.getElementById("forfeitTable").style.display="table";
}
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 2.2 was used');
}
}
else {
var remBal = fee - diff ;
var ttlcost = remBal * gsts;
frm.totalcost.value = ttlcost.toFixed(2);
document.getElementById("ppDisplay").innerHTML=remBal.toFixed(2);
document.getElementById("grandTotalDisplay").innerHTML=ttlcost.toFixed(2);
document.getElementById("forfeitTable").style.display="none";
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 2.3 was used');
}
}
}
else if (selectVal == "residualM" ) {
var diff = final_orTtl - final_nwTtl;
var displayDiff = diff* -1;
document.getElementById("differenceDisplay").innerHTML= displayDiff.toFixed(2);
frm.difference.value = displayDiff.toFixed(2);
if (diff > fee) {
var mco = diff - fee ;
document.getElementById("MCOInfo").innerHTML=mco.toFixed(2);
frm.MCOamt.value = mco.toFixed(2);
//document.getElementById("differenceDisplay").innerHTML=diff;
//frm.difference.value = diff* -1;
frm.totalcost.value = 0;
document.getElementById("ppDisplay").innerHTML=0;
document.getElementById("grandTotalDisplay").innerHTML=0;
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
document.getElementById("forfeitTable").style.display="none";
document.getElementById("MCOtable").style.display="table";
}
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 2.4 was used');
}
}
else {
var remBal = fee - diff ;
var ttlcost = remBal * gsts;
frm.totalcost.value = ttlcost.toFixed(2);
document.getElementById("ppDisplay").innerHTML=remBal.toFixed(2);
document.getElementById("grandTotalDisplay").innerHTML=ttlcost.toFixed(2);
document.getElementById("forfeitTable").style.display="none";
document.getElementById("MCOtable").style.display="none";
// this is just for testing to show which method was actually used
if (orBase != "" && orTax != "" && nwBase != "" && nwTax != "" && fee != "" && gsts != "") {
// this is in its own if statement so it doesnt popuop while entering data
alert('if 2.5 was used');
}
}
}
}
var nwTtl = fltrd_nwTtl / 100;
var final_orTtl = orTtl.toFixed(2)
var orTtl = fltrd_orTtl / 100;
var final_orTtl = orTtl.toFixed(2)
if (final_orTtl > final_nwTtl ) {
}
This part seems to be my problem. the if comparison im doing here doesnt seem to like the '.toFixed(2)' that I did above it for some reason. I changed it to:
var nwTtl = fltrd_nwTtl / 100;
var orTtl = fltrd_orTtl / 100;
if (orTtl > nwTtl ) {
}
Im still testing all the other features but this seems to be working as expected so far. I would still love to know why my use of '.toFixed(2)' causes two numbers that are clearly higher vs lower to evaluate to the opposite. and will accept any answer to that part of this question

Categories

Resources