
Dojo — это модульная библиотека JavaScript. Разработана для простоты и ускорения в построении сайтов с использованием интерактивных систем и AJAX технологий. Разработка данной библиотеки берет свое начало с 2004 года. С версии 1.0. С выходом версии 1.6 dojo начало использоваться в Zend Framework.
Внутренние классы Dojo
Помимо гибкого расширения в разработке и написание собственных объектов, Dojo предлагает к использованию уже большой комплект собственных написанных объектов. В него входит коллекция инпутов, с валидациями и всплывающими окнами, чекбоксы и радио батоны, выпадающие списки и различными возможностями, а также модули для работы с графикой, построение диаграмм, модули грид, локальные хранилища данных, модули для работы с AJAX и еще многое другое.
В версиях 1.10 была выпущенна поддержка работы с мобильными устройствами.
 Также библиотека Dojo поддерживает работу с браузерами:
Поддержка в операционных системах
Dojo и Dijit UI Framework.
 Без сомнения, самым большим преимуществом Dojo Toolkit перед другими JavaScript фреймворками является его Dijit UI фреймворк.
Это беспрецедентный набор лэйаутов, форм и других инструментов:
По мимо выше перечисленных пунктов dojo предлагают пользователям прямо из коробки 5 тем для начальной разработки и построения интерфейсов. Имена шаблонов стиля:
Также, исходя из этих шаблонов возможно написать свой шаблон стилей, который будет подчеркивать индивидуальность.
Модульность и расширяемость
Клиентский JavaScript код, как и любой код, склонен расти в размерах. Модульность является тем ключем, который делает наш код легко поддерживаемым и производительным. Dojo Toolkit является ярким примером фреймворка, использующего модули. Он использует dojo.require для того, чтобы динамически подтягивать только те ресурсы, которые нужны странице в данный момент.
 Dojo использует асинхронный загрузчик, который мастерски загружает все ресурсы асинхронно и намного быстрее, чем в начальных версиях 1.0 — 1.3.
Пример кода:
 // Функция require сообщает загрузчику, что необходимы модули из первого массива
 // Если модуль из списка уже был загружен, то он будет взят из кэша
 require(
 // Массив модулей требующих загрузки [“dojo/on”, “dojo/touch”, “dijit/form/Button”, “dojo/domReady!”],
 // Функция, которая будет вызвана после загрузки всех модулей,
 // с объектами модулей переданными ей в качестве аргументов.
 // Модули должны быть перечислены в том же порядке, что и в массиве требований
 function(on, touch, Button) {
 // Здесь выполняем нужные нам действия с загруженными модулями.
 });
В дальнейшем будет приведен пример – написание собственного модуля системного окна уведомления пользователей.
В то время, как JavaScript не предоставляет настоящей системы классов, Dojo Toolkit предоставляет классоподобный паттерн наследования, основанный на использовании dojo/declare. Declare реализован во фреймворке так, что позволяет разработчикам:
Одной из самых негативных сторон в разработке модулей есть непонимание проблем в возникающих ошибках при удалениях и созданиях новых объектов, так как система оповещения об ошибках с описанием в dojo отсутствует.
Система классов Dojo использует прототипное наследование. Использование dojo/declare невероятно просто:
Пример кода:
define([
 “dojo/_base/declare”, // базовые классы для расширения
 “dijit/_WidgetBase”,
 “dijit/_TemplatedMixin”,
 ‘dijit/_AttachMixin’,
 ‘dijit/_WidgetsInTemplateMixin’,
 “dojo/_base/fx”,
 “dojo/_base/lang”,
“dojo/text!./templates/template1.html”, // путь к используемому шаблону
“dojo/dom-style”, // внутренние классы для работы с структурой DOM
 “dojo/on”,
 “dojo/mouse”,
 “dojo/dom-construct”,
 //подключаемые классы из предоставленых библиотекой dojo компонентов.
 “dijit/form/Button”
 ], function(declare, _WidgetBase, _TemplatedMixin, _AttachMixin, _WidgetsInTemplateMixin, baseFx, lang, template, domStyle,  on, mouse, require, domConstruct,  Button){
 return declare([_WidgetBase, _TemplatedMixin, _AttachMixin, _WidgetsInTemplateMixin], {
 templateString: template,
 description: “”,
 alertType: “”,
 baseClass: “systemAlert”,
 answer: null,
 }
 });
 });
