I have a small menu made with dat.gui JavaScript library. I use different lines with some initial values which are displayed (these initial values are modified during the execution of code).
My issue is, for example, that instead of display a value "15", I would like to display "15.0000". I try to used toFixed(4) function but without success.
Here's the raw (without "toFixed(4)" function) code snippet :
var componentThetaInit = 15;
var componentPhiInit = 15;
var gui = new dat.GUI({
autoplace: false,
width: 350,
height: 9 * 32 - 1
});
var params = {
StartingVector : '',
ComponentVectorTheta : componentThetaInit,
ComponentVectorPhi : componentPhiInit
};
gui.add(params, 'StartingVector').name('Starting Vector :');
controllerComponentVectorTheta = gui.add(params, 'ComponentVectorTheta', minComponentTheta, maxComponentTheta, 0.0001).name('Component θ ');
controllerComponentVectorPhi = gui.add(params, 'ComponentVectorPhi', minComponentPhi, maxComponentPhi, 0.0001).name('Component φ ');
Now I tried :
var params = {
StartingVector : '',
ComponentVectorTheta : componentThetaInit.toFixed(4),
ComponentVectorPhi : componentPhiInit.toFixed(4)
};
but this doesn't work. Here's below a capture of what I get ("15" instead of "15.0000") before the execution :
Once the code is running, the 4 floating points are well displayed (because values are no more integers) : this is actually the initial values (before animation) that I would like to be displayed like "15.0000" instead of "15".
The result is the same by declaring :
var componentThetaInit = 15.0000;
var componentPhiInit = 15.0000;
I have also tried :
ComponentVectorTheta : parseFloat(componentThetaInit.toFixed(4)),
ComponentVectorPhi : parseFloat(componentPhiInit.toFixed(4))
If anyone could see what's wrong, this would be nice.
Thanks
First, some minor bugs. There were some missing variable declarations. I added:
var minComponentTheta = -10.0;
var maxComponentTheta = 100.0;
var minComponentPhi = -100.0;
var maxComponentPhi = 100.0;
2) The autoplace param (which should be autoPlace, capital P) has nothing to do with decimal places... it appears to be an option to automatically add the UI to the DOM.
None of this actually fixes the issue. It's a problem that starts with javascript. If you put this code in the console you'll see the same problem:
var a = 15.0000;
console.log(a);
// prints 15 and not 15.0000
When a number is an integer, it's an integer. To get around this, you can have your default value have a non integer value like 15.0001.
This probably isn't what you're looking for though. So, if you are up for modifying the code for dat.gui.js you can force it to set the value of the input to the string version of the number value. Find the code that looks like this and copy and paste the code below replacing it. I've simply added a toFixed at the end of the first line in the function. Be aware that when you get the value now, it will be a string and not a number, so to do math with it you'll want to parseFloat() on it before using it.
NumberControllerBox.prototype.updateDisplay = function updateDisplay() {
this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision).toFixed(this.__precision);
return _NumberController.prototype.updateDisplay.call(this);
};
In the unminified JS version, ^ that's on line 2050.
I verified this works as you want
Just leave it like this:
ComponentVectorTheta : componentThetaInit.toFixed(4),
ComponentVectorPhi : componentPhiInit.toFixed(4)
Consider this:
a = 15; // a is an integer now
b = a.toFixed(4); // b is the string "15.0000"
c = parseFloat(b); // c is a number (internally, probably an integer)
d = c.toString(2); // d is the string "1111"
e = parseInt(d, 2);// e is an integer again
assert(a === e); // true
Related
There is a certain webpage which randomly generates a number, for example "Frequency : 21". I am trying to create a script which takes the number, 21, and compares it to another variable, then to an if else function. Basically, I've completed most of it, but I can't obtain the number 21. And since it is random, I can't put in a fixed value.
Can anyone help me out?
My code goes like:
setTimeout(MyFunction,5000)
function MyFunction(level,legmin) {
var level = x
var legmin = 49
if (level <= legmin) {
location.reload(true)
}
else {
alert("Met requirements.")
}
where the address of the text I want is:
html>body>div#container>div#contentContainer>div#content>
div#scroll>div#scrollContent>div>div>div#pkmnappear>form>p (x in the code above).
A quick-n-dirty solution without regex.
var lookFor = "Frequency : ";
var text = document.querySelector("#pkmnappear>form>p").textContent;
var level = text.substr(text.indexOf(lookFor) + lookFor.length).split(" ")[0];
This assumes the number will be followed by a space
I'm attempting to build an app that calculates sales metrics. I have run into an unusual problem in my build.
Part of the app allows users to increase/decrease a variable by 5% and then see how that will effect an overall metric. It also allows the user to see the percentage increase/decrease.
I have the functionality working roughly as intended, however if I enter a number lower than 20 into the input and then try in increase it with my incrementing function it only increments once and then stops.
If the number I enter into the input is 20 or greater it increments in the intended way.
Below is my angular code:
function controller ($scope) {
$scope.firstNumber = 0;
$scope.firstPercent = 0;
$scope.increase = function(id) {
var A = parseInt(id);
var B = A * 5/100;
var C = 0;
var C = A + B;
if (id === $scope.firstNumber) {
$scope.firstNumber = C;
$scope.firstPercent = $scope.firstPercent + 5;
}
};
$scope.decrease = function(id) {
var A = parseInt(id);
var B = A * 5/100;
var C = 0;
var C = A - B;
if (id === $scope.firstNumber) {
$scope.firstNumber = C;
$scope.firstPercent = $scope.firstPercent - 5;
}
};
I can't see anything wrong with my maths, my thinking is that perhaps I'm approaching angular in the wrong way. However I'm not sure.
I have put together a fiddle that shows the full code.
jsFiddle
I have updated the fiddle to use parseFloat. Seems like the numbers are incrementing now.
var A = parseFloat(id);
http://jsfiddle.net/kjDx7/1/
The reason why it was working with values above 20 was that it was just reading the part before decimals each time it tried to increase. So 20 became 21 and 22.05 and so on. As long the the value before decimal kept changing, it showed different (but incorrect) answers.
On the other hand, 10 became 10.5 which when parsed yielded 10. As you can see, this cycle continued endlessly.
The reason why you face the issue is because 5% of anything less than or equal to 20 is less than or equal to 1.
When you parseInt() the value, you always end up with the same number again.
Take 15 for example.
5% of 15 = 15.75
After parseInt(), you get the value 15 again.
You use the same value to increment / decrement each time.
Hence for values below 20, you don't get any changes.
As #Akash suggests, use parseFloat() instead - or why even do that when the value that you get is float anyway
I made a fork of your fiddle. I'm not completely sure what you want to achive.
Take a look at this fiddle.
$scope.increase = function() {
$scope.firstPercent = $scope.firstPercent + 5;
var A = $scope.firstNumber;
var B = (A / 100) * $scope.firstPercent;
var C = A + B;
$scope.firstNumberWithPercent = C;
};
update
After posting, i see that question is already answered. But is this what you really want? When you hit increase, it takes 5 % off of the number in the input field. That is ok, but when you hit decrease after that, it takes 5 % off the number in the same field. So your starting point is different.
100 + 5/100 = 105
105 - 5/105 = 99,75
An example of what im trying to get:
String1 - 'string.co.uk' - would return 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'string` and 'co.uk'
I currently have this:
var split= [];
var tld_part = domain_name.split(".");
var sld_parts = domain_name.split(".")[0];
tld_part = tld_part.slice(1, tld_part.length);
split.push(sld_parts);
split.push(tld_part.join("."));
With my current code, it takes the split parameter from the beginning, i want to reverse it if possible. With my current code it does this:
String1 - 'string.co.uk' - returns 'string' and 'co.uk'
String2 - 'random.words.string.co.uk' - would return 'random` and 'words.string.co.uk'
Any suggestions?
To expand upon elclanrs comment:
function getParts(str) {
var temp = str.split('.').slice(-3) // grabs the last 3 elements
return {
tld_parts : [temp[1],temp[2]].join("."),
sld_parts : temp[0]
}
}
getParts("foo.bar.baz.co.uk") would return { tld_parts : "co.uk", sld_parts : "baz" }
and
getParts("i.got.99.terms.but.a.bit.aint.one.co.uk") would return { tld_parts : "co.uk", sld_parts : "one" }
try this
var str='string.co.uk'//or 'random.words.string.co.uk'
var part = str.split('.');
var result = part[part.length - 1].toString() + '.' + part[part.length - 1].toString();
alert(result);
One way that comes to mind is the following
var tld_part = domain_name.split(".");
var name = tld_part[tld_part.length - 2];
var tld = tld_part[tld_part.length - 1] +"."+ tld_part[tld_part.length];
Depending on your use case, peforming direct splits might not be a good idea — for example, how would the above code handle .com or even just localhost? In this respect I would go down the RegExp route:
function stripSubdomains( str ){
var regs; return (regs = /([^.]+)(\.co)?(\.[^.]+)$/i.exec( str ))
? regs[1] + (regs[2]||'') + regs[3]
: str
;
};
Before the Regular Expression Police attack reprimand me for not being specific enough, a disclaimer:
The above can be tightened as a check against domain names by rather than checking for ^., to check for the specific characters allowed in a domain at that point. However, my own personal perspective on matters like these is to be more open at the point of capture, and be tougher from a filtering point at a later date... This allows you to keep an eye on what people might be trying, because you can never be 100% certain your validation isn't blocking valid requests — unless you have an army of user testers at your disposal. At the end of the day, it all depends on where this code is being used, so the above is an illustrated example only.
How do I add the following text boxes together with the logic below?
oneTextBox = $120.00,
twoTextBox = .03*oneTextBox,
threeTextBox = oneTextBox + twoTextBox
I would also like the units of each text box to be in dollars ($).
function doGet(e) {
var app = UiApp.createApplication();
var VertPanel = app.createVerticalPanel().setId('VertPanel');
var oneTextBox = app.createTextBox().setText("$120.00").setId("oneTextBox").setName("oneTextBox");
var twoTextBox = app.createTextBox().setId("twoTextBox").setName("twoTextBox");
var threeTextBox = app.createTextBox().setId("threeTextBox").setName("threeTextBox");
app.add(VertPanel);
VertPanel.add(oneTextBox).add(twoTextBox).add(threeTextBox);
return app;
}
The value returned by e.parameter.oneTextBox in the handler function is a string, in your example it should be "$120.00," and what you want is a numeric value... what I'd suggest is to use a replace() to remove all non numeric characters and convert that to a number like this :
var oneTextBoxNumValue = Number(e.parameter.oneTextBox.replace(/[^0-9]/g,''));// the regex ^0-9 takes everything not between 0 and 9 (and replace by '')
Using the same process on other textBoxes you can do everything you want with math operations after this conversion.
To get the results in $, simply add a '$' to your result
getElementById('oneTextBox').setText(resultNumeric+"$")
the only tricky thing is the decimal point, you'll need to take this into account in your conversion : $120.00, will become 12000 in numeric value so don't forget to divide the result somewhere or your stuff will become very expensive ! ;-)
Also I've had some rounding errors sometimes but it's always possible to handle quite easily, for example in a similar case I had to use something like this to get the correct result : (2.00 instead of 1.99 if quant = 2 in the example below, note that I divide the integer by 100 to get value with 2 decimals)
var total = parseInt(Number(quant)*valtotal*100+0.01)/100;
Hoping it will give some ideas to start with.
EDIT : here is a small code to illustrate :
function calcTest() {
var app = UiApp.createApplication().setTitle('TextField Calculator');
var button = app.createButton('Calculate');
var handler = app.createServerHandler('calc');
button.addClickHandler(handler);
var grid = app.createGrid(5, 2);
grid.setText(0, 0, 'value1 ');
grid.setWidget(0, 1, app.createTextBox().setName('value1').setText('$ 45.00/unit'));
grid.setText(1, 0, 'value2');
grid.setWidget(1, 1, app.createTextBox().setName('value2').setText('3 units'));
grid.setText(2, 0, 'press button to calculate');
grid.setWidget(2, 1, button);
grid.setText(3, 0, 'value3 = value1*1.35');
grid.setWidget(3, 1, app.createTextBox().setId('value3').setEnabled(false));
grid.setText(4, 0,'sum value1 + value2 + value3');
grid.setWidget(4, 1, app.createTextBox().setId('sum').setEnabled(false));
handler.addCallbackElement(grid);
app.add(grid);
var ss = SpreadsheetApp.getActive();
ss.show(app);
}
function calc(e){
var app = UiApp.getActiveApplication();
var value1 = Number(e.parameter.value1.replace(/[^0-9]/g,''))/100;
var value2 = Number(e.parameter.value2.replace(/[^0-9]/g,''));
var calcvalue = parseInt(value1*1.35*100)/100
var sumcalc = calcvalue+value1+value2
app.getElementById('value3').setText('$ '+calcvalue)
app.getElementById('sum').setText(sumcalc+' without unit;)')
return app
}
EDIT 2 : here is another code, a function that I use in an application to convert string values to Euros, it is slightly different in its approach but works pretty well.
function toEuro(val){
if(val==''){temp='';return temp}
var temp = val.toString().replace(/[^\d\.-]/g,'').split('.');
if(temp[0]==''){temp[0]='0'}
if(temp.length==1){var result = temp[0]+',00 €'}
else{
var int = temp[0]
var dec = temp[1]
if(dec.length==1){var result=int+','+dec+'0 €'}else{var result=int+','+dec+' €'}
}
return result
}
I was trying to get the top position of the element and the margin-bottom value.
that worked:
var top = -$('elem').postion().top; // lets say its -54
var margin = $('elem').css('margin-top'); // lets say its 0
Bud I need to add these up for my animate function. so top+margin but jQuery gives -540 px but it need to return -54 px.. or when its negative it just gives -54-10px when I need -64 px.
Is there someting to get this fixed? I can't come up with it and it annoys me!
My code:
var top = -$('#id1').position().top;
var margin = $('.scrollable').css('margin-top');
var combine = top+margin;
$('.animate').animate({'margin-top' : combine});
Bud i need to add these up for my animate function. so top+margin but jQuery gives 540 p
css values are strings, so since one of your operands is a string, the + is being interpreted as a concatenation operator (54 + "0" = "540"), not an addition operator. (Details) To turn them into numbers, use parseInt(str, 10), e.g.:
// I believe `top` will already be a number; check and if not, use parseInt here too,
// e.g. var top = -parseInt($('#id1').position().top, 10);
var top = -$('#id1').position().top;
// This will definitely be a string that needs parsing; note that we're assuming
// here that the margin has been given in `px` units.
var margin = parseInt($('.scrollable').css('margin-top'), 10);
// Now this + is an addition, not a concatenation
var combine = top+margin;
$('.animate').animate({'margin-top' : -combine});
It's because it returns the values as strings, and using the + operator on them concatenates. You can use parseInt to get a number from a string. It'll even work if there is a px suffix, though it will stop at that.
var top = $('elem').postion().top;
var margin = $('elem').css('margin-top');
var total = parseInt(top, 10) + parseInt(margin, 10);
Try this
var combine = parseInt(top) + parseInt(margin);