Skip to content

Commit 96a642b

Browse files
authored
Merge pull request #11 from IntellectualSpecialist/module11-task1
2 parents 5ce4c3a + af54b73 commit 96a642b

File tree

10 files changed

+168
-174
lines changed

10 files changed

+168
-174
lines changed

js/api.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const BASE_URL = 'https://31.javascript.htmlacademy.pro/kekstagram';
2+
const Route = {
3+
GET_DATA: '/data',
4+
SEND_DATA: '',
5+
};
6+
const ErrorText = {
7+
GET_DATA: 'Не удалось загрузить данные. Попробуйте обновить страницу',
8+
SEND_DATA: 'Не удалось отправить форму. Попробуйте ещё раз',
9+
};
10+
const Method = {
11+
GET: 'GET',
12+
POST: 'POST',
13+
};
14+
15+
const load = (route, errorText, method = Method.GET, body = null) => fetch(`${BASE_URL}${route}`, {method, body}).then((response) => {
16+
if (!response.ok) {
17+
throw new Error(`Произошла ошибка ${response.status}: ${response.statusText}`);
18+
}
19+
20+
return response.json();
21+
}).catch((err) => {
22+
throw new Error(errorText ?? err.message);
23+
});
24+
25+
const getData = () => load(Route.GET_DATA, ErrorText.GET_DATA);
26+
27+
const sendData = (body) => load(Route.SEND_DATA, ErrorText.SEND_DATA, Method.POST, body);
28+
29+
export { getData, sendData };

js/create-photos.js

Lines changed: 0 additions & 49 deletions
This file was deleted.

js/data.js

Lines changed: 0 additions & 32 deletions
This file was deleted.

js/form-validation.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,6 @@ const resetValidation = () => {
6565
pristine.reset();
6666
};
6767

68-
const initFormValidation = () => {
69-
if (!formElement) {
70-
return;
71-
}
72-
73-
formElement.addEventListener('submit', (evt) => {
74-
evt.preventDefault();
75-
76-
if (pristine.validate()) {
77-
formElement.submit();
78-
}
79-
});
80-
};
68+
const isFormValid = () => pristine.validate();
8169

82-
export { initFormValidation, resetValidation };
70+
export { isFormValid, resetValidation };

js/form.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import { isEscKey } from './utils.js';
2-
import { initFormValidation, resetValidation } from './form-validation.js';
2+
import { renderSendInfoModal } from './info-modal-send.js';
3+
import { isFormValid, resetValidation } from './form-validation.js';
34
import { initScalePhoto, resetScaleValue } from './scale-photo.js';
45
import { initPhotoFilters, resetPhotoFilters } from './photo-filters.js';
6+
import { sendData } from './api.js';
7+
8+
const SubmitButtonText = {
9+
IDLE: 'Отправить',
10+
SENDING: 'Отправляю...'
11+
};
512

613
const bodyElement = document.querySelector('body');
714
const formElement = bodyElement.querySelector('.img-upload__form');
815
const modalFormElement = formElement.querySelector('.img-upload__overlay');
916
const uploadControlElement = formElement.querySelector('.img-upload__input');
1017
const modalFormCloseElement = modalFormElement.querySelector('.img-upload__cancel');
1118
const sliderWrapperElement = modalFormElement.querySelector('.img-upload__effect-level');
19+
const submitButtonElement = modalFormElement.querySelector('.img-upload__submit');
1220

1321
const onDocumentKeydown = (evt) => {
1422
if (isEscKey(evt)) {
@@ -21,6 +29,16 @@ const onDocumentKeydown = (evt) => {
2129
}
2230
};
2331

32+
const disableSubmitButton = () => {
33+
submitButtonElement.disabled = true;
34+
submitButtonElement.textContent = SubmitButtonText.SENDING;
35+
};
36+
37+
const enableSubmitButton = () => {
38+
submitButtonElement.disabled = false;
39+
submitButtonElement.textContent = SubmitButtonText.IDLE;
40+
};
41+
2442
function openModalForm() {
2543
modalFormElement.classList.remove('hidden');
2644
bodyElement.classList.add('modal-open');
@@ -43,6 +61,23 @@ const initModalForm = () => {
4361
return;
4462
}
4563

64+
formElement.addEventListener('submit', (evt) => {
65+
evt.preventDefault();
66+
67+
if (isFormValid()) {
68+
const formData = new FormData(evt.target);
69+
disableSubmitButton();
70+
sendData(formData).then(() => {
71+
closeModalForm();
72+
renderSendInfoModal('success');
73+
}).catch(() => {
74+
renderSendInfoModal('error');
75+
}).finally(() => {
76+
enableSubmitButton();
77+
});
78+
}
79+
});
80+
4681
uploadControlElement.addEventListener('change', () => {
4782
openModalForm();
4883
});
@@ -51,7 +86,6 @@ const initModalForm = () => {
5186
closeModalForm();
5287
});
5388

54-
initFormValidation();
5589
initScalePhoto();
5690
initPhotoFilters();
5791
};