Класс Dojo поддерживает подключение уже готовых встроенных классов, или уже написаных рание. Что позволяет расширять функциональность и дополнять новыми возможностями.
Каждый класс поддерживает создание своего используемого шаблона на основе вертки HTML. Что является еще одним плюсом, так как шаблон можно в любой момент изменить или перестроить под собственные нужды. Тем самым позволяет отделять верстку от создаваемой функциональности.
Пример шаблона:
<div>
 <h3 data-dojo-attach-point=”Nodetitle” class=”${baseClass}title” ></h3>
 <div class=”${baseClass}description”>
 <img class=”${baseClass}image” src=”” data-dojo-attach-point=”Nodemessageimage”>
 <p data-dojo-attach-point=”Nodedescription” class=”alertdescription”>${description}</p>
 <div class=”${baseClass}buttonpanel”>
 <button data-dojo-type=”dijit.form.Button” data-dojo-attach-point=”buttonOk” label=”Ок” data-dojo-attach-event=”click:ok” ></button>
 <button data-dojo-type=”dijit.form.Button” data-dojo-attach-point=”Cancel” label=”Відмінити” data-dojo-attach-event=”click: cancel”></button>
 </div>
 </div>
 </div>
Главным и решающим моментом в создание шаблона является нахождения всего тела шаблона в одном теге. Все внутренные переменные в шаблоне объявляються в формате ${baseClass}. Доступ к определенным узлам в шаблоне фиксинуеться внутринными переменными типа  data-dojo-attach-point = «имя переменной». Для того, чтобы прикрепить к определенному тегу событие, используют внутреннюю переменную data-dojo-attach-event=” «название события»:  «Имя функции» “. Где имя функции описываеться в теле класса:
 data-dojo-attach-event=”click: cancel”
