I’m writing a help page for a lottery order form to confirm to specific gaming standards. The page has to show odds for a given set of games that are offered on the order form. I made the decision to pull the content from the database, so that it can be edited from the admin site rather than us going in and editing it. I also decided that a Markdown syntax would restrict how the content was displayed yet allow a degree of power in how it was formatted.

However, there definitely was a problem in displaying things like pay tables. I had to insert a couple of tables into this content to show odds and payout factors for the games that were displayed. Here’s the table in Markdown (GFM-flavor) format. For those who don’t know what Markdown is, it is a method of writing content that is still very readable in its un-rendered form.

# Payout Factors for Different Bet Types Game Type | Combination | Example Bet | Payout ------------ | ------------------------------------------- | -------------------- | -------- Pick 2 | Straight: Any 2 digit # from 00 to 99 | 12 (exact order) | 90:1 Pick 2 | Boxed (2-way; 2 unique digits) | 12 (any order) | 45:1 Pick 3 | Straight: Any 3 digit # from 000 to 999 | 123 (exact order) | 900:1 Pick 3 | Boxed (6-way; 3 unique digits) | 123 (any order) | 150:1 Pick 3 | Boxed (3-way, 2 unique digits) | 334 (any order) | 300:1 Pick 4 | Straight: Any 4 digit # from 0000 to 9999 | 1234 (exact order) | 9000:1 Pick 4 | 24-Way Box (4 digit # with unique digits) | 1234 (any order) | 375:1 Pick 4 | 12-Way Box (4 digit #, 3 unique digits) | 1233 (any order) | 750:1 Pick 4 | 6-Way Box (4 digit #, 2 sets of 2 digits) | 3344 or 4343 (any order) | 1500:1 Pick 4 | 4-Way Box (4 digit, 3 digits the same) | 1112 (any order) | 2250:1

The above renders into an H1 tag for the title and an HTML table for the table portion.

That’s all fine, but see where it says 90:1 for a straight bet? I don’t want a human to edit that number. Additionally, I don’t want to use an example number, since that would force the users to mentally calculate the payout factors themselves, and *could possibly* violate the standards we are implementing. Therefore, the actual payout factor values should be pulled from the database. There’s a number of different ways to do this, one being using something like a replacement token, e.g. {2BallPF}:1. But then, I gotta do something like {2BallPF/2}:1 for the boxed bet, which I would have to figure out on the server…. sounds like a huge pain. I could just let the users edit it every time mass payout factors are changed…

Pick 2 | Straight: Any 2 digit # from 00 to 99 | 12 (exact order) | 70:1 Pick 2 | Boxed (2-way; 2 unique digits) | 12 (any order) | 45:1 Pick 3 | Straight: Any 3 digit # from 000 to 999 | 123 (exact order) | 700:1 Pick 3 | Boxed (6-way; 3 unique digits) | 123 (any order) | 150:1 Pick 3 | Boxed (3-way, 2 unique digits) | 334 (any order) | 300:1

* NO*. I can’t entrust the operators of the system to make these changes any time a payout factor update is done. And I definitely don’t want to manage that crap. It

*always*happens on a Friday night when I am relaxing, or any time on Saturday or Sunday. I

**really**value my free time, even if it’s to do absolutely

**nothing**.

Would a framework like angular.js, react.js, durandal, etc. work for what I’m trying to do? Possibly, but I wasn’t interested in the learning curve (at this moment, mind you, although learning at least one or two of these frameworks sounds like fun), or the **weight**. All I wanted to do was something like take a token, replace it with its value, and evaluate anything as an expression. I thought to myself “man, a ‘data-‘ style attribute would be really nice about now”. I then remembered that Markdown allows HTML to be inserted.

So this is what I did! I made some example output in jsbin:

<!DOCTYPE html> <html> <head> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <meta charset="utf-8"> <title>JS Bin</title> </head> <body>

<input type="hidden" id="max2" value="90" /> <input type="hidden" id="max3" value="900" /> <input type="hidden" id="max4" value="9000" /> <input type="hidden" id="mx" value="6" /> This is a test to see how:<br /><br /> <span data-fix="{max2}">x</span> / <span data-fix="{mx}">16</span> = <span data-fix="{max2} / {mx}">y</span>.<br><br> <span data-fix="{max3}">x</span> / <span data-fix="{mx}">16</span> = <span data-fix="{max3} / {mx}">y</span>.<br><br> <span data-fix="{max4}">x</span> / <span data-fix="{mx}">16</span> = <input type="text" data-fix="{max4} / {mx}" value="?" />.<br><br> </body> </html>

So for elements that I want to dynamically render a mathematical value, I enclose them in a span tag with an attribute of data-fix. This contains the formula, which is actually something that **eval()** can parse in Javascript. A bit dangerous, if someone were to get into the admin and change a value to something destructive, but then they could do a *heck of a lot more* than just add stuff for eval() statements to hit.

A little javascript magic goes a long way:

$(function(){ var regex = /\{[\w\d\-_]+?\}/gim; $("[data-fix]").each(function(){ var that = $(this); var formula = that.attr("data-fix"); //console.log("formula = " + formula); var rendered = formula.replace(regex, function(match, capture) { var s = match.replace("{", "").replace("}", ""); //console.log("-- s = " + s); var elem = document.getElementById(s); //console.log("-- tag = " + elem.tagName); if (elem == null || elem === undefined) return "null"; var value = $(elem).val() | $(elem).html(); return value; }); //console.log("rendered = " + rendered); var final = eval(rendered); //console.log("final = " + final); if (this.tagName.toLowerCase() == "input" || this.tagName.toLowerCase() == "select") that.val(final); else that.html(final); }); });

What’s going on here is that I’m grabbing all instances of any element that has the data-fix attribute, grabbing the “template” formula, doing any replacing in it as needed, doing an **eval()** on the final formula, and then inserting the value back into the element, one time.

Check out the JS Bin for more details and to play with it!