Tag Archives: coffeescript

webmastering

Function overloading in JavaScript

I won’t talk about PHP today. Sorry PHPers. If you do some fron­tend job, you won’t be disap­po­in­ted. I’m assu­ming you know some basic Java­Script stuff like closu­res, proto­ty­ping and context swit­ching, because I’m going to do some cheating.

Our goal for today is to force Java­Script to invoke diffe­rent func­tions accor­ding to diffe­rent argu­ments number. To further compli­cate all of this, we’ll work on proto­ty­pes and check if over­lo­ading works on inhe­ri­ted objects.

I’ll use Coffe­eScript since it has nice, conden­sed syntax. You don’t need to write much JS boiler­plate like semi­co­lons and braces, what leads to about 30% less code in CS <-> JS compa­ri­son. Always remem­ber: Coffe­eScript is just Java­Script and you can simple paste it in Try Coffe­eScript’s section to see the JS compi­led result. Don’t worry, i’ll provide some hints in sensi­tive places.

Most impor­tant things for today are:

  • you can always check how many argu­ments func­tion has in its decla­ra­tion using length property,
  • you can always check how many argu­ments func­tion was invo­ked with by using arguments.length property.


A few ending thoughts:

  • augmen­ting methods have some perfor­mance penalty,
  • you’ll proba­bly compli­cate stuff when use over­lo­ading too much,
  • if you truly need that solu­tion in JS, you’re doing some­thing wrong :-)
webmastering

Creating EAN-13 barcode using CoffeeScript and HTML5 Canvas

It’s been a long time since I’ve writ­ten my last english-spoken text. It was about Webwor­kers API. The visi­tors number has been achie­ved, so it’s time for the next topic. Now I’m going to talk about Canvas and some Coffe­eScript tricks. Again I’m asking You to forgive me my „langu­age glitches”.

Since I don’t like to get to know about some­thing new in an abstract way, we’ll going to write a simple EAN-13 barcode gene­ra­tor. You meet it at every store, it saves time and money for merchants. Price can be atta­ched to barcode instead of price tags. Imagine chan­ging a price in the same 100 products. But how to gene­rate one? Wiki­pe­dia has a nice descrip­tion. EAN-13 is compo­sed of GS1 orga­ni­za­tion numbers, company numbers, item refe­rence and check digit.

This time I’m going to cover some Coffe­Script featu­res I didn’t talk about 2 posts earlier: exten­ding clas­ses and static proper­ties. I’ll write one class compu­ting „0101…” EAN-13 code and another one capa­ble of drawing the code on HTML canvas element. I even created a public GitHub repo­si­tory, so feel free to steal some code. Working exam­ple can be found here.

I won’t explain You all code here, only the most impor­tant parts. For exam­ple how to compute control digit?

computeControlSum: ->
  sum = 0
 
  # this one line of array comprehension substitutes four lines in pure JS
  sum += (if key % 2 then 3 else 1) * value for value, key in @eanArray
  controlSum = 10 - sum % 10
  if controlSum == 10 then controlSum = 0
  return controlSum

Piece of code above is trans­la­ted into:

EAN13Generator.prototype.computeControlSum = function() {
  var controlSum, key, sum, value, _i, _len, _ref;
  sum = 0;
  _ref = this.eanArray;
  for (key = _i = 0, _len = _ref.length; _i < _len; key = ++_i) {
    value = _ref[key];
    sum += (key % 2 ? 3 : 1) * value;
  }
  controlSum = 10 - sum % 10;
  if (controlSum === 10) {
    controlSum = 0;
  }
  return controlSum;
};

As we can see we don’t need to worry about some tempo­rary varia­bles in CoffeScript.

Digits 2–7 in barcode (before the central „whiskers”) can be writ­ten as odd or even. Pattern depends on first barcode digit. It has been writ­ten as object literal:

class EAN13Generator
 
# some code here
 
  # this is how we create class properties
  # we can call to such property like EAN13Generator.LEFT_SIDE_CODING
  @LEFT_SIDE_CODING:
    0: ['odd', 'odd',  'odd',  'odd',  'odd',  'odd' ]
    1: ['odd', 'odd',  'even', 'odd',  'even', 'even']
    2: ['odd', 'odd',  'even', 'even', 'odd',  'even']
    3: ['odd', 'odd',  'even', 'even', 'even', 'odd' ]
    4: ['odd', 'even', 'odd',  'odd',  'even', 'even']
    5: ['odd', 'even', 'even', 'odd',  'odd',  'even']
    6: ['odd', 'even', 'even', 'even', 'odd',  'odd' ]
    7: ['odd', 'even', 'odd',  'even', 'odd',  'even']
    8: ['odd', 'even', 'odd',  'even', 'even', 'odd' ]
    9: ['odd', 'even', 'even', 'odd',  'even', 'odd' ]

The next inte­re­sing part is how to conca­te­nate barcode string. Here’s how:

