Skip to content

Четвертое ДЗ #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
53 changes: 53 additions & 0 deletions collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var Collection = (function () {
'use strict';
var Collection = function (items) {
var item;
this.items = [];
for (item in items) {
if (items.hasOwnProperty(item)) {
if (items[item].validate().valid) {
this.items.push(items[item]);
}
}
}
};

/**
* @return {Collection}
*/
Collection.prototype =
{
add : function (model) {
this.items.push(model);
},
/**
* Фильтрация коллекции по правилам, определенным в функции selector
*
* @param {Function} selector
*
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
*
* @return {Collection}
*/
filter : function (selector) {
var tmp = this.items.filter(selector);
return new this.constructor(tmp);
},
/**
* Сортировка коллекции по правилам, определенным в функции selector
*
* @param {Function} selector
* @param {Boolean} desc
*
* @return {Collection}
*/
sortBy : function (selector, desc) {
this.items.sort(selector);
if (desc) {
this.items.reverse();
}
return this;
}
};
return Collection;
}());
28 changes: 28 additions & 0 deletions event-collection.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>

<meta charset="utf-8">
<title>EVents test</title>

</head>

<body>

<div class="container">

<input type="button" onclick="console.dir(events.findFutureEvents().findThisWeekEvents());" value = "будущие события недели"/>
<input type="button" onclick="console.dir(events.findFutureEvents().findPartyEvents().sortByStartDate());" value = "будущие пьянки, отсортированные по дате"/>
<input type="button" onclick="console.dir(events.findFutureEvents().findThisWeekEvents().findNightAlarms().sortByNextHappenDate());" value = "события, которые меня разбудят на этой неделе"/>

</div>

<script src="validation.js"></script>
<script src="model.js"></script>
<script src="collection.js"></script>
<script src="event-model.js"></script>
<script src="event-collection.js"></script>
<script src="utils.js"></script>

