Skip to content

Commit

Permalink
Merge pull request #9 from reking06/module6-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Sep 30, 2024
2 parents 89d91af + b4084e4 commit e30930c
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 32 deletions.
3 changes: 0 additions & 3 deletions src/presenter/main-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ export default class MainPresenter {
this.#renderContainer();
this.#sortPoints(this.#defaultSortType);
this.#renderPoints();
// render(this.#sortComponent, this.contentContainer);
// render(this.#listComponent, this.contentContainer);
// this.#renderPoints(points, offers, destinations);
};

#renderSortTypes = () => {
Expand Down
3 changes: 3 additions & 0 deletions src/presenter/point-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default class PointPresenter {

resetView() {
if (this.#mode !== Mode.DEFAULT) {
this.#eventEditorComponent.reset(this.#point);
this.#replaceFormToPoint();
}
}
Expand All @@ -92,6 +93,7 @@ export default class PointPresenter {
#escKeyDownHandler = (event) => {
if (event.key === 'Escape') {
event.preventDefault();
this.#eventEditorComponent.reset(this.#point);
this.#replaceFormToPoint();
}
};
Expand All @@ -101,6 +103,7 @@ export default class PointPresenter {
};

#handleCloseClick = () => {
this.#eventEditorComponent.reset(this.#point);
this.#replaceFormToPoint();
};

Expand Down
123 changes: 94 additions & 29 deletions src/view/event-editor-view.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import AbstractView from '../framework/view/abstract-view.js';
import AbstractStatefulView from '../framework/view/abstract-stateful-view';
import { convertDate, getCapitalized } from '../util/utils.js';
import { DATE_TIME_FORMAT, EVENT_TYPES } from '../constants.js';

const createEventTypeItemTemplate = (type) => `
const createEventTypeItemTemplate = (type, pointId) => `
${EVENT_TYPES.map((eventType) => (`
<div class="event__type-item">
<input id="event-type-${eventType}-1" class="event__type-input visually-hidden" type="radio" name="event-type" value="${eventType}" ${eventType === type ? 'checked' : ''}>
<label class="event__type-label event__type-label--${eventType}" for="event-type-${eventType}-1">${getCapitalized(eventType)}</label>
<input
id="event-type-${eventType}-${pointId}"
class="event__type-input visually-hidden"
type="radio"
name="event-type"
value="${eventType}"
${eventType === type ? 'checked' : ''}>
<label
class="event__type-label event__type-label--${eventType}"
for="event-type-${eventType}-${pointId}">${getCapitalized(eventType)}</label>
</div>`
)).join('')}`;

const createEventDestinationListTemplate = (destinations) => destinations.map((destination) => `<option value="${destination.name}"></option>`).join('');

const createEventAvailableOffersTemplate = (defaultOffers, selectedOffers) => {
const createEventAvailableOffersTemplate = (defaultOffers, selectedOffers, pointId) => {
const convertOfferTitle = (title) => title.toLowerCase().split(' ')[-1];

if (defaultOffers.length === 0) {
Expand All @@ -26,7 +34,12 @@ const createEventAvailableOffersTemplate = (defaultOffers, selectedOffers) => {
<div class="event__available-offers">
${defaultOffers.map((defaultOffer) => (`
<div class="event__offer-selector">
<input class="event__offer-checkbox visually-hidden" id="event-offer-${convertOfferTitle(defaultOffer.title)}-1" type="checkbox" name="event-offer-${convertOfferTitle(defaultOffer.title)}" ${selectedOffers.map((selectedOffer) => selectedOffer.id).includes(defaultOffer.id) ? 'checked' : ''}>
<input
class="event__offer-checkbox visually-hidden"
id="event-offer-${convertOfferTitle(defaultOffer.title)}-${pointId}"
type="checkbox"
name="event-offer-${convertOfferTitle(defaultOffer.title)}"
${selectedOffers.map((selectedOffer) => selectedOffer.id).includes(defaultOffer.id) ? 'checked' : ''}>
<label class="event__offer-label" for="event-offer-${convertOfferTitle(defaultOffer.title)}-1">
<span class="event__offer-title">${defaultOffer.title}</span>
&plus;&euro;&nbsp;
Expand Down Expand Up @@ -55,14 +68,14 @@ const createEventSectionDestinationTemplate = (description, pictures) => {
</section>`;
};

const createEventDetailsTemplate = (defaultOffers, selectedOffers, description, pictures) => {
const createEventDetailsTemplate = (defaultOffers, selectedOffers, description, pictures, pointId) => {
if (defaultOffers.length === 0 && !description) {
return '';
}

return `
<section class="event__details">
${createEventAvailableOffersTemplate(defaultOffers, selectedOffers)}
${createEventAvailableOffersTemplate(defaultOffers, selectedOffers, pointId)}
${createEventSectionDestinationTemplate(description, pictures)}
</section>`;
};
Expand All @@ -74,6 +87,7 @@ const createEventEditorTemplate = (point, offers, destinations)=> {

const { basePrice, dateFrom, dateTo, type } = point;
const { description, name, pictures } = eventDestination || {};
const pointId = point.id || 0;

const startTime = convertDate(dateFrom, DATE_TIME_FORMAT.DATE_AND_TIME);
const endTime = convertDate(dateTo, DATE_TIME_FORMAT.DATE_AND_TIME);
Expand All @@ -83,61 +97,66 @@ const createEventEditorTemplate = (point, offers, destinations)=> {
<form class="event event--edit" action="#" method="post">
<header class="event__header">
<div class="event__type-wrapper">
<label class="event__type event__type-btn" for="event-type-toggle-1">
<label class="event__type event__type-btn" for="event-type-toggle-${pointId}">
<span class="visually-hidden">Choose event type</span>
<img class="event__type-icon" width="17" height="17" src="img/icons/${type}.png" alt="Event ${type} icon">
</label>
<input class="event__type-toggle visually-hidden" id="event-type-toggle-1" type="checkbox">
<input class="event__type-toggle visually-hidden" id="event-type-toggle-${pointId}" type="checkbox">
<div class="event__type-list">
<fieldset class="event__type-group">
<legend class="visually-hidden">Event type</legend>
${createEventTypeItemTemplate(type)}
${createEventTypeItemTemplate(type, pointId)}
</fieldset>
</div>
</div>
<div class="event__field-group event__field-group--destination">
<label class="event__label event__type-output" for="event-destination-1">
<label class="event__label event__type-output" for="event-destination-${pointId}">
${getCapitalized(type)}
</label>
<input class="event__input event__input--destination" id="event-destination-1" type="text" name="event-destination" value="${name || ''}" list="destination-list-1">
<datalist id="destination-list-1">
<input
class="event__input event__input--destination"
id="event-destination-${pointId}"
type="text"
name="event-destination"
value="${name || ''}"
list="destination-list-${pointId}">
<datalist id="destination-list-${pointId}">
${createEventDestinationListTemplate(destinations)}
</datalist>
</div>
<div class="event__field-group event__field-group--time">
<label class="visually-hidden" for="event-start-time-1">From</label>
<input class="event__input event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${startTime}">
<label class="visually-hidden" for="event-start-time-${pointId}">From</label>
<input class="event__input event__input--time" id="event-start-time-${pointId}" type="text" name="event-start-time" value="${startTime}">
&mdash;
<label class="visually-hidden" for="event-end-time-1">To</label>
<input class="event__input event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${endTime}">
<label class="visually-hidden" for="event-end-time-${pointId}">To</label>
<input class="event__input event__input--time" id="event-end-time-${pointId}" type="text" name="event-end-time" value="${endTime}">
</div>
<div class="event__field-group event__field-group--price">
<label class="event__label" for="event-price-1">
<label class="event__label" for="event-price-${pointId}">
<span class="visually-hidden">Price</span>
&euro;
</label>
<input class="event__input event__input--price" id="event-price-1" type="text" name="event-price" value="${basePrice}">
<input class="event__input event__input--price" id="event-price-${pointId}" type="text" name="event-price" value="${basePrice}">
</div>
<button class="event__save-btn btn btn--blue" type="submit">Save</button>
<button class="event__reset-btn" type="reset">Delete</button>
<button class="event__reset-btn" type="reset">${point.id ? 'Delete' : 'Cancel'}</button>
<button class="event__rollup-btn" type="button">
<span class="visually-hidden">Open event</span>
</button>
</header>
${createEventDetailsTemplate(defaultOffers, selectedOffers, description, pictures)}
${createEventDetailsTemplate(defaultOffers, selectedOffers, description, pictures, pointId)}
</form>
</li>`;
};

