Skip to content
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "qunit"]
path = qunit
url = git://github.com/jquery/qunit.git
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: node_js
node_js:
- "0.8"
- "0.6"

21 changes: 21 additions & 0 deletions XHRobject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(function (exports) {
"use strict";

exports.asyncXHR = function (method, url, callback, data) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);

xhr.addEventListener('readystatechange', function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, xhr.responseText);
}
else {
callback("error");
}
}
}, false);

xhr.send(data);
}
}(window));
91 changes: 91 additions & 0 deletions collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
(function (exports) {
"use strict";

var Collection = function (items) {

this.items = [];
var key;

for (key in items) {
if (items.hasOwnProperty(key)) {
this.items.push(items[key]);
}
}
};

exports.Collection = Collection;

Collection.prototype.constructor = Collection;

/**
* Сериализует коллекцию
*
* @return {JSON object}
*
*/
Collection.prototype.serialise = function () {
return JSON.stringify(this.items, 3);
}

/**
* Добавляет в коллекцию объект
*
* @param {object} model
*
* @return {Collection} * @example
*
*/
Collection.prototype.add = function (model) {

var temp = new this.constructor(this.items);
temp.items.push(model);
return temp;
};

/**
* @param {Function} selector
*
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
*
* @example
* new Collection().filter(function (item) {
* return item.get('attendee').indexOf("me") !== -1;
* });
* @return {Collection}
*/
Collection.prototype.filter = function (selector) {

if (typeof selector !== "function") {
throw new Error('Argument must be function');
}

return new this.constructor(this.items.filter(selector));
};

/**
* Принимает функцию сортировки и сортирует на основе ее
*
* @param {function} selector
*
* @return {Collection} * @example
*
*/
Collection.prototype.sort = function (selector) {

if (typeof selector !== "function") {
throw new Error('Argument must be function');
}

return new this.constructor(this.items.sort(selector));
};

Collection.prototype.reverse = function () {

return new this.constructor(this.items.reverse());
};

Collection.prototype.length = function (selector) {

return this.items.length;
};
}(window));
5 changes: 4 additions & 1 deletion current-event.json
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
[{"name":"pewpew","start":"2012-11-07T10:18:39.207Z","end":"2012-11-07T10:18:39.207Z"}]
[
{"name":"pewpew","start":"2012-11-07T10:18:39.207Z","end":"2012-11-07T10:18:39.207Z"},
{"name":"Пара по веб-технологиям","start":"2012-11-20T12:50:40.207Z","end":"2012-11-20T12:50:50.207Z","location":"5 этаж","remindTime":10,"description":"Взять бумагу и ручку, не брать бук!"}
]
233 changes: 233 additions & 0 deletions documentAction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
(function (exports) {
"use strict";

var ListOfEvents = new Events();
var sortedList = new Events();

var filterOption = "all";
var sortOption = "without";

document.body.addEventListener('load', initialise(), false);

function initialise() {
asyncXHR('GET','http://yunnii.github.com/dz-6-async/current-event.json', restoreState, null);
}

/**
* Загружает свое состояние с сервера
* при отсутсвии соединения/страницы на сервере пытается подключиться через 5 минут снова
*
*/
function restoreState(error, json) {

document.querySelector("#notify").style.visibility = 'hidden';

if (error === "error") {
document.querySelector("#notifyError").visibility = 'visible';
return;
}

var parseObject = JSON.parse(json);

for (var i=0; i < parseObject.length; i++) {
var newEvent = new Event(parseObject[i]).validate();
ListOfEvents = ListOfEvents.add(newEvent);
};

changeDocument("sort");
addListener();
}

/**
* Добавляет новое событие в список. Если установлены опции фильтрации и сортировки
* - то располагает элменты на странице, в с-ии с ними
*
*/
function preventDefault() {

var name = document.querySelector("#title").value,
start = document.querySelector("#from").value,
end = document.querySelector("#to").value,
location = document.querySelector("#location").value,
raiting = document.querySelector("#raiting").value,
description = document.querySelector("#description").value,
remindTime = document.querySelector("#remindTime").value;

if (!validateTitle(name, document.querySelector('#title_help'))) { alert("Событие не было добавлено. Ошибка"); return; };
if (!validateDate(start, document.querySelector('#from_help'))) { alert("Событие не было добавлено. Ошибка"); return; };
if (!validateNumber(remindTime, document.querySelector('#remindTime_help'))) { alert("Событие не было добавлено. Ошибка"); return; };

var element = new Event({
name: name,
start: start,
end: end,
location: location,
raiting: raiting,
description: description,
remindTime: remindTime
}).validate();

var result = ListOfEvents.add(element);
var data = result.serialise();

asyncXHR('POST','http://localhost:8080/current-event.json', function(error) {

/*if (error === "error") {
alert("Не могу подключиться к северу. Попробуйте позже");
return;
}*/

ListOfEvents = result;
changeDocument("sort");
document.forms["form"].reset();
}, data);
};

function filterEvents(listEvents) {
switch (filterOption) {
case "future":
return listEvents.coming();
case "past":
return listEvents.past();
default:
return listEvents;
}
}

function sortEvents(listEvents) {
switch (sortOption) {
case "byName":
return ListOfEvents.sortByName();
case "byStart":
return ListOfEvents.sortByTime();
case "byRaiting":
return ListOfEvents.sortByRaiting();
default:
return ListOfEvents;
}
}

/**
* Сортирует и фильтрует события в соответствии с указанными опциями.
*
* @param {string} changeType - если указана строка "sort", то события также будут отсортированы,
* инчае - только отфильтрованы
* @return коллекция объектов типа event
*/

function changeDocument(changeType) {
var parent = document.querySelector(".collection"),
removeList = document.querySelector(".events");
parent.removeChild(removeList);

var addList = document.createElement('ul');
addList.className = "events";

var fragment = document.createDocumentFragment();
if (changeType === "sort") {
sortedList = sortEvents(ListOfEvents);
}
var filterList = filterEvents(sortedList);

var length = filterList.length();

for (var i = 0; i < length; i++)
{
var element = filterList.items[i];
var el = addLiElement(element);
addList.appendChild(el);
}

var parent = document.querySelector(".collection");
fragment.appendChild(addList);
parent.appendChild(fragment);
}

/**
* Создает DOM-элемент типа li, заполняется полями из объекта
*
* @param {Event} element - объект типа Element
*
* @return Возвращает созданный дом-элемент типа li
*/

function addLiElement (element) {
var el = document.createElement('li');
el.className = 'event_item';

var name = document.createElement('div');
name.textContent = "Название: " + element.name;

var start = document.createElement('div');
start.textContent = "Начало: " + element.start;

var end = document.createElement('div');
end.textContent = "Окончание: " + element.end;

var location = document.createElement('div');
location.textContent = "Местоположение: " + element.location;

var remindTime = document.createElement('div');
remindTime.textContent = "Напомнить за: " + element.remindTime + "минут";

var description = document.createElement('div');
description.textContent = "Описание: " + element.description;

var raiting = document.createElement('div');
raiting.textContent = "Рейтинг: " + element.raiting;

el.appendChild(name);
el.appendChild(start);
el.appendChild(end);
el.appendChild(location);
el.appendChild(remindTime);
el.appendChild(description);
el.appendChild(raiting);

return el;
};

/**
* Навешивает обработчики событий на страницу
*/
function addListener() {
var name = document.querySelector("#title");
var start = document.querySelector("#from");
var remindTime = document.querySelector("#remindTime");
var filters = document.querySelectorAll('.filter');
var sort = document.querySelectorAll('.sort');
var button = document.querySelector("#addButton");

name.addEventListener('blur', function(event) {
var cur = event.currentTarget;
validateTitle(cur.value, document.querySelector('#title_help'));
});

start.addEventListener('blur', function (event) {
var cur = event.currentTarget;
validateDate(cur.value, document.querySelector('#from_help'));
});

remindTime.addEventListener('blur', function (event) {
var cur = event.currentTarget;
validateNumber(remindTime.value, document.querySelector('#remindTime_help'));
});

for (var i=0; i < filters.length; i++) {
filters[i].addEventListener('change', function (event) {
filterOption = document.querySelector('input[name="filter"]:checked').value;
changeDocument("filter");
});
}

for (var i=0; i < sort.length; i++) {
sort[i].addEventListener('change', function(event) {
sortOption = document.querySelector('input[name="sort"]:checked').value;
changeDocument("sort");
});
}

button.addEventListener('click', preventDefault);
}

}(window));
Loading