Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea/
/node_modules
/server.js
/jquery
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "qunit"]
path = qunit
url = git://github.com/jquery/qunit.git
[submodule "jquery"]
path = jquery
url = git://github.com/jquery/jquery.git
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
dz-7-jquery
===========
# Домашнее задание по jQuery

Домашнее задание по jQuery
Необходимо заменить **все нативные DOM функции** функциями jQuery и заставить работать ваш проект **под IE8+**

Нет IE8? - http://www.my-debugbar.com/wiki/IETester/HomePage

## Обратить внимание

* `innerHTML` -> `$().text(), $().html()`
* `querySelectorAll, getElementById` -> `$('#selector')`
* `JSON.*` -> полифилл https://github.com/douglascrockford/JSON-js/blob/master/json2.js
* `XMLHttpRequest` -> `$.get(), $.post()`
* `[].map(), [].forEach(), [].filter()` -> полифилл https://github.com/kriskowal/es5-shim или underscore.js (lowdash.js)
* `addEventListener` -> `$().on('click', function () {})` или `$().click(function () {})`
* ваш основной .js файл обвернуть в DOMReady `$(function () { /*your code*/ });`
* генерацию HTML `createElement` заменить на шаблоны http://ejohn.org/blog/javascript-micro-templating/ или http://api.jquery.com/jquery.tmpl/ или любой другой
158 changes: 158 additions & 0 deletions Scripts/BaseEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
(function (toExport) {
"use strict";
/**
* Создает оболочку над массивом событий, предоставляющую "sql" подобные операции
*
* @class Оболочка над массивом событий.
* @augments Collection
*/
var BaseEvent = function BaseEvent(events) {
"use strict";
Collection.call(this, events);
};

toExport.BaseEvent = BaseEvent;

BaseEvent.prototype = Object.create(Collection.prototype, {
constructor: {
value: BaseEvent,
enumerable: false,
writable: true,
configurable: true
}
});
/**
*
*@field {BaseEvent} - ссылка на "родной" конструктор
*/
BaseEvent.prototype.constructor = BaseEvent;
/**
*@function Возвращает новую оболочку, но уже только с прошедшими событиями
*
*@return {BaseEvent}
*/
BaseEvent.prototype.pastEventBase = function () {
var currentDate = new Date();
return this.filter(function (event) {
return event.end.getTime() < currentDate.getTime();
});
};
/**
* @function Возвращает новую оболочку, но уже только с ненаступившими событиями
*
* @return {BaseEvent}
*/
BaseEvent.prototype.nextEventBase = function () {
var currentDate = new Date();
return this.filter(function (event) {
return event.start.getTime() > currentDate.getTime();
});
};
/**
* @function Возвращает новую оболочку, но уже с событиями, которые идут в данный момент
*
* @return
*/
BaseEvent.prototype.nowEventBase = function () {
var currentDate = new Date();
return this.filter(function (event) {
return (event.start.getTime() <= currentDate.getTime() && event.end.getTime() >= currentDate.getTime());
});
};

/**
* @function Возвращает новую оболочку, но уже с событиями, в которых участвует определенный человек
*
* @return
*/
BaseEvent.prototype.withFriend = function (myFriend) {
return this.filter(function (event) {
return event.parties.some(function (party) {
return party.name === myFriend.name;
});
});
};

/**
* @function Возвращает новую оболочку, но уже с событиями, которые будут в определенный период
*
* @param {Date} fromDate - начала периода
* @param {Date} toDate - конец периода
*
* @return
*/
BaseEvent.prototype.getEventFromPeriod = function (fromDate, toDate) {
return this.filter(function (event) {
return (event.start.getTime() > fromDate.getTime() && event.end.getTime() < toDate.getTime());
});
};

/**
* @function Возвращает новую оболочку, но уже с событиями, которые стоят не меньше min и не больше max
*
* @param {Number} min - начала периода
* @param {Number} max - начала периода
*
* @return {BaseEvent}
*/
BaseEvent.prototype.getEventWithCost = function (min, max) {
return this.filter(function (event) {
return (event.cost >= min && event.cost <= max);
});
};

/**
* @function Компаратор рейтинга по убыванию
* @private
*
* @field {Date} a
* @field {Date} b
*
* @return {Number}
*/
var starsComparer = function compare(a, b) {
if (a.stars > b.stars) {
return -1;
}
if (a.stars < b.stars) {
return 1;
}
return 0;
};
/**
* @function Возвращает новую оболочку c теми же событиями, но отсортированными по уменьшению количества звезд
*
* @return {BaseEvent}
*/
BaseEvent.prototype.sortByStars = function (ascending) {
return this.sortBy(starsComparer, ascending);
};

/**
* @function Компаратор дат по возрастанию
* @private
*
* @field {Date} a
* @field {Date} b
*
* @return {Number}
*/
var dateComparer = function (a, b) {
if (a.start.getTime() < b.start.getTime()) {
return -1;
}
if (a.start.getTime() > b.start.getTime()) {
return 1;
}
return 0;
};

/**
* @function Возвращает новую оболочку c теми же событиями, но отсортированными по дате
*
* @return {BaseEvent}
*/
BaseEvent.prototype.sortByDate = function (ascending) {
return this.sortBy(dateComparer, ascending);
};
}(window));
119 changes: 119 additions & 0 deletions Scripts/Calendar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
(function (toExport) {
"use strict";
/**
*
* @param {jQuery} $factory объект, содержащий фабрику событий
* @param {jQuery} $filter объект, содержащий различные фильтры
* @param {jQuery} $table
* @param {String} baseUrl
* @constructor контроллер каландаря
*/
var Calendar = function ($factory, $filter, $table, baseUrl) {
var cloneCalendar = this;
this.factory = new FactoryEvent($factory);
this.filter = new FilterEventBase($filter);
this.table = new TableEventBase($table);

this.loadBase(baseUrl);
this.factory.WriteDefaultEvent();

this.factory.$container.find("input[type = text], input[type = date]").on("blur", function () {
cloneCalendar.factory.eventValidation();
});

this.factory.$container.find("#SubmitNewEventButton").on("click", function () {
var eventObj = cloneCalendar.factory.readEvent(),
errors = Event.isValidate(eventObj),
isCritical = errors.some(function (element) {
return element.isCritical;
});
cloneCalendar.factory.eventValidation();
if (!isCritical) {
if (errors.length !== 0 ) {
if (confirm('Некоторые незначительные поля некорректны, продолжить?')) {
cloneCalendar.saveNewEvent(baseUrl, eventObj);
alert("УИИИ!!!");
}
}
else {
cloneCalendar.saveNewEvent(baseUrl, eventObj);
alert("УИИИ!!!");
}
}
});
//todo это гомосятина ! но почему то у input type = radio, нет события blur
this.filter.$container.find("input").on("click", function () {
var newBaseEvent = cloneCalendar.filter.apply(cloneCalendar.baseEvent);
cloneCalendar.table.updateTable(newBaseEvent);
});
this.filter.$container.find("input").on("blur", function () {
var newBaseEvent = cloneCalendar.filter.apply(cloneCalendar.baseEvent);
cloneCalendar.table.updateTable(newBaseEvent);
});
};
toExport.Calendar = Calendar;
Calendar.prototype = Object.create(Model.prototype, {
constructor: {
value: Event,
enumerable: false,
writable: true,
configurable: true
}
});
/**
* @function Загрузить по url базу событий
* @param baseUrl {String} url
*
*/
Calendar.prototype.loadBase = function (baseUrl) {
var calendar = this,
i,
events;
$.getJSON(baseUrl, function (date) {
events = [];
for (i = 0; i < date.items.length; i += 1) {
var item = date.items[i];
events.push(new Event({
"start": new Date(item.start),
"end": new Date(item.end),
"name": item.name,
"gps": {
"x": parseFloat(item.gps.x),
"y": parseFloat(item.gps.y)
},
"cost": parseFloat(item.cost),
"stars": parseInt(item.stars),
"parties": item.parties
}));
}
calendar.baseEvent = new BaseEvent(events);
calendar.table.updateTable(calendar.baseEvent);
});
};
/**
*
* @param {String} saveUrl url
* @param {Object} newEvent новое событие похожий на Event.
* @function отправляет json с новым событием на сервер
*/
Calendar.prototype.saveNewEvent = function (saveUrl, newEvent) {
var cloneCalendar = this;
$.post(saveUrl ,newEvent)
.done(function () {
cloneCalendar.baseEvent.items.push(new Event(newEvent));
var newBaseEvent = cloneCalendar.filter.apply(cloneCalendar.baseEvent);
cloneCalendar.table.updateTable(newBaseEvent);
cloneCalendar.factory.WriteDefaultEvent();
console.log("Данный удачно сохранились");
})
.fail(function () {
alert("Данные не сохранились. Позвоните в тех поддержку");
console.log("Данные не сохранились");
});
//todo убрать все что ниже как добавиться сервер. Тк будет дублирование
cloneCalendar.baseEvent.items.push(new Event(newEvent));
var newBaseEvent = cloneCalendar.filter.apply(cloneCalendar.baseEvent);
cloneCalendar.table.updateTable(newBaseEvent);
cloneCalendar.factory.WriteDefaultEvent();
};
}(window));
70 changes: 70 additions & 0 deletions Scripts/Collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(function(toExport) {
"use strict";
/**
* Создает оболочка для хранения массива объектов с операциями по извлечению более конкретных элементов
* @class Оболочка для храения массива объектов
*
* @param {Array} otherItems элементы коллекции
*/
var Collection = function (otherItems) {
"use strict";
var item;
this.items = [];
for (item in otherItems) {
if (otherItems.hasOwnProperty(item)) {
this.items.push(otherItems[item]);
}
}
};
toExport.Collection = Collection;
/**
* @field {Collection} хранит ссылку на родной конструктор
*/
Collection.prototype.constructor = Collection;
/**
* @function создает новую коллекцию элементов с теме же элементами + с новым элементом obj
*
* @return {Object} instanceof this.constructor
*/
Collection.prototype.add = function (obj) {
var newEvents = this.items.concat([obj]);
return new this.constructor(newEvents);
};
/**
* @function создает новую коллекцию элементов с отфильтрованными элементами
*
* @param {Function} selector делегат
*
* @return {Object} instanceof this.constructor
*/
Collection.prototype.filter = function (selector) {
var newItems = this.items.filter(selector);
return new this.constructor(newItems);
};
/**
* @function создает новую коллекцию элементов с теме же элементами + с новым элементом obj
*
* @param {Function} comparator компаратор
* @param {Function} isInvert инвертировать, ли результат
*
* @return {Object} instanceof this.constructor
*/
Collection.prototype.sortBy = function (comparator, isInvert) {
var newItems = [].concat(this.items);
if (newItems.length === 0) {
return [];
}
if (comparator) {
if (isInvert) {
newItems.sort(function (a, b) {
return -1 * comparator(a, b);
});
} else {
newItems.sort(comparator);
}
} else {
newItems.sort();
}
return new this.constructor(newItems);
};
}(window));
Loading