export default class EventEditorView extends AbstractView {
#point = [];
export default class EventEditorView extends AbstractStatefulView {
#destinations = [];
#offers = [];

Expand All @@ -146,24 +165,70 @@ export default class EventEditorView extends AbstractView {

constructor({ point, offers, destinations, onEditClick, onFormSubmit }) {
super();
this.#point = point;
this._setState(EventEditorView.parsePointToState(point));
this.#offers = offers;
this.#destinations = destinations;
this.#handleEditClick = onEditClick;
this.#handleFormSubmit = onFormSubmit;

this.element.querySelector('form').addEventListener('submit', this.#formSubmitHandler);
this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#editClickHandler);
this._restoreHandlers();
}

get template() {
return createEventEditorTemplate(this.#point, this.#offers, this.#destinations);
return createEventEditorTemplate(this._state, this.#offers, this.#destinations);
}

static parsePointToState(point) {
return {...point};
}

static parseStateToPoint(state) {
return {...state};
}

reset(point) {
this.updateElement(EventEditorView.parseStateToPoint(point));
}

_restoreHandlers() {
this.element.querySelector('.event__rollup-btn').addEventListener('click', this.#editClickHandler);
this.element.querySelector('form').addEventListener('submit', this.#formSubmitHandler);
this.element.querySelector('.event__type-group').addEventListener('change', this.#changeTypeHandler);
this.element.querySelector('.event__input--destination').addEventListener('change', this.#changeDestinationHandler);
this.element.querySelector('.event__available-offers')?.addEventListener('change', this.#changeAvailableOffersHandler);
this.element.querySelector('.event__field-group--price').addEventListener('input', this.#changePriceHandler);
}

#formSubmitHandler = (event) => {
event.preventDefault();
this.#handleFormSubmit(this.#point);
this.#handleFormSubmit(EventEditorView.parseStateToPoint(this._state));
};

#editClickHandler = () => this.#handleEditClick();

#changeTypeHandler = (event) => {
this.updateElement({
type: event.target.value
});
};

#changeDestinationHandler = (event) => {
this.updateElement({
destination: this.#destinations.find((destination) => destination.name === event.target.value).id
});
};

#changeAvailableOffersHandler = () => {
const selectedOffers = this.element.querySelectorAll('.event__offer-checkbox:checked');

this._setState({
offers: Array.from(selectedOffers).map((item) => item.dataset.offerId)
});
};

#changePriceHandler = (event) => {
this._setState({
basePrice: parseInt(event.target.value, 10)
});
};
}

0 comments on commit e30930c

Please sign in to comment.