What I'm attempting to do can be accomplished by the following...
elementContent = document.getElementById('docElement').innerHTML;
elementContent = parseFloat(elementContent);
or even by...
elementContent = parseFloat( document.getElementById('docElement').innerHTML );
but I can't help to wonder if there's a more elegant way to retrieve and assign DOM content as a float that I may be unaware of. Any insight?
There is the unary plus operator which tries to convert a string (or another type's toString()) to a number. It would be used like:
elementContent = +document.getElementById('docElement').innerHTML;
As others have mentioned you can use jQuery as essentially syntactic sugar for .innerHTML here, also.
That's a fine way to go about doing things. The only thing I could suggest would be that if you can avoid working with the HTML markup entirely, by storing the "clean" number as an attribute of the element, that would be preferable, as it would get around problems that might be introduced if the HTML gets fancier than you expect it to be. (For example, sometimes designers want negative numbers formatted with the Unicode "minus" glyph instead of the plain hyphen, because it looks better.)
Thus if you could generate your elements like this:
<span id='docElement' data-value='29.20221'>29.20221</span>
then instead of accessing the value as ".innerHTML" you'd use ".getAttribute()":
var value = document.getElementById('docElement').getAttribute('data-value');
value = parseFloat(value);
Use JQuery:
var html = parseFloat($('#docElement').html());
$('#docElement').html(html);
If you use a library such as jQuery the code for this would be more elegant, like so:
var el = parseFloat( $('#docElement').text() );
Don't forget you might run into an issue where you need to trim() the string as well.
Related
I have a standard $scope.totals = $scope.totals = {storage:0, dailystorage:0}; and an angular.forEach that adds cam.storage to the $scope.totals.storage to give me the total storage.
I am using this to do that:
$scope.totals.storage = $scope.totals.storage+cam.storage;
The problem is that, say if two cam.storage are 21.09 and 15.82, it'll make $scope.totals.storage 21.0915.82 - basically adding them like strings instead of like math.
How do I make it an addition - not a joining?
Judging from what you've posted (verifying that $scope.totals is already a number), cam.storage is a string. You need to parse it to a number before adding it to the existing value:
$scope.totals.storage += parseFloat(cam.storage);
If they are concatenating instead of adding, it sounds like you need to parse them as decimals (You can also use toFixed(int) to limit the decimals as needed).
$scope.totals.storage = parseFloat($scope.totals.storage)+parseFloat(cam.storage);
My solution I use {{(a*1)+(b*1)}} It work.
I'm attempting to grab a data-* with jQuery. My problem is that jQuery reads my string of numbers as a number and as such drops the leading zero.
HTML
<tr data-string-number="0123456789">... (website layout, jk) ...</tr>
jQuery 1.7.2
var string_number = $('#selector').data('string-number');
// string_number == 123456789
// string_number != '0123456789'
Seems simple enough however this always drops the leading zero.
data-string-number is always going to be a number and may or may not have a leading zero. Currently it has a standard length but I can't say at this point if that will stay true.
Current only thought is to prefix it with a non-numeric and remove it straight away. This feels hacky and makes me sad.
Any thought appreciated.
Thanks.
Use this:
$('#selector').attr('data-string-number')
The .data() method does data conversion by design. The .attr() method simply returns the attribute as is (as a string). Note that when using .attr() you need to supply the full name of the attribute including the "data-" prefix.
I know this is old but I have 2 alternative to using the .attr() for accessing the data as a string.
<!-- Force a String by breaking the parser Remove Quotes later
or Use Object Below -->
<li data-tmp='"0123456789"'>Data as a String: </li>
<li data-tmp='{"num":123456789,"str":"0123456789"}'>Data as a Object: </li>
Now you can access them with the jQuery .data() method.
See this fiddle to illustrate http://jsfiddle.net/KUrJ2/.
Get the attribute with the standard attr() accessor.
jQuery tries to guess the type and convert it when using data() on data-* attributes. As we know leading 0's are insignificant in a Number but not a String.
use the jquery attr()
http://jsfiddle.net/duerq/
If an html element id has no period in it, then copying between elements is of course trivial, e.g.:
var theForm = document.paymentForm;
theForm.BillStreet1.value = theForm.ShipStreet1.value;
I've got a case where I need to have period in my ids, namely id="bill.street1" and id="ship.street1", and the following doesn't work :-(
theForm.bill.street1.value = theForm.ship.street1.value;
Can you please let me know how to handle the period? Does jquery make this simpler?
jQuery makes everything simplier by using css selectors to access elements. However, if you don't want to use jQuery, you can access the element this way, I believe.
theForm['bill.street1'].value = theForm['ship.street1'].value;
I haven't tested this, but it should work because periods are an alternate method to access an array, iirc.
Be sure to use theForm['bill.street1'].value = theForm['ship.street1'].value;
and not theForm.['bill.street1'].value = theForm.['ship.street1'].value;. The extra periods make the format invalid, in the same way using array.[2] instead of array[2] would invalidate it.
theForm['bill.street1'].value
theForm['ship.street1'].value
var str = '<div part="1">
<div>
...
<p class="so">text</p>
...
</div>
</div><span></span>';
I got a long string stored in var str, I need to extract the the strings inside div part="1". Can you help me please?
you could create a DOM element and set its innerHTML to your string.
Then you can iterate through the childNodes and read the attributes you want ;)
example
var str = "<your><html>";
var node = document.createElement("div");
node.innerHTML = str;
for(var i = 0; i < node.childNodes.length; i++){
console.log(node.childNodes[i].getAttribute("part"));
}
If you're using a library like JQuery, this is trivially easy without having to go through the horrors of parsing HTML with regex.
Simply load the string into a JQuery object; then you'll be able to query it using selectors. It's as simple as this:
var so = $(str).find('.so');
to get the class='so' elememnt.
If you want to get all the text in part='1', then it would be this:
var part1 = $(str).find('[part=1]').text();
Similar results can be achieved with Prototype library, or others. Without any library, you can still do the same thing using the DOM, but it'll be much harder work.
Just to clarify why it's a bad idea to do this sort of thing in regex:
Yes, it can be done. It is possible to scan a block of HTML code with regex and find things within the string.
However, the issue is that HTML is too variable -- it is defined as a non-regular language (bear in mind that the 'reg' in 'regex' is for 'regular').
If you know that your HTML structure is always going to look the same, it's relatively easy. However if it's ever going to be possible that the incoming HTML might contain elements or attributes other than the exact ones you're expecting, suddenly writing the regex becomes extremely difficult, because regex is designed for searching in predictable strings. When you factor in the possibility of being given invalid HTML code to parse, the difficulty factor increases even more.
With a lot of effort and good understanding of the more esoteric parts of regex, it can be done, with a reasonable degree of reliability. But it's never going to be perfect -- there's always going to be the possibility of your regex not working if it's fed with something it doesn't expect.
By contrast, parsing it with the DOM is much much simpler -- as demonstrated, with the right libraries, it can be a single line of code (and very easy to read, unlike the horrific regex you'd need to write). It'll also be much more efficient to run, and gives you the ability to do other search operations on the same chunk of HTML, without having to re-parse it all again.
I have the following
var id='123';
newDiv.innerHTML = "";
Which renders in my HTML.
The problem I have is that I wish to take the call to the method TestFunction, and use as a string parameter in my function StepTwo(string, boolean), which would ideally end up in live HTML as shown...
notice how the TestFunction is a string here (it is executed within StepTwo using eval).
I have tried to format my JS as by :
newDiv.innerHTML = "";
but while this appears to me correct in my IDE, in the rendered HTML, it as garbelled beyond belief.
Would appreciate if anyone could point me in the right direction. Thanks!
One of the biggest capital failures on the internet is creating html in javascript by gluing strings together.
var mya = document.createElement("a");
mya.href="#";
mya.onclick = function(){
StepTwo(function(){
TestFunction('123', false );
}, true );
};
newDiv.innerHTML = "";
newDiv.appendChild(mya);
This Eliminates the need for any fancy escaping stuff.
( I probably should do 'onclick' differently, but this should work, I'm trying hard not to just use jQuery code to do everything )
Heres how I would do it in jQuery:
jQuery(function($){
var container = $("#container");
var link = document.createElement("a"); /* faster than $("<a></a>"); */
$(link).attr("href", "Something ( or # )" );
$(link).click( function(){
var doStepTwo = function()
{
TestFunction('123', true );
};
StepTwo( doStepTwo, false ); /* StepTwo -> doStepTwo -> TestFunction() */
});
container.append(link);
});
There is no good excuse for gluing strings together in Javascript
All it does is ADD overhead of html parsing back into dom structures, and ADD potential for XSS based broken HTML. Even beloved google get this wrong in some of their advertising scripts and have caused epic failures in many cases I have seen ( and they don't want to know about it )
I don't understand Javascript is the only excuse, and it's NOT a good one.
Try using " instead of \"
newDiv.innerHTML = "<a href="#"...
You should be using " not " or \" inside an HTML string quoted with double-quotes.
NewDiv.innerHTML = "";
There's probably a better way to do this - any time you find yourself using eval() you should stand back and look for a different solution.
You claim that eval is the right thing to do here. I'm not so sure.
Have you considered this approach:
and in your StepTwo function
function StepTwo(func,args,flag){
//do what ever you do with the flag
//instead of eval use the function.apply to call the function.
func.apply(args);
}
You could create the a element and attach to the click event using DOM Methods.
A Javascript Framework (like the ubiquitous jQuery) would make this a lot easier.
Your biggest problem is using eval, it leads to so many potential problems that it's nearly always better to find an alternative solution.
Your immediate problem is that what you really have is
as the next " after the start of the onclick attribute, closes it. Use " as others have suggested. And don't use eval.
You need to alternate your " and '.
Maybe you don't need quotes around the 123, because of Javascripts flexible typing. Pass it without quotes but treat it as a string within TestFunction.
Hey guys, thanks for all the answers. I find that the quot; seems to work best.
I'll give you guys some votes up once I get more reputation!
In regards to eval(), what you see in the question is a very small snapshot of the application being developed. I understand the woes of eval, however, this is one of those one in a million situations where it's the correct choice for the situation at hand.
It would be understood better if you could see what these functions do (have given them very generic names for stackoverflow).
Thanks again!
The best way is to create the element with document.createElement, but if you're not willing to, I guess you could do or use ".
In your code:
newDiv.innerHTML = "";
If it doesn't work, try changing "\'" to "\\'".
Remember that the " character is used to open and close the attribute on HTML tags. If you use it in the attribute's value, the browser will understand it as the close char.
Example:
<input type="text" value="foo"bar"> will end up being <input type="text" value="foo">.
...
I know this is hella' old now, but if anyone has issues with escaped strings when using eval (and you absolutely have to use eval), I've got a way to avoid problems.
var html = '';
eval('(function(div, html){div.innerHTML = html;})')(newDiv, html);
So, what's going on here?
eval creates a function that contains two parameters, div and html and returns it.
The function is immediately run with the parameters to the right of the eval function. This is basically like an IIFE.
In this case
var myNewMethod = eval('(function(div, html){div.innerHTML = html;})');
is basically the same as:
var myNewMethod = function(div, html){div.innerHTML = html;}
and then we're just doing this:
myNewMethod(newDiv, html); //where html had the string containing markup
I would suggest not using eval. If it can't be avoided, or if you control all the inputs and there's no risk of injection then this will help in cases where string escapes are an issue.
I also tend to use Function, but it isn't any more secure.
Here's the snippet I use:
var feval = function(code) {
return (new Function(code))();
}