generateEANcode: ->
 
  # we're using class property to find out first 6 digits coding
  codingStyle = EAN13Generator.LEFT_SIDE_CODING[@eanArray[0]]
  eanCode = EAN13Generator.START_SENTINEL
  for i in [1..6]
    if codingStyle[i-1] == 'odd'
      eanCode += EAN13Generator.EAN_13_CODE_TABLE[@eanArray[i]].left.odd
    else
      eanCode += EAN13Generator.EAN_13_CODE_TABLE[@eanArray[i]].left.even
  eanCode += EAN13Generator.CENTRAL_SENTINEL       
  eanCode += (EAN13Generator.EAN_13_CODE_TABLE[@eanArray[i]].right) for i in [7..12]
  eanCode += EAN13Generator.END_SENTINEL

Class exten­sion is reali­zed thro­ugh extends keyword.

class EAN13CanvasDrawer extends EAN13Generator
 
  # @canvasId is shorthand for @canvasId = canvasId
  constructor: (eanString, @canvasId) ->
 
    # we're launching EAN13Generator constructor
    super(eanString)

I’m using jCanva­Script JS library to draw on canvas. Below is the whole draw­Bar­code() method:

drawBarcode: ->
  jc.clear @canvasId
  jc.start @canvasId
  splitArray = @generateEANcode().split ''   
  barStartActual = @barStartX  
  for i, key in splitArray
    barHeightActual = @barHeight
 
    # barcode longer 'whiskers'
    if key in [0,1,2,45,46,47,48,49,92,93,94] then barHeightActual = @barLongerHeight
 
    # draw white stripe
    if i == '0'
      jc.rect barStartActual, @barStartY, @barWidth, barHeightActual, 'rgb(255,255,255)', true
    else
      jc.rect barStartActual, @barStartY, @barWidth, barHeightActual, 'rgb(0,0,0)', true
  barStartActual += @barWidth    
  jc.start @canvasId
 
  # drawing numbers below the stripes
  textStartActual = @textStartX
  for i, key in @eanArray
    if key in [1,7] then textStartActual += @textBreak
    jc.text(i, textStartActual, @textStartY).font "#{@textSize}px courier bold"
    textStartActual += @textStep
  jc.start @canvasId

The final execu­tion of code is just as simple as:

barcodeDrawer = new EAN13CanvasDrawer $('input#ean_13').val(), 'canvas_1'
barcodeDrawer.drawBarcode()
webmastering

Testowanie localStorage, embedded gist i CoffeeScript

Mamy niedzielę, więc warto trochę popro­gra­mo­wać dla sportu (oczy­wi­ście zamiast upra­wia­nia „normal­nego” sportu :-) ). Z głupoty chcia­łem rozpra­co­wać kilka rzeczy. Przede wszyst­kim wpra­wić się trochę w Coffe­eScript, a przy okazji spraw­dzić w dzia­ła­niu zapi­sy­wa­nie danych po stro­nie prze­glą­darki przy użyciu local­Sto­rage.

Moim dzisiej­szym zamia­rem było stwo­rze­nie strony z formu­la­rzem, w którym wpisy­wane warto­ści zapi­sy­wa­łyby się na bieżąco po stro­nie prze­glą­darki wpisu­ją­cego. Powiedzmy, że jakaś sierotka podczas wypeł­nia­nia formu­la­rza zamknie kartę/przeglądarkę i całe mozolne wpisy­wa­nie poszło w las. Dzięki local­Sto­rage wpisane dane nie zostaną skaso­wane, a formu­larz wypełni się auto­ma­tycz­nie. Oczy­wi­ście niesie to za sobą szereg niebez­pie­czeństw, jak np. co w przy­padku kogoś korzy­sta­ją­cego z publicz­nego kompu­tera, chcą­cego zamó­wić coś w skle­pie inter­ne­to­wym i mu się nagle „odwi­dzi”? Następna osoba dosta­nie dane osobowe poprzed­nika na tacy. Mini­mal­nym zabez­pie­cze­niem byłby mecha­nizm kasu­jący dane jeśli są sprzed dłużej niż np. 2 minut.

Dodat­kowo chcia­łem zrobić przy­cisk, który daje jakąś kontrolę nad prze­cho­wy­wa­nymi danymi. Efekt można sobie oglą­dać tutaj.

Używana przeze mnie wtyczka do kolo­ro­wa­nia składni (WP-Syntax) nie obsłu­guje CS. Zamiast tego kod umiesz­czę za pomocą embed­ded gist z GitHub. Efekt jest bardzo ładny. Poni­żej „mózg” formu­la­rza:

Efektu kompi­la­cji nie poka­zuję. Jeśli ktoś bardzo chce to może sobie podej­rzeć plik storager.js.

Jeśli szukasz biblio­teki backupu danych formu­la­rza w czasie rzeczy­wi­stym opar­tego o local­Sto­rage to pole­cam wtyczkę jQuery: Sisy­phus.