Advanced CSS: Using Sass Maps for UI Components
Sass is a great and very popular CSS preprocessor. If you are not familiar with it, take a look at these lessons. Associative arrays (Maps) are an extremely underrated feature…

Continue reading →

Website framework, or modular grid in web design
What is a modular grid? I will explain with an example familiar to you. Open any paper book. You see, the text passing through the entire width of the page,…

Continue reading →

Effective web design - what is it?
If you want to achieve serious heights and build a successful career as a web designer, then you definitely need to know the key criteria for evaluating the effectiveness of…

Continue reading →

SOLID principles in JavaScript. Open-closed principle

The essence of the principle
The principle of openness-closeness is as follows:

“Software entities (classes, modules, functions, etc.) must be open for expansion, but closed for change.”

That is, the application architecture should allow changing the behavior of certain entities without changing their source code.

This principle is especially important for large business applications, when requirements change, functionality expands or changes, which can lead to a lot of unexpected changes. A cascade of changes entails, in turn, labor costs for testing and unpleasant unpredictable errors.

JavaScript open-close principle
To illustrate the principle of openness-closedness in JavaScript, consider an example that implements a simple survey:

Javascript
/ **
* Types of questions (an object containing possible types of questions)
* /
var AnswerType = {
Choice: 0,
Input: 1
};

/ **
* Question
* /
function question (label, answerType, choices) {
return {
label: label,
answerType: answerType,
choices: choices
};
}

/ **
* Presentation object
* /
var view = (function () {
/ **
* Function display one question
* /
function renderQuestion (target, question) {
var wrapper = $ (‘<div class = “question”> </div>’),
label = $ (‘<div class = “question-label”> </div>’),
answer = $ (‘<div class = “question-input”> </div>’);

label.html (question.label);

if (question.answerType === AnswerType.Choice) {
var input = $ (‘<select> </select>’);
var len = question.choices.length;
for (var i = 0; i <len; i ++) {
var option = $ (‘<option> </option>’);
option.text (question.choices [i]);
option.val (question.choices [i]);
input.append (option);
}
}
else if (question.answerType === AnswerType.Input) {
var input = $ (‘<input type = “text” />’);
}

answer.append (input);
wrapper.append (label);
wrapper.append (answer);
target.append (wrapper);
}

return {
/ **
* Question list display function
* /
render: function (target, questions) {
for (var i = 0; i <questions.length; i ++) {
renderQuestion (target, questions [i]);
};
}
};
}) ();

var questions = [
question (‘Your age’, AnswerType.Input),
question (‘Do you like science fiction?’, AnswerType.Choice, [‘Yes’, ‘No’]),
question (‘How many hours per week do you spend on average reading fiction?’, AnswerType.Choice, [‘less than an hour’, ‘2-5 hours’,’ 5-8 hours’, ‘9-15 hours’,’ more than 15 hours’])
];

var questionContainer = $ (‘# questions’);
view.render (questionContainer, questions);
In the example above, the view object has a render () method, which takes a container object and an array of questions and displays each question in turn. Everything seems to be logical, however, adding a new type of question requires changing the render () method, which contradicts the principle of openness-closeness.

Now consider another example where this point is fixed:

Javascript
/ **
* Abstract object displaying a question
* /
function questionCreator (params) {
var that = {};

that.renderInput = function () {
throw “Not implemented”;
};

that.render = function (target) {
var wrapper = $ (‘<div class = “question”> </div>’),
label = $ (‘<div class = “question-label”> </div>’),
answer

label.html (params.label);
answer = that.renderInput ();

wrapper.append (label);
wrapper.append (answer);

return wrapper;
};

return that;
}

/ **
* The object that displays the question with the type of answer is a drop-down list
* /
function choiceQuestionCreator (params) {
var that = questionCreator (params);

that.renderInput = function () {
var input = $ (‘<select> </select>’);
var len = params.choices.length;
for (var i = 0; i <len; i ++) {
var option = $ (‘<option> </option>’);
option.text (params.choices [i]);
option.val (params.choices [i]);
input.append (option);
}

return input;
};

return that;
}

/ **
* An object displaying a question with an answer type – input field
* /
function inputQuestionCreator (params) {
var that = questionCreator (params);

that.renderInput = function () {
var input = $ (‘<input type = “text” />’);
return input;
};

return that;
}

var view = {
render: function (target, questions) {
for (var i = 0; i <questions.length; i ++) {
target.append (questions [i] .render ());
}
}
};

var questions = [
inputQuestionCreator ({
label: ‘Your age’
}),
choiceQuestionCreator ({
label: ‘Do you like science fiction?’,
choices: [‘Yes’, ‘No’]
}),
choiceQuestionCreator ({

Visual Regression Testing with PhantomCSS
If you worked on large, serious projects, you probably already felt the importance of automated testing during the development process. Depending on experience, this awareness may come suddenly like a…

...

What is web design and what does it eat?
When I ask new friends about how I earn my bread, I have to answer twice. At first, it sounds proudly from my lips: “Web designer”, which flies to me…

...

How much does a web designer earn on freelance and in studios?
No matter how interesting the web design, most people go there not because of this, but because of financial attractiveness. This direction is quite profitable after the accumulation of a…

...

Features of the profession and key responsibilities of a web designer
To make it easier to understand the main tasks of the representative of this craft, for a start it is worth considering its basic definition. The profession of "web designer"…

...