BackboneJS, MarionetteJS — how to display chess pieces in the ugliest way

In this post I’ll show how I display chess pieces — in ugly way, which I definitely have to rewrite to use Backbone model instead of HTML manipulation with jQuery.

Job done, chessboard pieces are visible. And only visible

Unicode characters

Fortunately, chessboard pieces can be drawn without any custom fonts or images — they are available as Unicode symbols. How to display them in proper squares?

JQuery to the rescue!

They should be passed to model, then displayed from model… But I didn’t have time. Also, it’s good to practice refactoring from bad solution to good solution, cause it may happen many time in our 9–5 — at least in my opinion.

Calculation in which rows pieces should be displayed

They should be drawn only for chessboard squares, not characters nor numbers:

if (this._isChessboardField()) {
// other code
setTimeout(this._drawChessPiecesInUglyWay.bind(this), 0);
}

setTimeout is used to allow everything to be initialized properly, because it adds task at the end of the loop. One thing mentioned in this MDN article is important, second parameters (miliseconds) indicates minimal delay, not guaranteed delay:

Calling setTimeout will add a message to the queue after the time passed as a second argument. If there is no other message in the queue, the message is processed right away; however, if there are messages, the setTimeout message will have to wait for other messages to be processed. For that reason the second argument indicates a minimum time and not a guaranteed time.

Pieces should be displayed in first and last two rows, which is checked with ugly if:

//white pieces
if (Number(rowNumber) === 8) {
//display piece
}
if (Number(rowNumber) === 7) {
//display pawn
}
//black pieces
if (Number(rowNumber) === 2) {
//display piece
}
if (Number(rowNumber) === 1) {
//display pawn
}

How pieces are displayed? With ugly HTML insert into span:

this.$el.find("span").html(/*piece by square number or pawn*/);

How to decide which piece should be displayed? Another ugly calculation… First, ids have to be set based on position in row, we need to take all squares, transform result to list and then iterate over list and set id:

const elements = this.$el.parent().find("p");
Array.from(elements).forEach(function bindIdInUglyWay(element, index) {
$(element).attr("id", rowNumber + "_" + index);
});

Important note: I use here Array.from() factory method. This nice feature from ES 6 allows us to create pure JS array from array-like objects, like document.querySelectorAll() result, which makes dealing with DOM API much more less painful.
What is bad in this solution, we try to get squares from square :) So, we have to use parent() and find() method. Find() is useful here, cause it traverse only DOM elements inside parent():

Description: Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.

And next, based on generated ids, square number is calculated:

_getFieldNumber: function () {
const id = this.$el.attr("id");
return Number(id.substr(id.length - 1));
},

What is veeery wrong with this solution, ids are calculated… 64 times :) Because they are calculated for every square, so I have to correct it as fast as possible, to wash away this shame :)

Conclusion

It is very basic solution, moreover — it’s useless when it comes to, for example, calculating possible moves for piece. So, in the next post I will prepare displaying pieces for calculating possible moves — probably to extensive usage of Backbone.Model.