js/gallery.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
1+
import { findElementById } from './utils.js';
2+
import { showAlertTemporarily, findTemplateById } from './utils.js';
13
import { renderThumbnails } from './render-thumbnails.js';
2-
import { createPhotos } from './create-photos.js';
3-
import { initPhotoModal } from './photo-modal.js';
4+
import { registerPhotoModalEvents, openPhotoModal } from './photo-modal.js';
5+
import { getData } from './api.js';
46

57
const thumbnailsContainerElement = document.querySelector('.pictures');
68

7-
const photos = createPhotos();
9+
const errorTemplateElement = findTemplateById('data-error');
810

911
const initGallery = () => {
10-
renderThumbnails(photos, thumbnailsContainerElement);
11-
initPhotoModal(photos, thumbnailsContainerElement);
12+
getData().then((photos) => {
13+
renderThumbnails(photos, thumbnailsContainerElement);
14+
registerPhotoModalEvents();
15+
16+
thumbnailsContainerElement.addEventListener('click', (evt) => {
17+
const targetThumbnailElement = evt.target.closest('.picture');
18+
19+
if (targetThumbnailElement) {
20+
evt.preventDefault();
21+
22+
const targetThumbnailElementId = Number(targetThumbnailElement.dataset.id);
23+
const targetPhoto = findElementById(targetThumbnailElementId, photos);
24+
25+
openPhotoModal(targetPhoto);
26+
}
27+
});
28+
}).catch(() => {
29+
showAlertTemporarily(errorTemplateElement);
30+
});
31+
1232
};
1333

1434
export { initGallery };

js/info-modal-send.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { isEscKey, findTemplateById } from './utils.js';
2+
3+
const bodyElement = document.querySelector('body');
4+
const errorTemplateElement = findTemplateById('error');
5+
const successTemplateElement = findTemplateById('success');
6+
7+
let modalElement;
8+
let currentStatus;
9+
10+
const onBodyClick = (evt) => {
11+
if (!evt.target.closest(`.${currentStatus}__inner`)) {
12+
removeSendInfoModal();
13+
}
14+
};
15+
16+
const onBodyKeydown = (evt) => {
17+
if (isEscKey(evt)) {
18+
evt.preventDefault();
19+
removeSendInfoModal();
20+
evt.stopPropagation();
21+
}
22+
};
23+
24+
const createSendInfoModal = (message) => {
25+
const templateElement = currentStatus === 'success' ? successTemplateElement : errorTemplateElement;
26+
const templateModalElement = templateElement.cloneNode(true);
27+
const closeElement = templateModalElement.querySelector(`.${currentStatus}__button`);
28+
29+
if (message) {
30+
templateModalElement.querySelector(`.${currentStatus}__title`).textContnet = message;
31+
}
32+
33+
closeElement.addEventListener('click', () => {
34+
removeSendInfoModal();
35+
});
36+
37+
return templateModalElement;
38+
};
39+
40+
function renderSendInfoModal(status, message) {
41+
currentStatus = status;
42+
modalElement = createSendInfoModal(message);
43+
bodyElement.append(modalElement);
44+
bodyElement.addEventListener('keydown', onBodyKeydown);
45+
bodyElement.addEventListener('click', onBodyClick);
46+
}
47+
48+
function removeSendInfoModal() {
49+
modalElement.remove();
50+
bodyElement.removeEventListener('keydown', onBodyKeydown);
51+
bodyElement.removeEventListener('click', onBodyClick);
52+
}
53+
54+
export { renderSendInfoModal };

js/photo-filters.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,7 @@ const createSlider = () => {
6666
start: 1,
6767
connect: 'lower',
6868
format: {
69-
to: (value) => {
70-
if (Number.isInteger(value)) {
71-
return value;
72-
}
73-
return value.toFixed(1);
74-
},
69+
to: (value) => Number.isInteger(value) ? value : value.toFixed(1),
7570
from: (value) => parseFloat(value),
7671
},
7772
});

js/photo-modal.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { findElementById, isEscKey } from './utils.js';
1+
import { isEscKey } from './utils.js';
22
import { renderComments } from './render-comments.js';
33

44
const COMMENTS_CHUNK_SIZE = 5;
@@ -65,24 +65,11 @@ function closePhotoModal() {
6565
bodyElement.classList.remove('modal-open');
6666
}
6767

68-
const initPhotoModal = (photos, container) => {
68+
const registerPhotoModalEvents = () => {
6969
if (!modalElement) {
7070
return;
7171
}
7272

73-
container.addEventListener('click', (evt) => {
74-
const targetThumbnailElement = evt.target.closest('.picture');
75-
76-
if (targetThumbnailElement) {
77-
evt.preventDefault();
78-
79-
const targetThumbnailElementId = Number(targetThumbnailElement.dataset.id);
80-
const targetPhoto = findElementById(targetThumbnailElementId, photos);
81-
82-
openPhotoModal(targetPhoto);
83-
}
84-
});
85-
8673
modalCommentsLoaderElement.addEventListener('click', () => {
8774
renderNextComments();
8875
});
@@ -92,4 +79,4 @@ const initPhotoModal = (photos, container) => {
9279
});
9380
};
9481

95-
export { initPhotoModal };
82+
export { registerPhotoModalEvents, openPhotoModal };

0 commit comments

Comments
 (0)