logic in setFormat to not roundup the values - google-apps-script

I created a range using offset and setting the format for the range
I did that using below code
a1_range = Sheet1.getRange("D43");
var a4_range = a1_range.offset(0,6);
a4_range = a4_range.offset(0,1,15,6);
a4_range.setBackground("#e6e6e6").setBorder(true, true, true, true, true, true);
a4_range.setNumberFormat("$#");
The setNumberFormat is setting is write as I want , but the problem is when user enters the data, it is rounding up the value as shown in the picture.
However, to not round the values, I did this
a4_range.setNumberFormat("$#, ##0.000000");
This works but has extra trailing zeroes which I do not want as below,
What I want is when user comes and enters 56.768 in that range, the value should be exactly $56.768 and NOT 56.768000 and NOT have it round off to any decimal places.
Similarly, if the user enters 34.3 then it should be $34.3 and if user enters 8.98945 it should be $8.98945
How do I achieve this?

Try this:
a4_range.setNumberFormat("$0.#######");

Related

Input for currency not treating 0 like other numbers after decimal

I'm make a react application that takes an input that should be shown to two decimal places. When the default input has a one number after the decimal, it should add a second number with a 0 after it. It also lets me add infinite amounts of "0"s, but caps any other number at 2 decimal places.
Two different problems pictured:
Case 1.
This is how the input looks when first loaded. The preferred display would be 1.60 (two decimal places)
Case 2.
Current behavior allows the user to add infinite 0s (any other number it caps at 2 decimal places). Expected behavior should cap all numbers including 0s at 2 decimal places.
function ProductMaterial() {
const [name, setName] = useState("");
function handleChange(e) {
let val = e.target.value;
if (val.includes(".") && val.split(".")[1].length > 2) {
}
else {
setName(parseFloat(val));
setMaterialState(parseFloat(val));
}
}
return (
<div className="input-group-sm col-xs-2 material input-group">
<div className="input-group-prepend">
<span className="input-group-text">$</span>
</div>
<input
className="form-control"
type="number"
min="0.00"
onChange={handleChange}
value={product.material}
/>
</div>
);
}
Here is the code for setMaterialState. It changes the product.material value, and then calls setMaterial() in a useEffect() function. The setMaterial() takes the id of the product, and the new material value and saves it to state.
function setMaterialState(newMaterial) {
product.material = newMaterial;
}
useEffect(() => {
setMaterial(product.id, product.material);
}, [product.material]);
I know that the issue here is that on first load nothing is triggering the onChange() function. I've tried setting value={product.material} to value={product.material.toFixed(2)} but it makes it difficult to fix the input. Is there a good way to initialize it before, maybe using a UseEffect() statement? And on top of this I'm not sure why the 0s can be added indefinitely.
Update:
The first problem with the leading 0s was solved by using the onKeyPress= answer suggested by Photonic.
However, I'm still struggling on the forcing it to be two decimal places when there is a 0 at the end problem. I'm realizing that the issue with not starting doing 1.60 is due to it being converted to a float value and not being a string. I tried doing a UseEffect() [] and force it to go to 2 decimal places with product.material.toFixed(); as well as modify the data to start with being 1.60, but it seems like the only way to force the two decimal places is keeping it as a string or converting it to a string by using product.material.toFixed(2). The value in the input value={product.material} need to be a number to correctly execute calculations and collect user input. I'm not sure what the best solution for this is.
I dont know how you are initializing the first load but you can use UseEffect() to fix the decimal place issue like you mentioned.
For the infinite decimal places...
onChange is an event that is already happen, you might want to try changing from onChange to onKeyDown or onKeyPress and in your code you can add e.preventDefault() to stop number from being entered
if (val.includes(".") && val.split(".")[1].length > 2) {
e.preventDefault()
}
If you want to call a function when the 'component did mount' you can use
useEffect(yourFunction(){}, [])

Value Calculation issue in Google web HTML App

