Since I could not make .toFixed(2) to work I designed my own piece of code to add desired decimal digits after the "." by simple joining two strings with + sign.
While Browser.msgBox outputs the 2 strings joined correctly as "1.00",
it seems like getRange.setValue outputs only the first of the 2 strings as "1" :(
function myFunction() {
var ss_calc = SpreadsheetApp.openById("1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ");
var sheet_calc = ss_calc.getSheetByName("Calcs");
var ss_source = SpreadsheetApp.openById("1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ");
var sheet_source = ss_source.getSheetByName("Farmah");
var decDig = ""; var strDec = ""; var impVal = "";
impVal = sheet_source.getRange(12,7).getValue().toString();
if (JSON.stringify(impVal).indexOf(".")>-1)
{ if (JSON.stringify(impVal).split(".")[1].length < 2 )
{
if (JSON.stringify(impVal).split(".")[1].length < 1)
{
decDig = "00";
}
else
{
decDig = "0";
}
}
}
else
{
decDig = ".00";
}
var strDec = impVal.toString() + decDig.toString();
Browser.msgBox(JSON.stringify(impVal).indexOf(".")+ "\\n" +
impVal.toString()+ "\\n" +
decDig+ "\\n" +
strDec);
sheet_calc.getRange(1,1).setValue(strDec);
}
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
What am I missing?
Here are the links to google spreadsheets ( anyone with the link can edit :)
(above code has to be triggered manually by script editor in the first spreadsheet here under):
https://docs.google.com/spreadsheets/d/1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ/edit?usp=sharing
https://docs.google.com/spreadsheets/d/1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ/edit?usp=sharing
You want to put the value of 1.00 to a cell "A1".
If my understanding is correct, how about this modification? I think that the reason of your issue is that the value by putting by setValue() is converted to the number. By this, 1 is shown. In order to put the value as 1.00, I think that there are 3 patterns. Please select one of them for your situation.
Pattern 1:
In this pattern, from your question, the value is put as a string using setNumberFormat("#").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("#").setValue(strDec);
Pattern 2:
In this pattern, from your question, the format of cell is set using setNumberFormat("0.00").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("0.00").setValue(strDec);
Pattern 3:
In this pattern, from the script of your shared Spreadsheet, When decDig is ".00", the format is set.
From:
sheet_calc.getRange(x+6,c).setValue(strDec);
To:
var range = sheet_calc.getRange(x+6,c);
if (decDig) {
range.setNumberFormat("0.00").setValue(strDec); // or setNumberFormat("#")
} else {
range.setValue(strDec);
}
Reference:
setNumberFormat(numberFormat)
If I misunderstood your question and this was not the result you want, I apologize.
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
Google Sheets, as well as other spreadsheet apps, have an automatic data type assignation, so things that look as numbers are converted to Google Sheets number data type, etc.
You could prepend an ' to force that a value be treated as text or you could set the number format in such way that numbers are displayed with two decimals. The cell formatting could be applied in advance, i.e., by using the Google Sheets UI commands or you could use Apps Script to set the format for you.
World!
I'm trying to create a program in Javascript that takes the log of a number typed into an HTML input. Unfortunately i've encountered a problem where it wont accept the string with the .replace().
Its Function:
I.E: When log(10) is calculated, the function should first remove the first 4 char's "log(" next remove the last parenthesis ")" and then take the log of the no. between.
HTML includes style elements, button and input form and an output < DIV >.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
//TESTING CODE
/*
if (inputString.value.startsWith("log(").endsWith(")"))
{
console.log(output.innerHTML = inputString.value.substring(4, 20).replace(")", ""));
}
else
{
output.innerHTML = "false";
}
*/
//Math.log() calc *****DOESNT WORK*****
if (inputString.value.startsWith("log(").endsWith(")"))
{
output.innerHTML = Math.log(inputString.value.replace(")", "").substring(4, 20));
}
else
{
output.innerHTML = inputString.value;
}
event.preventDefault();
}
If someone can give me an effective solution that would be much appreciated.
Thanks,
Syntax
Since Math.log() accepts only number values and you're trying to pass a string to it, you should first parse this value into a float number and then pass it to the log function:
let val = parseFloat(inputString.value.replace(")", "").substring(4, 20));
output.innerHTML = Math.log(val);
I'm guessing I got downvoted for being lazy, so here is the quick info. Gonras got it right relating to what you want to extract, but he forgot to check that what's being input is actually a log.
That's where the regex below comes in handy! I'm matching the field to:
^ start of word, since we want to match the entire field.
log(
([-.\d])) any consecutive sequence () of numbers (\d), -, and '.', represented by the []. The \(...\) makes sure to save this inner part for later.
$ is end of word, see 1.
res will be null if there is no match. Otherwise, res[0] is the entire match (so the entire input field) and res[1] is the first 'capture group', at point 3 - which is presumably the number.
This of course fails for multiple "-" inside, or "." etc... so think it over.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
var res = /^log\(([-.\d]*)\)$/.exec(inputString.value);
if (res)
output.innerHTML = Math.log(res[1]);
else
output.innerHTML = res;
}
document.getElementById("output").innerHTML='start';
calculate()
<div id='output'></div>
<input id='inpstr' value='log(2.71828)'></input>
If I wanted to fix your if to supplement Gonras's solution:
if (inputString.value.startsWith("log(") && inputString.value.endsWith(")"))
Yours fails since startsWith() returns a boolean, which obviously doesn't have a endsWith function.
I would like to be able to change a list of words in my coding, e.g.
var words= {
AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can't be asked }
changed to this format:
var words= {
'AFK': "Away from the keyboard", '4U': "For you", 'B4N': "By for now", 'BBL': "Be back later", 'BDAY': "Birthday", 'CBA': "Can't be asked",
}
without having to change each word into the format manually using HTML/JavaScript. However I understand that this might not be possible, but I thought I'd see if anyone had an I idea on how to do it anyway. From what I read it looks as if I'll have to use Python and a Database, but I don't know anything about python what so ever really so I was hoping (probably vainly) that there is some HTML/JavaScript code that I haven't seen that solves this!
I found a similar question here, but it wasn't really what I wanted as it uses python: [turning data into a list
The thing I want to do is change all words in this format: e.g
AFK Away from the Keyboard
to a format with
'AFK': "Away from the keyboard",
the aim of this code is to translate text abbreviations to real English words which it is already doing, but in order to get a decent amount of words to translate I need to get words in the above format which would take forever if I formated each one individually. here is the rest of the code if that helps:
function replacer() {
var text= document.getElementById("textbox1").value;
for (var modifiers in translationwords){
text = text.replace(new RegExp('\\b' + modifiers + '\\b', 'gi'), translationwords[modifiers]); }
document.getElementById("textbox2").value=text;
document.getElementById("add").onclick= function storage() {
if(!document.cookie) document.cookie = "";
document.cookie = document.cookie +"<li>"+document.getElementById("textbox1").value+ ":"+"</li>";
document.cookie = document.cookie +"<li>" + document.getElementById("textbox2").value+ "</li>";
document.getElementById("array").innerHTML= document.cookie;
}
}
function textdelete(x) {
if (x.value=="ENTER TRANSLATION HERE"){
x.value="";
};
}
Thank You
If your words were in a string to begin with, then it would be arguably possible to translate it into an object the way you want it, but it might not be the most accurate translation.
Since it looks like all the abbreviations are all upper case and without spaces, we can look through the string, and set the all caps/numbers 'words' as properties, with the following string of text as the value. In javascript, something like this would work.
//set words as string
var string = "AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can't be asked";
// create empty dictionary for storage
var dictionary = {};
// use regex to find all abbreviations and store them in an array
var abbreviations = string.match(/[A-Z0-9]+(?![a-z])\w/g);
// returns ["AFK", "4U", "B4N", "BBL", "BDAY", "CBA"]
// use regex to replace all abbreviations with commas...
englishWords = string.replace(/[A-Z0-9]+(?![a-z])\w/g, ',');
// Edit (see below):
englishWords = englishWords.replace(/\W,\W/g,',');
// End edit
// then split string into array based on commas
englishWords = englishWords.split(',').slice(1);
// finally loop over all abbreviations and add them to the dictionary with their meaning.
for(var i = 0; i < abbreviations.length; i++){
dictionary[abbreviations[i]] = englishWords[i];
}
Edit: the above solution still might have white space at the beginning or end of each english string. You can add this line of code just before splitting the string to remove the white space.
englishWords = englishWords.replace(/\W,\W/g,',');
Assuming you have the data as a list in python, or as a string, or that you can get it into that format:
>>> lst = 'AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can\'t be asked'.split()
>>> lst
['AFK', 'Away', 'from', 'the', 'keyboard', '4U', 'For', 'you', 'B4N', 'By', 'for', 'now', 'BBL', 'Be', 'back', 'later', 'BDAY', 'Birthday', 'CBA', "Can't", 'be', 'asked']
Further assuming that the keywords are always in all-uppercase and that the values are never in all uppercase, and that there are no duplicate keys, you can create the following dictionary:
>>> keys = [x for x in lst if x.upper() == x]
>>> {keys[i]:' '.join(lst[lst.index(keys[i]):lst.index(keys[i+1])]) for i in range(len(keys)-1)}
{'BDAY': 'BDAY Birthday', 'BBL': 'BBL Be back later', '4U': '4U For you', 'B4N': 'B4N By for now', 'AFK': 'AFK Away from the keyboard'}
Let's say that this is your list of words:
["AFK","Away","from","the","keyboard","4U","For","you","B4N","By","for","now","BBL","Be","back","later","BDAY","Birthday","CBA","Can't","be","asked"]
Now, we can change that into an object simply by using regular JavaScript without any database or back-end langauge like Python.
var list = ["AFK","Away","from","the","keyboard","4U","For","you","B4N","By","for","now","BBL","Be","back","later","BDAY","Birthday","CBA","Can't","be","asked"] /*What we have*/;
var code = {} /*What we want*/;
var currKey = null /*Our current key*/, hasBeenSet = false /*Whether or not the property at our current key has been set*/;
for (var i = 0; i < words.length; i++) {
//If the current word is an abbreviation...
if (words[i] === words[i].toUpperCase()) {
currKey = words[i]; //We set currKey to it
hasBeenSet = false; //We make hasBeenSet false
}
//Otherwise, if the property at current key has been set, we add on to it.
else if (hasBeenSet) code[currKey] += " "+words[i];
//Otherwise, the property at current key hasn't been set...
else {
code[currKey] = words[i]; //We set the property to the current word
hasBeenSet = true; //We make hasBeenSet true
}
}
code //{ AFK: "Away from the keyboard", 4U: "For you", B4N: "By for now", BBL: "Be back later", BDAY:"Birthday", CBA:"Can't be asked" }
Aanval op Vlemis (499|453) C44
This is what the string looks like. Though it's actually like this: "Aanval op variable (variable) variable
What I want to do is 1: get the coordinates (I already have this), 2 get Vlemis (first variable), get C44 (third variable) and check to see if the string is of this type.
My code:
$("#commands_table tr.nowrap").each(function(){
var text = $(this).find("input[id*='editInput']").val();
var attackername= text.match(/(?=op)[\s|\w]*(?=\()/);
var coordinates = text.match(/\(\d{1,3}\|\d{1,3}\)/);
});
Coordinates works, attackername however doesn't.
Html:
<span id="labelText[6]">Aanval op Vlemis (499|453) C44</span>
You should use one regex to take everything :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/).slice(1);
This builds
["Vlemis", "499", "453", "C44"]
If you're not sure the string is valid, test like this :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/);
if (parts) {
parts = parts.slice(1);
// do things with parts
} else {
// no match, yell at the user
}
I'm struggling with a ExtJS 4.1.1 grid that has editable cells (CellEditing plugin).
A person should be able to type a mathematic formula into the cell and it should generate the result into the field's value. For example: If a user types (320*10)/4 the return should be 800. Or similar if the user types (320m*10cm)/4 the function should strip the non-mathematical characters from the formula and then calculate it.
I was looking to replace (or match) with a RegExp, but I cannot seem to get it to work. It keeps returning NaN and when I do console.log(e.value); it returns only the originalValue and not the value that I need.
I don't have much code to attach:
onGridValidateEdit : function(editor,e,opts) {
var str = e.value.toString();
console.log(str);
var strCalc = str.match(/0-9+-*\/()/g);
console.log(strCalc);
var numCalc = Number(eval(strCalc));
console.log(numCalc);
return numCalc;
},
Which returns: str=321 strCalc=null numCalc=0 when I type 321*2.
Any help appreciated,
GR.
Update:
Based on input by Paul Schroeder, I created this:
onGridValidateEdit : function(editor,e,opts) {
var str = e.record.get(e.field).toString();
var strCalc = str.replace(/[^0-9+*-/()]/g, "");
var numCalc = Number(eval(strCalc));
console.log(typeof numCalc);
console.log(numCalc);
return numCalc;
},
Which calculates the number, but I am unable to print it back to the grid itself. It shows up as "NaN" even though in console it shows typeof=number and value=800.
Final code:
Here's the final code that worked:
onGridValidateEdit : function(editor,e,opts) {
var fldName = e.field;
var str = e.record.get(fldName).toString();
var strCalc = str.replace(/[^0-9+*-/()]/g, "");
var numCalc = Number(eval(strCalc));
e.record.set(fldName,numCalc);
},
Lets break this code down.
onGridValidateEdit : function(editor,e,opts) {
var str = e.value.toString();
What listener is this code being used in? This is very important for us to know, here's how I set up my listeners in the plugin:
listeners: {
edit: function(editor, e){
var record = e.record;
var str = record.get("your data_index of the value");
}
}
Setting it up this way works for me, So lets move on to:
var strCalc = str.match(/0-9+-*\/()/g);
console.log(strCalc);
at which point strCalc=null, this is also correct. str.match returns null because your regex does not match anything in the string. What I think you want to do instead is this:
var strCalc = str.replace(/[^0-9+*-]/g, "");
console.log(strCalc);
This changes it to replace all characters in the string that aren't your equation operators and numbers. After that I think it should work for whole numbers. I think that you may actually want decimal numbers too, but I can't think of the regex for that off the top of my head (the . needs to be escaped somehow), but it should be simple enough to find in a google search.