diff --git a/package-lock.json b/package-lock.json
index ed83f69..9516d66 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"dayjs": "1.11.7",
"flatpickr": "4.6.13",
+ "he": "1.2.0",
"nanoid": "5.0.3"
},
"devDependencies": {
@@ -4601,7 +4602,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
"bin": {
"he": "bin/he"
}
diff --git a/package.json b/package.json
index 7a16eb7..136a5c4 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"dependencies": {
"dayjs": "1.11.7",
"flatpickr": "4.6.13",
+ "he": "1.2.0",
"nanoid": "5.0.3"
}
}
diff --git a/public/index.html b/public/index.html
index 44c26b4..5297837 100644
--- a/public/index.html
+++ b/public/index.html
@@ -22,7 +22,7 @@
Filter events
-
+
diff --git a/src/const.js b/src/const.js
index f615cd4..2993be9 100644
--- a/src/const.js
+++ b/src/const.js
@@ -20,5 +20,17 @@ const SortType = {
OFFER: 'offer'
};
+const UserAction = {
+ UPDATE_POINT: 'UPDATE_POINT',
+ ADD_POINT: 'ADD_POINT',
+ DELETE_POINT: 'DELETE_POINT',
+};
+
+const UpdateType = {
+ PATCH: 'PATCH',
+ MINOR: 'MINOR',
+ MAJOR: 'MAJOR',
+};
+
-export {NO_POINT_MESSAGES, FiltersValues, SortType};
+export {NO_POINT_MESSAGES, FiltersValues, SortType, UserAction, UpdateType};
diff --git a/src/main.js b/src/main.js
index 280377d..dd3d69c 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,17 +1,43 @@
-import FiltersView from './view/filters-view.js';
-import { render } from './framework/render.js';
import BoardPresenter from './presenter/board-presenter.js';
+import FilterPresenter from './presenter/filter-presenter.js';
import PointsModel from './model/points-model.js';
-import {generateFilter} from './mock/filter.js';
+import FilterModel from './model/filter-model.js';
+import NewPointButtonView from './view/new-point-button-view.js';
+import { render, RenderPosition } from './framework/render.js';
const header = document.querySelector('.trip-main');
const filtersContainer = header.querySelector('.trip-controls__filters');
const main = document.querySelector('.page-main');
const mainContainer = main.querySelector('.trip-events');
const pointsModel = new PointsModel();
-const boardPresenter = new BoardPresenter({boardContainer: mainContainer, pointsModel});
-const filters = generateFilter(pointsModel.points);
+const filterModel = new FilterModel();
-render(new FiltersView({filters}), filtersContainer);
+const boardPresenter = new BoardPresenter({
+ boardContainer: mainContainer,
+ pointsModel,
+ filterModel,
+ onNewPointDestroy: handleNewPointFormClose});
+const filterPresenter = new FilterPresenter({
+ filterContainer: filtersContainer,
+ filterModel: filterModel,
+ pointsModel: pointsModel
+});
+
+const newPointButtonComponent = new NewPointButtonView({
+ onClick: handleNewPointButtonClick
+});
+
+function handleNewPointFormClose() {
+ newPointButtonComponent.element.disabled = false;
+}
+
+function handleNewPointButtonClick() {
+ boardPresenter.createPoint();
+ newPointButtonComponent.element.disabled = true;
+}
+
+render(newPointButtonComponent, header, RenderPosition.AFTEREND);
+
+filterPresenter.init();
boardPresenter.init();
diff --git a/src/model/filter-model.js b/src/model/filter-model.js
new file mode 100644
index 0000000..fb6017f
--- /dev/null
+++ b/src/model/filter-model.js
@@ -0,0 +1,15 @@
+import Observable from '../framework/observable.js';
+import {FiltersValues} from '../const.js';
+
+export default class FilterModel extends Observable {
+ #filter = FiltersValues.EVERYTHING;
+
+ get filter() {
+ return this.#filter;
+ }
+
+ setFilter(updateType, filter) {
+ this.#filter = filter;
+ this._notify(updateType, filter);
+ }
+}
diff --git a/src/model/points-model.js b/src/model/points-model.js
index cbe12f2..9edc690 100644
--- a/src/model/points-model.js
+++ b/src/model/points-model.js
@@ -1,10 +1,11 @@
import { getRandomPoint } from '../mock/points';
+import Observable from '../framework/observable.js';
import { getDestinations } from '../mock/destinations';
import { getOffers } from '../mock/offers';
const POINT_COUNT = 4;
-export default class PointsModel {
+export default class PointsModel extends Observable{
#allOffers = getOffers();
#allDestinations = getDestinations();
#points = Array.from({length: POINT_COUNT}, getRandomPoint);
@@ -21,5 +22,45 @@ export default class PointsModel {
return this.#allOffers;
}
+ updatePoint(updateType, update) {
+ const index = this.#points.findIndex((point) => point.id === update.id);
+
+ if (index === -1) {
+ throw new Error('Can\'t update unexisting Point');
+ }
+
+ this.#points = [
+ ...this.#points.slice(0, index),
+ update,
+ ...this.#points.slice(index + 1),
+ ];
+
+ this._notify(updateType, update);
+ }
+
+ addPoint(updateType, update) {
+ this.#points = [
+ update,
+ ...this.#points,
+ ];
+
+ this._notify(updateType, update);
+ }
+
+ deletePoint(updateType, update) {
+ const index = this.#points.findIndex((point) => point.id === update.id);
+
+ if (index === -1) {
+ throw new Error('Can\'t delete unexisting Point');
+ }
+
+ this.#points = [
+ ...this.#points.slice(0, index),
+ ...this.#points.slice(index + 1),
+ ];
+
+ this._notify(updateType);
+ }
+
}
diff --git a/src/presenter/board-presenter.js b/src/presenter/board-presenter.js
index 4178487..56dcbbd 100644
--- a/src/presenter/board-presenter.js
+++ b/src/presenter/board-presenter.js
@@ -2,50 +2,111 @@ import SortView from '../view/sort-view.js';
import ListPointsView from '../view/list-points-view.js';
import NoPointView from '../view/no-point-view.js';
import PointPresenter from './point-presenter.js';
+import NewPointPresenter from './new-point-presenter.js';
+import {filter} from '../utils/filter.js';
import { render, remove } from '../framework/render.js';
-import {updateItem} from '../utils/common.js';
import { sortPointDate, sortPointPrice, sortPointTime } from '../utils/points.js';
-import { SortType, FiltersValues } from '../const.js';
+import { SortType, UpdateType, UserAction, FiltersValues } from '../const.js';
export default class BoardPresenter {
#boardContainer = null;
#pointsModel = null;
+ #filterModel = null;
#listContainer = new ListPointsView();
- #boardPoints = [];
#sortComponent = null;
#noPointComponent = null;
#pointPresenters = new Map();
- #newPointPresenters = null;
+ #newPointPresenter = null;
#currentSortType = SortType.DAY;
+ #filterType = FiltersValues.EVERYTHING;
- constructor({boardContainer, pointsModel}) {
+ constructor({boardContainer, pointsModel, filterModel, onNewPointDestroy}) {
this.#boardContainer = boardContainer;
this.#pointsModel = pointsModel;
+ this.#filterModel = filterModel;
+
+ this.#pointsModel.addObserver(this.#handleModelEvent);
+ this.#filterModel.addObserver(this.#handleModelEvent);
+
+ this.#newPointPresenter = new NewPointPresenter({
+ allOffers: this.offers,
+ allDestinations: this.destinations,
+ pointListContainer: this.#listContainer.element,
+ onDataChange: this.#handleViewAction,
+ onDestroy: onNewPointDestroy
+ });
+ }
+
+ get points() {
+ this.#filterType = this.#filterModel.filter;
+ const points = this.#pointsModel.points;
+
+ const filteredPoints = filter[this.#filterType](points);
+
+ switch (this.#currentSortType) {
+ case SortType.TIME:
+ return filteredPoints.sort(sortPointTime);
+ case SortType.PRICE:
+ return filteredPoints.sort(sortPointPrice);
+ }
+ return filteredPoints.sort(sortPointDate);
+ }
+
+ get destinations() {
+ return this.#pointsModel.destinations;
+ }
+
+ get offers() {
+ return this.#pointsModel.offers;
}
init() {
- this.#boardPoints = [...this.#pointsModel.points];
- this.allOffers = [...this.#pointsModel.offers];
- this.allDestinations = [...this.#pointsModel.destinations];
- this.#boardPoints.sort(sortPointDate);
this.#renderBoard();
}
- #renderSort(sortType) {
+ createPoint() {
+ this.#currentSortType = SortType.DEFAULT;
+ this.#filterModel.setFilter(UpdateType.MAJOR, FiltersValues.EVERYTHING);
+ this.#newPointPresenter.init();
+ }
+
+ #renderBoard() {
+ const filterType = this.#filterModel.filter;
+ if (this.points.length === 0) {
+ this.#renderNoPoint(filterType);
+ return;
+ }
+ this.#renderSort();
+ this.#renderPointsList();
+ }
+
+ #renderNoPoint() {
+ this.#noPointComponent = new NoPointView({filterType: this.#filterType});
+ render(this.#noPointComponent, this.#boardContainer);
+ }
+
+ #renderSort() {
this.#sortComponent = new SortView({
onSortTypeChange: this.#handleSortTypeChange,
- sortType
+ sortType: this.#currentSortType
});
render(this.#sortComponent, this.#boardContainer);
}
+ #renderPointsList() {
+ render(this.#listContainer, this.#boardContainer);
+ this.points.forEach((point) => {
+ this.#renderPoint(point, this.offers, this.destinations);
+ });
+ }
+
#renderPoint(point, allOffers, allDestinations) {
const pointPresenter = new PointPresenter({
pointsListContainer: this.#listContainer.element,
- onDataChange: this.#handlePointChange,
+ onDataChange: this.#handleViewAction,
onModeChange: this.#handleModeChange
});
@@ -53,71 +114,67 @@ export default class BoardPresenter {
this.#pointPresenters.set(point.id, pointPresenter);
}
- #renderPointsList() {
- render(this.#listContainer, this.#boardContainer);
- this.#boardPoints.forEach((point) => {
- this.#renderPoint(point, this.allOffers, this.allDestinations);
- });
- }
-
- #renderNoPoint(filter) {
- this.#noPointComponent = new NoPointView(filter);
- render(this.#noPointComponent, this.#boardContainer);
- }
-
-
- #renderBoard() {
- if (this.#boardPoints.length === 0) {
- this.#renderNoPoint(FiltersValues.EVERYTHING);
- return;
- }
- this.#renderSort(this.#currentSortType);
- this.#renderPointsList();
- }
-
- #clearPointsList() {
+ #clearBoard({resetSortType = false} = {}) {
+ this.#newPointPresenter.destroy();
this.#pointPresenters.forEach((presenter) => presenter.destroy());
this.#pointPresenters.clear();
- }
- #sortPoints = (sortType) => {
- switch (sortType) {
- case SortType.DAY:
- this.#boardPoints.sort(sortPointDate);
- break;
- case SortType.TIME:
- this.#boardPoints.sort(sortPointTime);
- break;
- case SortType.PRICE:
- this.#boardPoints.sort(sortPointPrice);
- break;
+ remove(this.#sortComponent);
+
+ if (resetSortType) {
+ this.#currentSortType = SortType.DAY;
}
- this.#currentSortType = sortType;
- };
+ if (this.#noPointComponent) {
+ remove(this.#noPointComponent);
+ }
+ }
#handleSortTypeChange = (sortType) => {
if (this.#currentSortType === sortType) {
return;
}
+ this.#currentSortType = sortType;
remove(this.#sortComponent);
this.#renderSort(sortType);
- this.#sortPoints(sortType);
- this.#clearPointsList();
- this.#renderPointsList();
-
+ this.#clearBoard();
+ this.#renderBoard();
};
#handleModeChange = () => {
+ this.#newPointPresenter.destroy();
this.#pointPresenters.forEach((presenter) => presenter.resetView());
};
-
- #handlePointChange = (updatedPoint) => {
- this.#boardPoints = updateItem(this.#boardPoints, updatedPoint);
- this.#pointPresenters.get(updatedPoint.id).init(updatedPoint, this.allOffers, this.allDestinations);
+ #handleViewAction = (actionType, updateType, update) => {
+ switch (actionType) {
+ case UserAction.UPDATE_POINT:
+ this.#pointsModel.updatePoint(updateType, update);
+ break;
+ case UserAction.ADD_POINT:
+ this.#pointsModel.addPoint(updateType, update);
+ break;
+ case UserAction.DELETE_POINT:
+ this.#pointsModel.deletePoint(updateType, update);
+ break;
+ }
};
+ #handleModelEvent = (updateType, data) => {
+ switch (updateType) {
+ case UpdateType.PATCH:
+ this.#pointPresenters.get(data.id).init(data, this.offers, this.destinations);
+ break;
+ case UpdateType.MINOR:
+ this.#clearBoard();
+ this.#renderBoard();
+ break;
+ case UpdateType.MAJOR:
+ this.#clearBoard({resetSortType: true});
+ this.#renderBoard();
+ break;
+ }
+ };
}
diff --git a/src/presenter/filter-presenter.js b/src/presenter/filter-presenter.js
new file mode 100644
index 0000000..b2fe8a5
--- /dev/null
+++ b/src/presenter/filter-presenter.js
@@ -0,0 +1,60 @@
+import {render, replace, remove} from '../framework/render.js';
+import FiltersView from '../view/filters-view.js';
+import {filter} from '../utils/filter.js';
+import {FiltersValues, UpdateType} from '../const.js';
+
+
+export default class FilterPresenter {
+ #filterContainer = null;
+ #filterModel = null;
+ #pointsModel = null;
+
+ #filterComponent = null;
+
+ constructor({filterContainer, filterModel, pointsModel}) {
+ this.#filterContainer = filterContainer;
+ this.#filterModel = filterModel;
+ this.#pointsModel = pointsModel;
+ this.#pointsModel.addObserver(this.#handleModelEvent);
+ this.#filterModel.addObserver(this.#handleModelEvent);
+ }
+
+ get filters() {
+ const points = this.#pointsModel.points;
+ return Object.values(FiltersValues).map((type) => ({
+ type,
+ points: filter[type](points)
+ }));
+ }
+
+ init() {
+ const filters = this.filters;
+ const prevFilterComponent = this.#filterComponent;
+
+ this.#filterComponent = new FiltersView({
+ filters,
+ currentFilterType: this.#filterModel.filter,
+ onFilterTypeChange: this.#handleFilterTypeChange
+ });
+
+ if (prevFilterComponent === null) {
+ render(this.#filterComponent, this.#filterContainer);
+ return;
+ }
+
+ replace(this.#filterComponent, prevFilterComponent);
+ remove(prevFilterComponent);
+ }
+
+ #handleModelEvent = () => {
+ this.init();
+ };
+
+ #handleFilterTypeChange = (filterType) => {
+ if (this.#filterModel.filter === filterType) {
+ return;
+ }
+
+ this.#filterModel.setFilter(UpdateType.MAJOR, filterType);
+ };
+}
diff --git a/src/presenter/new-point-presenter.js b/src/presenter/new-point-presenter.js
new file mode 100644
index 0000000..00daed8
--- /dev/null
+++ b/src/presenter/new-point-presenter.js
@@ -0,0 +1,70 @@
+import {remove, render, RenderPosition} from '../framework/render.js';
+import FormPointView from '../view/form-point-view.js';
+import {nanoid} from 'nanoid';
+import {UserAction, UpdateType} from '../const.js';
+
+export default class NewTaskPresenter {
+ #pointListContainer = null;
+ #handleDataChange = null;
+ #handleDestroy = null;
+
+ #pointEditComponent = null;
+
+ constructor({allOffers, allDestinations, pointListContainer, onDataChange, onDestroy}) {
+ this.#pointListContainer = pointListContainer;
+ this.#handleDataChange = onDataChange;
+ this.#handleDestroy = onDestroy;
+ this.allOffers = allOffers;
+ this.allDestinations = allDestinations;
+ }
+
+ init() {
+ if (this.#pointEditComponent !== null) {
+ return;
+ }
+
+ this.#pointEditComponent = new FormPointView({
+ allOffers: this.allOffers,
+ allDestinations: this.allDestinations,
+ onFormSubmit: this.#handleFormSubmit,
+ onDeleteClick: this.#handleDeleteClick
+ });
+
+ render(this.#pointEditComponent, this.#pointListContainer, RenderPosition.AFTERBEGIN);
+
+ document.addEventListener('keydown', this.#escKeyDownHandler);
+ }
+
+ destroy() {
+ if (this.#pointEditComponent === null) {
+ return;
+ }
+
+ this.#handleDestroy();
+
+ remove(this.#pointEditComponent);
+ this.#pointEditComponent = null;
+
+ document.removeEventListener('keydown', this.#escKeyDownHandler);
+ }
+
+ #handleFormSubmit = (task) => {
+ this.#handleDataChange(
+ UserAction.ADD_POINT,
+ UpdateType.MINOR,
+ {id: nanoid(), ...task},
+ );
+ this.destroy();
+ };
+
+ #handleDeleteClick = () => {
+ this.destroy();
+ };
+
+ #escKeyDownHandler = (evt) => {
+ if (evt.key === 'Escape' || evt.key === 'Esc') {
+ evt.preventDefault();
+ this.destroy();
+ }
+ };
+}
diff --git a/src/presenter/point-presenter.js b/src/presenter/point-presenter.js
index 2194f88..0ba8112 100644
--- a/src/presenter/point-presenter.js
+++ b/src/presenter/point-presenter.js
@@ -1,6 +1,8 @@
import {render, replace, remove} from '../framework/render.js';
import PointView from '../view/point-view.js';
import FormPointView from '../view/form-point-view.js';
+import {UserAction, UpdateType} from '../const.js';
+import { isDatesEqual } from '../utils/points.js';
const Mode = {
DEFAULT: 'DEFAULT',
@@ -30,6 +32,7 @@ export default class PointPresenter {
const prevPointComponent = this.#pointComponent;
const prevPointEditComponent = this.#pointEditComponent;
+
this.#pointComponent = new PointView({
point: this.#point,
allOffers: allOffers,
@@ -42,7 +45,8 @@ export default class PointPresenter {
point: this.#point,
allOffers: allOffers,
allDestinations: allDestinations,
- onFormSubmit: this.#handleFormSubmit
+ onFormSubmit: this.#handleFormSubmit,
+ onDeleteClick: this.#handleDeleteClick
});
if (prevPointComponent === null || prevPointEditComponent === null) {
@@ -74,15 +78,6 @@ export default class PointPresenter {
remove(this.#pointEditComponent);
}
- #escKeyDownHandler = (evt) => {
- if (evt.key === 'Escape') {
- evt.preventDefault();
- this.#pointEditComponent.reset(this.#point);
- this.#replaceFormToPoint();
- document.removeEventListener('keydown', this.#escKeyDownHandler);
- }
- };
-
#replacePointToForm() {
replace(this.#pointEditComponent, this.#pointComponent);
document.addEventListener('keydown', this.#escKeyDownHandler);
@@ -96,16 +91,42 @@ export default class PointPresenter {
this.#mode = Mode.DEFAULT;
}
+ #escKeyDownHandler = (evt) => {
+ if (evt.key === 'Escape') {
+ evt.preventDefault();
+ this.#pointEditComponent.reset(this.#point);
+ this.#replaceFormToPoint();
+ document.removeEventListener('keydown', this.#escKeyDownHandler);
+ }
+ };
+
#handleEditClick = () => {
this.#replacePointToForm();
};
- #handleFormSubmit = (point) => {
- this.#handleDataChange(point);
+ #handleFormSubmit = (update) => {
+ const isMinorUpdate = !isDatesEqual(this.#point.dateFrom, update.dateFrom) || !isDatesEqual(this.#point.dateTo, update.dateTo) || this.#point.basePrice !== update.basePrice;
+ this.#handleDataChange(
+ UserAction.UPDATE_POINT,
+ isMinorUpdate ? UpdateType.MINOR : UpdateType.PATCH,
+ update,
+ );
this.#replaceFormToPoint();
};
+ #handleDeleteClick = (point) => {
+ this.#handleDataChange(
+ UserAction.DELETE_POINT,
+ UpdateType.MINOR,
+ point,
+ );
+ };
+
#handleFavoriteClick = () => {
- this.#handleDataChange({...this.#point, isFavorite: !this.#point.isFavorite});
+ this.#handleDataChange(
+ UserAction.UPDATE_POINT,
+ UpdateType.PATCH,
+ {...this.#point, isFavorite: !this.#point.isFavorite},
+ );
};
}
diff --git a/src/utils/common.js b/src/utils/common.js
index 915c9a2..6c1799b 100644
--- a/src/utils/common.js
+++ b/src/utils/common.js
@@ -8,8 +8,4 @@ function capitalizeFirstLetter(text) {
return textFirstCapitalLetter;
}
-function updateItem(items, update) {
- return items.map((item) => item.id === update.id ? update : item);
-}
-
-export {getRandomArrayElement, capitalizeFirstLetter, updateItem};
+export {getRandomArrayElement, capitalizeFirstLetter};
diff --git a/src/utils/points.js b/src/utils/points.js
index f1c5ac8..6d84810 100644
--- a/src/utils/points.js
+++ b/src/utils/points.js
@@ -92,5 +92,9 @@ function toggleOffers(offers, id) {
return [...offers, id];
}
+function isDatesEqual(dateA, dateB) {
+ return (dateA === null && dateB === null) || dayjs(dateA).isSame(dateB, 'D');
+}
+
-export {humanizePointDate, humanizePointDuration, FORMATS, isCompletedPoints, isCurrentPoints, isPlannedPoints, sortPointDate, sortPointPrice, sortPointTime, toggleOffers};
+export {humanizePointDate, humanizePointDuration, FORMATS, isCompletedPoints, isCurrentPoints, isPlannedPoints, sortPointDate, sortPointPrice, sortPointTime, toggleOffers, isDatesEqual};
diff --git a/src/view/filters-view.js b/src/view/filters-view.js
index f2bc8c1..02ffd5f 100644
--- a/src/view/filters-view.js
+++ b/src/view/filters-view.js
@@ -1,16 +1,17 @@
import AbstractView from '../framework/view/abstract-view.js';
-function createFilterItemTemplate({type}) {
+function createFilterItemTemplate({type}, currentFilter) {
+ const isChecked = type === currentFilter ? 'checked' : '';
return `
-
+
`;
}
-function createFiltersTemplate(filtersItem) {
+function createFiltersTemplate(filtersItem, currentFilter) {
return (
``
);
@@ -18,13 +19,27 @@ function createFiltersTemplate(filtersItem) {
export default class FiltersView extends AbstractView{
#filters = null;
+ #currentFilter = null;
+ #handleFilterTypeChange = null;
- constructor ({filters}) {
+ constructor ({filters, currentFilterType, onFilterTypeChange}) {
super();
this.#filters = filters;
+ this.#currentFilter = currentFilterType;
+ this.#handleFilterTypeChange = onFilterTypeChange;
+ this.element.addEventListener('click', this.#filterTypeChangeHandler);
}
get template() {
- return createFiltersTemplate(this.#filters);
+ return createFiltersTemplate(this.#filters, this.#currentFilter);
}
+
+ #filterTypeChangeHandler = (evt) => {
+ evt.preventDefault();
+ if(evt.target.tagName === 'LABEL') {
+ const inputElement = evt.target.closest('.trip-filters__filter').querySelector('input');
+
+ this.#handleFilterTypeChange(inputElement.value);
+ }
+ };
}
diff --git a/src/view/form-point-view.js b/src/view/form-point-view.js
index f50fe1d..5b53ff0 100644
--- a/src/view/form-point-view.js
+++ b/src/view/form-point-view.js
@@ -1,7 +1,7 @@
import AbstractStatefulView from '../framework/view/abstract-stateful-view.js';
import { FORMATS, humanizePointDate, toggleOffers } from '../utils/points.js';
import { capitalizeFirstLetter } from '../utils/common.js';
-
+import he from 'he';
import flatpickr from 'flatpickr';
import 'flatpickr/dist/flatpickr.min.css';
@@ -12,7 +12,7 @@ const BLANK_POINT = {
dateFrom: '',
dateTo: '',
basePrice: '0',
- offers: ['luggage', 'comfort', 'meal', 'seats', 'train'],
+ offers: [],
};
function createTypeItemTemplate(type) {
@@ -92,7 +92,7 @@ function createEventTemplate(point = BLANK_POINT, allOffers, allDestinations, ed
-
+
@@ -100,10 +100,10 @@ function createEventTemplate(point = BLANK_POINT, allOffers, allDestinations, ed
-
+
—
-
+
@@ -111,7 +111,7 @@ function createEventTemplate(point = BLANK_POINT, allOffers, allDestinations, ed
basePrice
€
-
+
@@ -127,16 +127,18 @@ function createEventTemplate(point = BLANK_POINT, allOffers, allDestinations, ed
export default class FormPointView extends AbstractStatefulView{
#handleFormSubmit = null;
+ #handleDeleteClick = null;
#startDatepicker = null;
#endDatepicker = null;
- constructor({point, allOffers, allDestinations, onFormSubmit}) {
+ constructor({point = BLANK_POINT, allOffers, allDestinations, onFormSubmit, onDeleteClick}) {
super();
this._setState(FormPointView.parsePointToState(point));
this.allOffers = allOffers;
this.allDestinations = allDestinations;
this.isEdit = !!point.id;
this.#handleFormSubmit = onFormSubmit;
+ this.#handleDeleteClick = onDeleteClick;
this. _restoreHandlers();
}
@@ -150,6 +152,11 @@ export default class FormPointView extends AbstractStatefulView{
this.#handleFormSubmit(FormPointView.parseStateToPoint(this._state));
};
+ #formDeleteClickHandler = (evt) => {
+ evt.preventDefault();
+ this.#handleDeleteClick(FormPointView.parseStateToPoint(this._state));
+ };
+
#pointOfferClickHandler = (evt) => {
evt.preventDefault();
const labelElement = evt.target.closest('.event__offer-label');
@@ -170,11 +177,22 @@ export default class FormPointView extends AbstractStatefulView{
});
};
- #pointDestinationClickHandler = (evt) => {
+ #pointDestinationChangeHandler = (evt) => {
+ evt.preventDefault();
+ const newDestination = this.allDestinations.find((destinations) => evt.target.value === destinations.name);
+ if(!newDestination) {
+ evt.target.value = '';
+ return;
+ }
+ this.updateElement({
+ destination: newDestination.id,
+ });
+ };
+
+ #pointPriceChangeHandler = (evt) => {
evt.preventDefault();
- const newDestination = this.allDestinations.find((destinations) => evt.target.value === destinations.name).id;
this.updateElement({
- destination: newDestination,
+ basePrice: evt.target.value,
});
};
@@ -227,7 +245,11 @@ export default class FormPointView extends AbstractStatefulView{
this.element.querySelector('.event__type-group')
.addEventListener('click', this.#pointTypeClickHandler);
this.element.querySelector('.event__input--destination')
- .addEventListener('change', this.#pointDestinationClickHandler);
+ .addEventListener('change', this.#pointDestinationChangeHandler);
+ this.element.querySelector('.event__input--basePrice')
+ .addEventListener('change', this.#pointPriceChangeHandler);
+ this.element.querySelector('.event__reset-btn')
+ .addEventListener('click', this.#formDeleteClickHandler);
this.#setStartDatepicker();
this.#setEndDatepicker();
diff --git a/src/view/new-point-button-view.js b/src/view/new-point-button-view.js
new file mode 100644
index 0000000..af3bd14
--- /dev/null
+++ b/src/view/new-point-button-view.js
@@ -0,0 +1,24 @@
+import AbstractView from '../framework/view/abstract-view.js';
+
+function createNewPointButtonTemplate() {
+ return '';
+}
+
+export default class NewPointButtonView extends AbstractView {
+ #handleClick = null;
+
+ constructor({onClick}) {
+ super();
+ this.#handleClick = onClick;
+ this.element.addEventListener('click', this.#clickHandler);
+ }
+
+ get template() {
+ return createNewPointButtonTemplate();
+ }
+
+ #clickHandler = (evt) => {
+ evt.preventDefault();
+ this.#handleClick();
+ };
+}
diff --git a/src/view/no-point-view.js b/src/view/no-point-view.js
index 57ead32..6ce8101 100644
--- a/src/view/no-point-view.js
+++ b/src/view/no-point-view.js
@@ -1,20 +1,20 @@
import AbstractView from '../framework/view/abstract-view.js';
import { NO_POINT_MESSAGES } from '../const.js';
-function createNoPointTemplate(filterChecked) {
+function createNoPointTemplate(filterType) {
return `
- ${NO_POINT_MESSAGES[filterChecked.toUpperCase()]}
+ ${NO_POINT_MESSAGES[filterType.toUpperCase()]}
`;
}
export default class NoPointView extends AbstractView {
- #filterChecked = null;
- constructor(filter) {
+ #filterType = null;
+ constructor({filterType}) {
super();
- this.#filterChecked = filter;
+ this.#filterType = filterType;
}
get template() {
- return createNoPointTemplate(this.#filterChecked);
+ return createNoPointTemplate(this.#filterType);
}
}
diff --git a/src/view/sort-view.js b/src/view/sort-view.js
index 2c3caad..8e69d83 100644
--- a/src/view/sort-view.js
+++ b/src/view/sort-view.js
@@ -23,10 +23,12 @@ function createSortTemplate(sortType) {
export default class SortView extends AbstractView{
#handleSortTypeChange = null;
#sortType = null;
+
constructor({onSortTypeChange, sortType}) {
super();
this.#sortType = sortType;
this. #handleSortTypeChange = onSortTypeChange;
+
this.element.addEventListener('click', this.#sortTypeChangeHandler);
}