I have created an HTML web app in google script this works like a calculator, This app works fine if I add the input in descending order however if I skip the order and update in put data numbers randomly in any column then I am not getting the output properly
Example:- update the numbers in box number 4 and 5 then update in box number 1 you will find the differences in total numbers
Please refer the attached sheet for detailed script
Project Name- Project Proposal Form
$("#rTpe1").keyup(function(e){
$("#rFor1").val(this.value * $("#PerHourRate1").val());
$("#rFor3").val( Number($("#rFor1").val()) +Number($("#rFor2").val()))
});
$("#rTpe2").keyup(function(e){
$("#rFor2").val(this.value * $("#PerHourRate2").val());
$("#rFor3").val( Number($("#rFor1").val()) + Number($("#rFor2").val()))
});
$("#rTpe12").keyup(function(e){
$("#rFor12").val(this.value * $("#PerHourRate3").val());
$("#rFor3").val( Number($("#rFor1").val()) + Number($("#rFor2").val())+ Number($("#rFor12").val()))
});
$("#rTpe13").keyup(function(e){
$("#rFor13").val(this.value * $("#PerHourRate4").val());
$("#rFor3").val( Number($("#rFor1").val()) + Number($("#rFor2").val())+ Number($("#rFor12").val())+ Number($("#rFor13").val()))
});
I could be wrong, but I think that's the main culprit:
If your work your way top to bottom, the output in '#rFor3' is not affected. For example, if you enter values in the first field ('#rTpe1'), this statement
Number($("#rFor2").val()))
will evaluate to '0' because '#rFor2' probably contains an empty string at this point and Number("") will get you a zero. Because all subsequent input fields reference the results of previous calculations ('rTpe2' references 'rFor1', 'rTpe12' references both 'rFor1' and 'rFor2', etc), the sum will come out as correct.
Now consider the reverse scenario. For simplicity, let's make all your rates equal to 1. If you enter the value of '5' into 'rTpe12', the value of 'rFor3' will be
Number("") + Number("") + Number(5*1) == 5; //the first two inputs will contain empty strings at this point
The output of '#rFor3' would be 5. If you go up a step and enter the value of '2' into 'rTpe2', the value of the 'rFor3' output will change to
Number("") + Number(2*1) == 2; the first input will contain an empty string.
The code is not easy to understand, so even if this solution doesn't work for you, consider caching your DOM elements to improve performance and make your code more readable. Currently, you are using jQuery selectors to search the DOM over and over again, which is a serious performance drag. You could also store your calculated value as a variable and simply add values to it instead of recalculating on each input. For example
$('document').ready(function(){
var total = 0;
var input1 = $('#input1');
var input2 = $('#input1');
var input3 = $('#input1');
var output = $('#output');
input1.keyup(function(e){
var value = Number(this.value);
sum += value;
output.val(sum);
});
});

Flex Number.toFixed not giving expected result

I have a function that gets a numeric value (as Object) and returns a well formatted representation of that number. Because we can get very small numbers, in the process we use the Number object of flex. this is part of the code:
var numericValue:Number = Number(value.toString());
var fixed:String = numericValue.toFixed(precision);
This is the problem: there are situations that the numeric value is in the form of
5.684341886080802e-14
because we want to represent these numbers as 0 we use the above code. In this specific case, where precision is 0 we get an odd result
Initial Values:
value = 5.684341886080802e-14
percision = 0
Operation on values:
var numericValue:Number = Number(value.toString());
var fixed:String = numericValue.toFixed(precision);
Result:
fix = "1."
Why is this?
(BTW - on other numbers in the representataion of X.XXXXXXe-YY with percision bigger than 0 we get the correct result of 0)
This is a bug in Flash Player (FP-5141). It has been around for quite a while. The bug report says it is fixed, but it is not as of Flash Player 11.5.

validation functions in google apps script is not working properly

