Format integer thousands separator throughout the document - javascript

After months of web-development, I find myself completely helpless trying to find a good solution for a simple problem of formatting all the numbers throughout the DOM as I wish. Specifically, I have a js function my_int_formatter(), that I want to apply to all integers after the doc has been loaded. Best descriped by example - I want to do something like
<td>my_int_formatter({{django_variable}})</td>
I know the code above won't work, because I have to include 'script' tag, but first, I don't like the messy code, and second, javascript won't recognize python variable
I tried the following way:
HTML
<td class = 'my_integer'>{{django_variable}}</td>
JS
$(document).ready(function(){
// ....
content = $('.my_integer').html();
$('.my_integer').html(my_int_formatter(content));
...but as expected, I got wrong results because the js code applied the same html() content of the first .my_integer element in the DOM chain to all the others. Any ideas how to do this the short and correct way ?

If I understand correctly, your problem isn't with the formatting but actualy applying the formatting to each of your dom elements.
Try using jquerys .each() function and using $(this).html() to actualy grab the content.
$('.my_integer').each(function(){
content = $(this).html();
$(this).html(content+"formatted");
});
here's a quick fiddle :
https://jsfiddle.net/57rdq2a0/2/

If I understand you correctly, you want to use builtin django.contrib.humanize application: https://docs.djangoproject.com/en/1.9/ref/contrib/humanize/
You can format integers using some predefined filters, for example intcomma:
4500 becomes 4,500.
45000 becomes 45,000.
450000 becomes 450,000.
4500000 becomes 4,500,000.
Usage in your case would be like
{% load humanize %}
<td>{{django_variable|intcomma}}</td>
Also don't forget to include the app in INSTALLED_APPS
Also this question might be useful
If you want to apply filter to all variables of some kind, I suggest you to use Middleware to fiddle with response before rendering.

Related

Using variables with jQuery's replaceWith() method

Ok this one seems pretty simple (and it probably is). I am trying to use jQuery's replace with method but I don't feel like putting all of the html that will be replacing the html on the page into the method itself (its like 60 lines of HTML). So I want to put the html that will be the replacement in a variable named qOneSmall like so
var qOneSmall = qOneSmall.html('..........all the html');
but when I try this I get this error back
Uncaught SyntaxError: Unexpected token ILLEGAL
I don't see any reserved words in there..? Any help would be appreciated.
I think the solution is to only grab the element on the page you're interested in. You say you have like 60 lines. If you know exactly what you want to replace..place just that text in a div with an id='mySpecialText'. Then use jQuery to find and replace just that.
var replacementText = "....all the HTML";
$("#mySpecialText").text(replacementText);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mySpecialText">Foo</div>
If you're only looking to replace text then jaj.laney's .text() approach can be used. However, that will not render the string as HTML.
The reason the way you're using .html() is likely illegal is that qSmallOne is not a JQuery object. The method cannot be performed on arbitrary variables. You can set the HTML string to a variable and pass that string to the .html() function like this:
var htmlstring = '<em>emphasis</em> and <strong>strong</strong>';
$('#target').html(htmlstring);
To see the difference between using .html() and .text() you can check out this short fiddle.
Edit after seeing the HTML
So there is a lot going on here. I'm just going to group these things into a list of issues
The HTML Strings
So I actually learned something here. Using the carriage return and tab keys in the HTML string is breaking the string. The illegal-ness is coming from the fact the string is never properly terminated since it thinks it ends at the first line. Strip out the white space in your strings and they're perfectly valid.
Variable Names
Minor thing, you've got a typo in qSmallOne. Be sure to check your spelling especially when working with these giant variables. A little diligence up front will save a bunch of headache later.
Selecting the Right Target
Your targets for the change in content are IDs that are in the strings in your variables and not in the actual DOM. While it looks like you're handling this, I found it rather confusing. I would use one containing element with a static ID and target that instead (that way you don't have to remember why you're handling multiple IDs for one container in the future).
Using replaceWith() and html()
.replaceWith() is used to replace an element with something else. This includes the element that is being targeted, so you need to be very aware of what you're wanting to replace. .html() may be a better way to go since it replaces the content within the target, not including the target itself.
I've made these updates and forked your fiddle here.

Use one javascript script to dynamically modify another script

Yo!
I have an arbitrary javascript file, let's call it localScript, and just say it looks something like this:
<script id="myScript" type="text/javascript">
function () {
var blue = 'blue';
var person = {
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"brown"
};
var bluePerson = function () {
person[color] = blue;
};
}
</script>
I want to be able to use another externalScript to dynamically change the contents of this localScript. For this simple example, let's just say I want to update some of the values in localScript, like—maybe change age of the person object to 75. (Obviously, there's very simple ways to do this, but for my use case it's imperative that I use another externalScript to generate the contents of this localScript).
It would be easy if there was something like .innerHtml which I could use in the externalScript which would allow me to select an element and then replace the 'innerHtml' contents. The localScript, though, obviously isn't composed of elements.
As far as I know, when using a script to modify another script, there aren't any 'easy' ways to reference variables/objects/items in the script.
Things I've considered are indexOf(), search(), and match(), which I could use in externalScript to find strings inside localScript and then replace the values. I feel though as these could be performance no-no's, especially if the script grows.
Are there any easy ways to do this—with an emphasis on performance? I feel like there must be some easy way to reference one of the items in the script, though, I suppose a script is all one large string.. and maybe there is no simple way.
BTW—I'm using AngularJS, if there are any built in methods—though I think this is mostly just a javascript thing.
Thanks a bunch!
It looks like a bad idea, but... well, if it is imperative...
It makes no sense to change a script in a <script> tag - if it is in DOM, it has already executed (and no longer matters). Thus, to change the script before it has a chance to execute, you need to load it using AJAX, change the text, then eval it.
You can easily change the variables. Refer following steps
Include external script just below the script you have written.
Access the variables in the external script as if they are locally declared.
The variables you have created in above script are available in global scope and hence should be accessible from everywhere.
Note: This answer was added before the function clause was added.

Replace content of a web page with stuff from AJAX response

The idea is to replace the contents of a web page with the same page requested through an ajax call, but only the HTML elements that are different.
Current I have this in my $.ajax success callback:
var replace = function(first, second){
$(first.html() !== second.html())
first.replaceWith(second);
};
replace($('#container'), response.find('#container'));
Which works, but because the content gets always replaced I get to see a "clipping" effect. The ajax request runs multiple times, almost every second, until a certain class is added to the container tag from the ajax response, so the clipping is very annoying.
Basically I want to only replace the elements that have different html, but somehow start from the last level, to prevent replacing of elements that have the same html code.
I made a fiddle example here: http://jsfiddle.net/2u4eB/
So in that markup only the contents of the <b> tag should be replaced, and not the entire div like it is now, because only <b> is different.
Does anyone have any pointers on how could I achieve this?
If you can make some assumptions, then it's not so hard:
Assumption 1: The markup is exactly the same every time
Assumption 2: The only thing which changes is the TEXT inside of certain html tags
You must then know the HTML tags. If you are a consistent person, all of your dynamic data should be wrapped in a similar tag - in your question you mentioned a <b> tag, so lets make a third assumption:
Assumption 3: All dynamic data is wrapped with a <b> tag
Then all you have to do is this:
var replace = function(first, second) {
var oldValues = first.find('b'),
newValues = second.find('b');
oldValues.each(function(i) {
if(oldValues[i].textContent != newValues[i].textContent) {
oldValues[i].textContent = newValues[i].textContent;
}
});
};
replace($('#container'), response.find('#container'));
NOTE: this works because jQuery's find() returns a list of nodes in document order - so Assumption #1 is very important.
I highly recommend using a framework that supports client side binding. (Examples include but are not limited to Knockout, Handlebars, Angular, Underscore) This will give you better results faster than writing low level DOM Manipulation.
Knockout.js and Underscore.js are my favorites, but there are many great options.

Javascript-better method of writing HTML

This problem is about Javascript writing HTML code for video player. I think there are some faster methods(document.createElement,Jquery and etc). Please tell some better and faster methods for this procedure. Thanks in advance
function createPlayer(videoSource){
document.writeln("<div id=\"player\">");
document.writeln("<object width=\"489\" height=\"414\" >");
document.writeln("<param name=\"player\" value=\"bin- debug/FlexPlayer.swf\">");
//etc
document.writeln("</embed>");
document.writeln("</object>");
document.writeln("</div>");
}
Going native with document.createElement will be the fastest. However, if your markup is large, going this way makes it a maintenance nightmare. Also, it is not easy to 'visualize' things.
In those cases, you might want to go for a tradeoff with client side templating solutions such as jQuery templates or underscore templates or John Resig's microtemplating.
Another performance boost is to build your entire markup and add it to DOM at the very end (add children first, then add the parent to DOM).
There is a jQuery function I know of that allows you to create a template HTML snippet which you can later use repeatedly with only 1 or 2 lines of code, adding in variables and appending it to the page.
For this you will need jQuery (latest should be fine) http://jquery.com/
Docs for the tmpl function are here: http://api.jquery.com/jquery.tmpl/
For details on how to use it you'd be best reading an example on the jQuery docs, I've not used it myself so can't write you a good example but there is great stuff on the docs site.
Hope this helps
EDIT:
A less resource intensive way to acheive that function would be to, rather than writing each line in turn to the document, just append them all to a string and then write that once when you are finished.
Eg:
function createPlayer(videoSource){
var html="<div id=\"player\">";
html+="<object width=\"489\" height=\"414\" >";
//etc
document.writeln(html);
}
This is faster because writing a line to the document uses more resources than just appending a string in memory. For MAXIMUM SPEED you could even declare the html var outside of the function and just set it to the markup as one long string, then write it - i.e
var html;
function createPlayer(videoSource){
html="<div id=\"player\"><object width=\"489\" height=\"414\" >"; //and so forth
document.writeln(html);
}
If you can justify the larger download sizes I'd go for the jQuery solution if possible, it's generally a bit more manageable - I've done plenty script generated HTML in the past and it very quickly becomes a pain to maintain. Good luck
You can try this:
function createPlayer(videosource){
var div = document.createElement('div');
div.innerHTML = '<object width=\"489\" height=\"414\" >' +
'.......'
document.body.appendChild(div);
}
For general manipulation and addition of HTML I'd recommend jQuery. It makes the process much easier and quicker.
You will find more information on this here:
jQuery Manipulation Methods - http://api.jquery.com/category/manipulation/
jQuery Tutorials - http://docs.jquery.com/Tutorials

ASP.NET inline server tags

I'd like to start by saying that my code is working perfectly, this is more a "how best to do it" kind of question.
So I have code like this in my .aspx file:
function EditRelationship() {
var projects=<%= GetProjectsForEditRelationship() %>;
// fill in the projects list
$('#erProjectsSelect').empty();
for(var i in projects)
$('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');
var rels=<%= GetRelationshipsForEditRelationship() %>;
// etc
}
Again, it's working fine. The problem is that VS2008 kinda chokes on code like this, it's underlining the < character in the tags (with associated warnings), then refusing to provide code completion for the rest of the javascript. It's also refusing to format my document anymore, giving parsing errors. The last part is my worst annoyance.
I could put some of these in evals I guess, but it seems sorta dumb to add additional layers and runtime performance hits just to shut VS up, and it's not always an option (I can't remember off the top of my head where this wasn't an option but trust me I had a weird construct).
So my question is, how do you best write this (where best means fewest VS complaints)? Neither eval nor ajax calls fit this imo.
If your aim is to reduce VS complaints, and if you are running asp.net 4 (supporting Static client Ids), maybe a strategy like the following would be better?
Create a ASP:HiddenField control, set its ClientIdMode to "Static"
Assign the value of GetRelationshipsForEditRelationship() to this field on page load
In your javascript, read the value from the hidden field instead, I assume you know how to do this.
It's more work than your solution, and you will add some data to the postback (if you perform any) but it won't cause any VS complaints I guess :)
You could do this from your page in the code-behind
ClientScript.RegisterArrayDeclaration("projects", "1, 2, 3, 4");
or to construct something like JSON you could write it out
ClientScript.RegisterClientScriptBlock(GetType(), "JSONDeclarations", "your json stuff");
UPDATE Based on my comment
<script id="declaration" type="text/javascript">
var projects=<%= GetProjectsForEditRelationship() %>;
var rels=<%= GetRelationshipsForEditRelationship() %>;
</script>
<script type="text/javascript">
function EditRelationship() {
// fill in the projects list
$('#erProjectsSelect').empty();
for(var i in projects)
$('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');
}
</script>
I don't have VS2008 installed to test with, so take this with a grain of salt, but have you tried something like this?
var projects = (<%= GetProjectsForEditRelationship() %>);
Something like that might trick the JavaScript parser into ignoring the content of your expression.
For what it's worth, VS2010 correctly parses and highlights your original code snippet.
Is it an option to move this to VS2010? I just copied and pasted your code and the IDE interpreted it correctly.
The best solution is to put javascript in a separate file and avoid this entirely. For this particular function, you're doing server-side work. Why not build the list of options that you intend to add dynamically in codebehind, put them in a hidden div, and then just have jQuery add them from the already-rendered HTML?
If you have a situation where you really want to dynamically create a lot javascript this way, consider using ScriptManager in codebehind to set up the variables you'll need as scripts and register them, then your inline script won't need to escape
ScriptManager.RegisterClientScript("projects = " + GetProductsForEditRelationship());
(Basically, that is not the complete syntax, which is context dependent). Then refer to "projects" in your function.
(edit)
A little cleaner way to do this on a larger scale, set up everything you need like this in codebehind:
string script = "var servervars = {" +
"GetProductsForEditRelationship: " + GetProductsForEditRelationship() +
"GetRelationshipsForEditRelationship: " + GetRelationshipsForEditRelationship() +
"}"
and refer to everything like:
servervars.GetProductsForEditRelationship
If you do this a lot, of course, you can create a class to automate the construction of the script.

Categories

Resources