Использование стандартных модулей, а также модулей, написанных в ходе разработки, возможна двумя разными способами. Первый из них является инициализацией объекта через JavaScript:
<script>
 require([“mywidjet/systemAlert”,
 function(systemAlert){
 dojo.byId(“IdName”).appendChild(new  systemAlert({}).domNode);
 });
 </script>
и другой способ, который возможен в виде описания модуля HTML разметкой. Но при этом следует иницализировать стандартный объект dojo.parser, которой распознает в структуре HTML ключевые слова, по которым может создать готовый объект dojo.
<div id=”IdName” data-dojo-type=”mywidjet/systemAlert”></div>
При таком объявлении в параметры тега можно вписывать все нужные значения для работы вашего объекта.
Пример описание инпута с валидацией и текстовым сообщением при не коректном вводе данных.
<script>
 require([“dojo/parser”, “dijit/form/ValidationTextBox”]);
 </script>
 <label for=”phone”>Phone number, no spaces:</label>
 <input type=”text” name=”phone” id=”phone” value=”someTestString” required=”true”
 data-dojo-type=”dijit/form/ValidationTextBox”
 data-dojo-props=”regExp:'[\\w]+’, invalidMessage:’Invalid Non-Space Text.'” />
От теории к практике
Данный пример заключается в написании собственного виджета, расширяемого элементами dijit Ui framework`a, с использованием call-back функций, привязкой событий к виджету и работу с внутренними переменными, а также доступ к ним.
Начнем с самого простого и построим дерево каталогов, в котором будем хранить *.js с нашими виджетами, каталог с шаблонами, каталог с изображениями, каталог для файла с стилями.
Тематика нашего виджета будет предельно простой, это будет окно уведомления пользователя, которое будет в себе вмещать изображение, описание, название (шапку).
Функциональность виджета будет реагировать на нажатия кнопок. Их будет две: для окна, которое будет опрашивать пользователя, и одна кнопка для простого окна уведомления, после которого системное окно будет удаляться.
Начнем с создания каркаса виджета, в него входит создание шаблона, привязку шаблона к виджету, объявление базовых класcов dojo, которые будут расширять наш виджет стандартными функциями, которые присутствуют во всех виджетах dojo.
Пример кода виджета «systemAlert»:
 define([
 “dojo/_base/declare”,
 “dijit/_WidgetBase”,
 “dijit/_TemplatedMixin”,
 “dojo/text!./templates/template1.html”,
 “dojo/dom-style”,
 “dojo/_base/fx”,
 “dojo/_base/lang”,
 “dojo/on”,
 “dojo/mouse”,
 “require”,
 “dojo/dom-construct”,
 ‘dijit/_AttachMixin’,
 ‘dijit/_WidgetsInTemplateMixin’,
 “dijit/form/Button”
 ], function(declare, _WidgetBase, _TemplatedMixin, template, domStyle, baseFx, lang, on, mouse, require, domConstruct, _AttachMixin, _WidgetsInTemplateMixin, Button){
 return declare(“mywidjet/systemAlert”, [_WidgetBase, _TemplatedMixin, _AttachMixin, _WidgetsInTemplateMixin], {
 templateString: template
 }
 });
 });
Выше указанная конструкция служит для построения виджета и привязки шаблона по указанному адресу. Все подключаемые классы в блоке «define» должны быть последовательно объявлены в функцию, которая передастся вторым параметром.
Шаблон, который привязан к виджету:
<div>
 <h3 data-dojo-attach-point=”Nodetitle” class=”${baseClass}title” ></h3>
 <div class=”${baseClass}description”>
 <img class=”${baseClass}image” src=”” data-dojo-attach-point=”Nodemessageimage”>
 <p data-dojo-attach-point=”Nodedescription” class=”alertdescription”>${description}</p>
 <div class=”${baseClass}buttonpanel”>
 <button data-dojo-type=”dijit.form.Button” data-dojo-attach-point=”buttonOk” label=”Ок” data-dojo-attach-event=”click:ok” ></button>
 <button data-dojo-type=”dijit.form.Button” data-dojo-attach-point=”Cancel” label=”Відмінити” data-dojo-attach-event=”click: cancel”></button>
 </div>
 </div>
 </div>
Данная конструкция может быть уже инициализирована и работать. Но без всякой функциональности.
Для примера я приведу следущий код, который заставит виджет показаться на экран =)
 <!DOCTYPE HTML>
 <html>
 <head>
 <meta charset=”utf-8″>
 <title>Тег DIV</title>
<script type=”text/javascript” src=”js/dojo-release/dojo/dojo.js” djConfig=”parseOnLoad:true, isDebug:true”></script>
 <link rel=”StyleSheet” type=”text/css” href=”/js/dojo-release/dijit/themes/claro/claro.css”>
 <link rel=”StyleSheet” type=”text/css” href=”/js/dojo-release/mywidjet/css/systemAlert.css”>
</head>
 <body class=”claro”>
 <div data-dojo-type=”mywidjet/systemAlert” alertType=”question” description=”Тут написаное описание вопроса?”></div>
 </body></html>
 <script>
 require([“dojo/parser”], function(parser){    parser.parse(); });</script>
И получаем картинку нашего уже полуработающего виджета.
И для того, чтобы показать еще второй способ вызвать виджет, опишу кусочек куда:
<script>
 require([“mywidjet/systemAlert”],
 function(systemAlert){
 dojo.byId(“1234”).appendChild(new systemAlert({
 ‘alertType’ : ‘question’,
 ‘description’: “Тут написаное описание вопроса?”
 }).domNode);
 });
 });
 </script>
При выше указаном объявлении мы получим такой же результат, как и в первом случае.
Теперь, когда мы уже описали шаблон и базовый виджет, можно приступить к описанию его функциональности.
Пример кода функционала виджета:
templateString: template, // данная переменная является базовой она отвечает за привязку шаблона к виджету и расширяет параметры виджета, объявленными переменными в шаблоне.
 Description: “”,  // переменная, которая отвечает на описание, которое будет находиться в виджете.
 AlertType: “”, // Отвечает за тип увидомления. Типы виджета описаны в функции PostCreate.
 baseClass: “systemAlert”, // базовый класс виджета для применения стиля
 answer: null, // call-back функция для получения ответа от пользователя
ok: function() // функция, которая вызывается при нажатии на кнопку «OK»
 {
 if(typeof(this.answer) == “function”) //call-back функция, которая отвечает за ответ пользователя.
 this.answer(true);
 },
cancel: function(){ // функция, которая вызывается при нажатии на кнопку «Відміна»
 if(typeof(this.answer) == “function”)
 this.answer(false);
 },
 constructor: function (args){ // базовая  функция. Являеться точкой начала создания виджета
 if(args){
 lang.mixin(this,args);
 }
 },
// базовая функция, которая выполняется после функции констракт и выводит инициализированый объект в HTML разметку.
 postCreate: function() {
 switch(this.alertType) // обращение к переменой в теле виджета.
 {
 case “informing”: {
 this.Nodetitle.innerHTML = “Інформування”; // переменная, которая     подтягивается с шаблона виджета.
 this.Nodemessageimage.src = require.toUrl(“./image/informing.png”);
 domStyle.set(this._startupWidgets[1].domNode, “display”, “none”); /* this._startupWidgets[1] this is button cancel*/
 break;
 }
 case “error”: {
 this.Nodetitle.innerHTML = “Помилка”;
 this.Nodemessageimage.src = require.toUrl(“./image/error.png”);
 domStyle.set(this._startupWidgets[1].domNode, “display”, “none”); /* this._startupWidgets[1] this is button cancel*/
 break;
 }
case “success”: {
 this.Nodetitle.innerHTML = “Успішно”;
 this.Nodemessageimage.src = require.toUrl(“./image/success.png”);
 domStyle.set(this._startupWidgets[1].domNode, “display”, “none”); /* this._startupWidgets[1] this is button cancel*/
 break;
 }
 case “question”: {
 this.Nodetitle.innerHTML = “Видійсно хочете виконати данну операцію?”;
 this.Nodemessageimage.src = require.toUrl(“./image/question.png”);
 break;
 }
 case “warning”: {
 this.Nodetitle.innerHTML = “Попередження”;
 this.Nodemessageimage.src = require.toUrl(“./image/warning.png”);
 domStyle.set(this._startupWidgets[1].domNode, “display”, “none”); /* this._startupWidgets[1] this is button cancel*/
 break;
 }
 default: break;
}
 Данный пример направлен на поверхносное ознакомление с структурой работы dojo library и построение собсвенных виджетов и их работа.