Currency Conversion with Javascript Iteration

Missing that handy currency/country conversion link on your favorite page? A quick bookmarklet can fix that.

We will put together some javascript to iterate over our currency elements to do the conversion for us. In this case, we are looking at the bicycle site road.cc and we wish to convert review prices from Pounds to US Dollars.

Screenshot 2013-12-29 22.55.21
road.cc reviews before conversion (http://road.cc/show/review-section/road-bikes/35)
Screenshot 2013-12-29 22.55.31
road.cc reviews after conversion (http://road.cc/show/review-section/road-bikes/35)

 

 

 

 

 

 

 

 

 

We first select all of our data of interest. In this case, our data is in a div with a specific class that merely contains the price.

var data = document.getElementsByClassName("review-price");

Next we will iterate over this data and convert the price using a decent approximation based upon today’s conversion rate. However, we have two considerations; the price div also contains the Pound character which we will first cut out before converting with the replace call and we will also want to round to two decimal places for sanity.

for (var i = 0; i < data.length; i++) {
   data[i].innerHTML = Math.round(data[i].innerText.replace('£', '') * 1.6479 * 100) / 100;
}

If you try and run this, you may notice one caveat – road.cc uses infinite scroll. This means that we will convert material that is currently loaded, however, upon scrolling down and with the loading of additional content, we would have to run the bookmarklet again to convert this newly loaded data. The problem is that we would convert our previously adjusted price data again. To prevent this issue, we can modify our code to convert data that begins with the Pound but not Dollar symbol.

function () {
    var data = document.getElementsByClassName("review-price");
    for (var i = 0; i < data.length; i++) {
        /* change class so we don't suck it up again since we have to re-run the bookmarklet
       again because of infinite scroll
      */
        if (data[i].innerHTML.indexOf("£") != -1) {
            data[i].innerHTML = '$' + Math.round(data[i].innerText.replace('£', '') * 1.6479 * 100) / 100;
        }
    }
}

Now, remember, we wrap this in a javascript declaration to create our bookmarklet. Thus, the final version will result in the following when we place our pieces of code together.

javascript: (

function () {
    var data = document.getElementsByClassName("review-price");
    for (var i = 0; i < data.length; i++) {
        /* change class so we don't suck it up again since we have to re-run the bookmarklet
       again because of infinite scroll
      */
        if (data[i].innerHTML.indexOf("£") != -1) {
            data[i].innerHTML = '$' + Math.round(data[i].innerText.replace('£', '') * 1.6479 * 100) / 100;
        }
    }
}())

Running the bookmarklet should now convert currency data to US Dollars which works with infinite scroll by re-clicking the bookmarklet as new data is loaded.

Stumpy Version 1.5 is Now Available!

Stumpy Version 1.5 is now out and ready for testing.
Should be functional, but please submit any issues you might find to the issues page.

Changes include (from commits):

  • Removed hardcoded domains from JS. We now pipe in through the stumpy_domain var by setting a global JS var ‘DOMAIN’ in the index and then reference that JS var in our scripts. You will no longer need to set your domain as hard coded into javascript code.
  • Updated to use get submission of new URLs for shortening. This should work, but needs to be tested on the production version to make sure WSGI and such are working okay without the earlier hack that was implemented.

Accessing Django Template Variables in Javascript

How do we follow the Django DRY principle and avoid as many hard coded elements as possible in our project when we need to include Javascript? A good example of this is if we are pulling in a bookmarklet that will be offered on the site. We need to reference the domain of our project in the bookmarklet, but this then yields code buried in our project’s static files that needs to be altered by anyone that might be utilizing your open sourced code.

This example presents a little bit of a challenge. If this were HTML in our template we could simply reference a DOMAIN variable that we would feed in through a view. However, this is a static Javascript file, so how do we go about utilizing Django template variables in supposedly static Javascript?

Here is a simple method. In our HTML template, we will setup a Javascript global variable that is created to reference a template variable that we feed in from our view, here a domain, and this variable is then referenced in our static Javascript files.

<!-- Our HTML Template (templates/index.html) that is fed data from views.py -->
{% extends "base.html" %}
{% block content %}

<script type="text/javascript" src="/static/somejs.js"></script>

<script> 
var DOMAIN = "{{ site_domain }}";
</script>

<!-- rest of our template, business as usual. -->
{% endblock %}

As you can see, we would feed in a site_domain variable from views.py that might be created something like this.

from django.contrib.sites.models import Site
from django.shortcuts import render_to_response

def index(request):
    '''Our main index view.'''
    site_domain = smart_str(Site.objects.get_current().domain)
    # more of our view code...
    
    return render_to_response('templates/index.html', {
	'site_domain': site_domain,
        #...rest of our template vars
    })

Now, how do we use this in our static Javascript? We reference that global Javascript variable we declared in our template using our Django template variable site_domain.

// Our Javascript file ... /static/somejs.js 
alert("Your current domain is: "+DOMAIN);

Now our code is much more portable, even in places where things should essentially be static.

jQuery – Running Functions Every X Seconds

Another quick hack post. This time we will look at running some Javascript code, specifically jQuery, on a set interval to update code in a page. I had a request from a good buddy the other night to create something to flash a word at random from a list very fast as well as changing the background color as the word changed, also in a random manner. I figured we could do something quick, and universal, in javascript using the jQuery library.

This is a rather specific example, and one that does not seem that practical or programmatically important at that. However, the concept is universal in that we can easily adapt this theory to select a random image or call upon an AJAX function on a set interval. I find that these fun and prank-driven challenges usually present an opportunity to learn a new concept or come up with a creative new strategy to solve a problem while not under the stress of some real world problem.

In the following example, we will start with a default div and we will load it up with fresh content using setInterval(). The idea of the code is to use a list of words and randomly select a word from this list and display it in our empty div and repeat this on an interval of our choosing. To make it even more fun, or shall we more poignantly say, more annoying, we will use a second list of background colors and set the page background color by adjusting the CSS attribute for the body tag as we change the word displayed.

First, we will declare lists of words and colors:

words = ['word a','word b','word c','word d'];
backgroundColors = ['gray','yellow','blue','black','red'];

To select a word and color in a random fashion we will use Math:

var thisWord = words[Math.floor(Math.random() * words.length)];
var thisBackground = backgroundColors[Math.floor(Math.random() * backgroundColors.length)];

In order to make the actual changes we will use the css and text calls:

$("body").css('background',thisBackground);
$("#container").text(thisWord);

Finally, we will nest the random selections and change calls inside a setInterval function to run it in a timed loop, here every 200ms:

$(function() {
  setInterval(function() {
    var thisWord = words[Math.floor(Math.random() * words.length)];
    var thisBackground = backgroundColors[Math.floor(Math.random() * backgroundColors.length)];
    $("body").css('background',thisBackground);
    $("#container").text(thisWord);
  },200);
}

Now we have some jQuery code that will select a random word and background color from our provided lists and make those changes every 200ms. To put everything together, we use something like the code below.

<html> 
<head> 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> 
<script type="text/javascript"> 
jQuery(document).ready(function($) {
words = ['word a','word b','word c','word d'];
backgroundColors = ['gray','yellow','blue','black','red'];
$(function() {
  setInterval(function() {
    var thisWord = words[Math.floor(Math.random() * words.length)];
    var thisBackground = backgroundColors[Math.floor(Math.random() * backgroundColors.length)];
    $("body").css('background',thisBackground);
    $("#container").text(thisWord);
  },200);
});
});
</script> 
<style> 
	body {
		margin: 0;
		padding: 0;
		background: black;
	}
	.container {
		width: 100%;
		margin: 0;
		padding: 0;	
	}
	#container {
		margin: 425px;
		padding: 0;
		color: white;
		font-size: 11em;
		font-family: impact, arial black;
		text-align: center;		
	}	
</style> 
</head> 
<body> 
<div class=container><p id=container>loading...</p></div> 
</body> 
</html> 

Try it out, it’s trippy!

Simple Javascript Redirect

Need a quick redirect for a page? A simple Javascript location set can get the job done just fine.

Let’s redirect mutaku.com/github to go to the Mutaku GitHub Page. All we need to do is create an index.html file with the following in our subdirectory of choice (here we would have it residing at mutaku.com/github/index.html).

<script type="text/javascript">
   window.location = "https://github.com/mutaku"
</script>

Now, as you would expect, if you visit mutaku.com/github you will be redirected to the GitHub page.