</body>
</html>
74 changes: 74 additions & 0 deletions event-collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
var Events = (function () {
'use strict';
var Events = function (items) {
Collection.apply(this, arguments);
};
inherits(Events, Collection);

Events.prototype.constructor = Events;
/**
* Возвращает новую коллекцию, содержащую только прошедшие события
* @return {Events}
*/
Events.prototype.findPastEvents = function () {
return this.filter(function (event) {
return event.endDate < new Date();
});
};
/**
* Возвращает новую коллекцию, содержащую только будущие события
* @return {Events}
*/
Events.prototype.findFutureEvents = function () {
return this.filter(function (event) {
return event.startDate > new Date();
});
};
/**
* Возвращает новую коллекцию, содержащую только события этой недели
* @return {Events}
*/
Events.prototype.findThisWeekEvents = function () {
return this.filter(function (event) {
return event.startDate > Utils.getWeekStartDate() && event.startDate < Utils.getWeekEndDate();
});
};
/**
* Возвращает новую коллекцию, содержащую только события 'Drunken feast'
* @return {Events}
*/
Events.prototype.findPartyEvents = function () {
return this.filter(function (event) {
return event.title === 'Drunken feast';
});
};
/**
* Возвращает новую коллекцию, содержащую только те события, напоминание которых сработает ночью
* @return {Events}
*/
Events.prototype.findNightAlarms = function () {
return this.filter(function (event) {
var alarm = event.getNextAlarmTime();
return alarm.getHours() > 0 && alarm.getHours() < 8;
});
};
/**
* Сортирует коллекцию по дате начала события
* @return {Events}
*/
Events.prototype.sortByStartDate = function (asc) {
return this.sortBy(function (a, b) {
return a.startDate - b.startDate;
}, asc);
};
/**
* Сортирует коллекцию по следующей дате периодического события
* @return {Events}
*/
Events.prototype.sortByNextHappenDate = function (asc) {
return this.sortBy(function (a, b) {
return a.getNextHappenDate() - b.getNextHappenDate();
}, asc);
};
return Events;
}());
144 changes: 144 additions & 0 deletions event-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
var Event = (function () {
'use strict';
function checkStartDate(date, validator) {
if (date === null) {
date = new Date();
} else if (!(date instanceof Date && isFinite(date))) {
validator.addError("startDate", "Start date is invalid, check syntax");
date = null;
}
return date;
}

function checkEndDate(endDate, startDate, validator) {
var date;
if (endDate === null) {
date = startDate;
if (date !== null) {
date.setHours(startDate.getHours() + 1);
}
} else if (endDate instanceof Date && isFinite(endDate)) {
if (endDate < startDate) {
validator.addError("endDate", "End date should be after start date");
date = null;
} else {
date = endDate;
}
} else {
validator.addError("endDate", "End date is invalid, check syntax");
date = null;
}
return date;
}

function checkRepeat(repeat, validator) {
if (repeat === null) {
repeat = Const.REPEAT.NEVER;
} else if (!(repeat.title && repeat.value)) {
validator.addError("repeat", "Unknown type of 'repeat' variable");
repeat = null;
} else if (!Utils.checkAddTime(repeat.value)) {
validator.addError("repeat", "Add time in 'repeat' variable must have format '+ dd.MM.YY hh:mm'");
repeat = null;
}
return repeat;
}

function checkAlert(alert, validator) {
if (alert === null) {
alert = Const.ALERT.NONE;
} else if (!(alert.title && alert.value)) {
validator.addError("alert", "Unknown type of 'alert' variable");
alert = null;
} else if (!Utils.checkAddTime(alert.value)) {
validator.addError("alert", "Add time in 'alert' variable must have format '+ dd.MM.YY hh:mm'");
alert = null;
}
return alert;
}
/**
* Создает объект Event
*
* @param {String} [title="New Event"] Имя события
* @param {String} [location] Место события
* @param {Number|Date} [starts="new Date()"] Начало события
* @param {Number|Date} [ends="starts + 1"] Конец события
* @param {Object} [repeat="Const.REPEAT.NEVER"] Периодичность события
* @param {Object} [alert="Const.ALERT.NONE"] Предупреждение
* @param {String} [notes] Заметки
*
* @example
* new Event({title: "Лекция JavaScript",
* location: "УРГУ",
* startDate: new Date('2011-10-10T14:48:00'),
* endDate: new Date('2011-10-10T15:48:00'),
* repeat: REPEAT.WEEK,
* alert: ALERT.B30MIN,
* notes: "Вспомнить, что проходили на прошлом занятии"})
*
* @return {Event}
*/
var Event = function (data) {
Model.apply(this, arguments);
};
inherits(Event, Model);

Event.prototype.constructor = Event;

/**
* Функция, валидирующая объект Event
*
* @return {ValidationResult}
*/
Event.prototype.validate = function () {
var result = new ValidationResult(true);
this.startDate = checkStartDate(this.startDate, result);
this.endDate = checkEndDate(this.endDate, this.startDate, result);
this.repeat = checkRepeat(this.repeat, result);
this.alert = checkAlert(this.alert, result);
result.log();
return result;
};
/**
* Вычисляет когда в следующий раз случится периодическое событие
*
* @return {Date}
*/
Event.prototype.getNextHappenDate = function () {
var nhd, today;
if (!this.nextHappenDate) {
today = new Date();
nhd = this.startDate;
while (nhd < today) {
nhd = Utils.addDateTime(nhd, this.repeat.value);
}
this.nextHappenDate = nhd;
}
return this.nextHappenDate;
};
/**
* Вычисляет следующее время напоминания для периодических событий
*
* @param {Event} event Событие
*
* @return {Date}
*/
Event.prototype.getNextAlarmTime = function () {
var nhd = this.getNextHappenDate();
return Utils.addDateTime(nhd, this.alert.value);
};
/**
* Функция проверяет, нужно ли напомнить о событии
*
* @param {Event} event Событие
*
* @return {Boolean}
*/
Event.prototype.isAlertTime = function () {
var today, diff;
today = new Date();
diff = today - this.getNextAlarmTime();
return diff > -500 && diff < 500;
};
return Event;
}());
52 changes: 52 additions & 0 deletions model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
var Model = (function () {
"use strict";
var Model = function (data) {
var propName;
for (propName in data) {
if (data.hasOwnProperty(propName)) {
this[propName] = data[propName];
}
}

};

Model.prototype =
{
/** Мутатор
* @param {Object} attributes
*
* @example
* item.set({title: "March 20", notes: "In his eyes she eclipses..."});
*/
set : function (attributes) {
var attribute;
for (attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
this[attribute] = attributes[attribute];
}
}
},
/** Аксессор
* @param {String} attribute
*/
get : function (attribute) {
if (this.hasOwnProperty(attribute)) {
return this[attribute];
}
},
/** Валидатор
* @param {Object} attributes
*/
validate : function (attributes) {
console.log('this is Abstract method');
}
};
return Model;
}());

function inherits(Constructor, SuperConstructor) {
"use strict";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можешь поступить как и с утилитами - вынести "use strict"; в IIFE

var F = function () {};
F.prototype = SuperConstructor.prototype;
Constructor.prototype = new F();
}
Loading