1.Textbox:
While using .validateNotNumber(TextBox),the TextBox is accepting alphanumeric, which shld nt be the case, as i want to have only NAME inside a text box n nt 'abc1234', it shld accept only 'abcd'. also if the textbox handles NUMBERS only using keyuphandler, it shld only accept '1234' n not 'a1234', which is the current behaviour now. It accepts 'a1234'. meaning, the first character is nt validated properly, if we enter 'a', it does nt validate, bt if we enter'a1234', it validates correctly after the first digit, i.e, it throws err only after the i/p of 2nd character in the text box area of a NUMBER type!
function doGet()
{
var app = UiApp.createApplication();
var panel = app.createVerticalPanel();
var grid = app.createGrid(11, 10).setId('maingrid');
var nameLabel = app.createLabel("Name:");
var nameTextBox = app.createTextBox().setName('name').setId('name');
var nameRequiredLabel = app.createLabel("*").setId('namerequired').setStyleAttribute("color", "red");
var requiredFieldLabel = app.createLabel("*-Required Field").setId('requiredfield').setStyleAttribute("color", "red");
grid.setWidget(0, 0, nameLabel).setWidget(0, 1, nameTextBox).setWidget(0, 2, nameRequiredLabel)
.setWidget(9, 2,requiredFieldLabel);
var invalidText=app.createClientHandler().validateNumber(nameTextBox)
.forTargets(nameTextBox).setStyleAttribute("color", "red")
.forTargets(nameRequiredLabel).setText('Please Enter a Valid Name.').setStyleAttribute("color", "red").setVisible(true);
var validText=app.createClientHandler().validateNotNumber(nameTextBox)
.forTargets(nameTextBox).setStyleAttribute("color","black")
.forTargets(nameRequiredLabel).setText('*').setStyleAttribute("color", "red").setVisible(true);
nameTextBox.addKeyUpHandler(invalidText).addKeyUpHandler(validText);
panel.add(grid);
app.add(panel);
return app;
}
Note: I used .validateInteger(TextBox) and .validateNotInteger(TextBox) also, But its too giving the same o/p as above(alphanumeric).
2.DateBox:
It shld accept only DATES format n shld nt be possible to enter any other characters after the DATE is picked.
Fr eg. If i select a DATE '14-08-2012', it shld nt accept any other characters beyond this length, like '14-08-2012abc123', literally there shld be a method to validate/restrict the field, if it's any REAL DATE format n nt just a DATE+TEXT. Accidentally, the user may enter any unwanted text in the DATE box, which we may need to avoid! We may need a '.validateDateLength()' to handle this issue!
3.Drop Down box:
in any given drop box, the option 'SELECT' will b the first option to intimate us to select the option required from the drop down list
I used .validateMatches("SELECT") and .validateNotMatches("SELECT"), to check if any option is selected by the user or not, which means i want to ensure the user has selected something from the drop down box n NT just left tht option UNSELECTED. Bt, it doesn't seem to validate the Matches.
4.Check Box,Radiobutton:
Fr these 2 controls, i just want to ensure tht the user has SELECTED any of my RADIOS or any of my CHECKBOXES, if those particular RADIO's are nt selected by the user, the control shld pass an err, saying tht 'PLZ SELECT THE RADIO/CHECK BOX OPTION TO PROCEED FURTHER'. What is the right method to do this?
Eg. script
var valid = app.createClientHandler()
.validateNumber(number)
.validateNotInteger(text)
.validateEmail(email)
.validateNotMatches(listbox, 'select')
.forTargets(submit).setEnabled(true)
.forTargets(number,text,email).setStyleAttribute("color","black")
.forTargets(numberrequired,textrequired,emailrequired).setText('*')
.setStyleAttribute("color","red").setVisible(true);
I used the above code for the 'SUBMIT' Button enable and disable concept, In this itself the ListBox is not validating correctly the 'SELECT' option.
So, basically, I want all these validation to function properly, so tht I cn make my 'SUBMIT/SAVE' ENABLED, until all my above controls are checked/validated, which ensure tht the user has entered/selected all the options properly & is in the required format to proceed to the SUBMIT page.
Hopefully, I m clear, plz dont hesitate to ask me if I m wrong/unclear somewhere!
Please guide me,
Thanks & Regards,
chocka.
I suspect addKeyPressHandler is the wrong type of handler - there is a focus style handler
But yes, the code does look more or less correct.

List Box enable/disable one column

Access 2007: Is it possible to enable/disable one column in a List Box on a form. For example: Say you have 2 columns A,B - If Me.A = title Then Me.B.Enabled = True Else Me.B.Enabled = False.
If so, where would it go? On Got Focus, On Click??
Thanks
I'm not sure what you mean by disable, but you can hide a column by adjusting the ColumnWidth.
So if you wanted to hide column2:
Me.MyListBox.ColumnWidths = (1 in;0;1 in)
And to hide column1:
Me.MyListBox.ColumnWidths = (0;1 in;1 in)