Skip to content

Commit 7e9ad25

Browse files
authored
Merge pull request #9 from suntira/module9-task1
2 parents 9af5448 + 4a3374a commit 7e9ad25

File tree

7 files changed

+146
-26
lines changed

7 files changed

+146
-26
lines changed

index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ <h2 class="pictures__title visually-hidden">Фотографии других
3030
<section class="img-upload">
3131
<div class="img-upload__wrapper">
3232
<h2 class="img-upload__title visually-hidden">Загрузка фотографии</h2>
33-
<form class="img-upload__form" id="upload-select-image" autocomplete="off">
33+
<form class="img-upload__form" id="upload-select-image" method="post" enctype="multipart/form-data" action= "https://31.javascript.htmlacademy.pro/kekstagram" autocomplete="off">
3434

3535
<!-- Изначальное состояние поля для загрузки изображения -->
3636
<fieldset class="img-upload__start">
@@ -234,5 +234,6 @@ <h2 class="data-error__title">Не удалось загрузить данны
234234
</section>
235235
</template>
236236
<script type="module" src="js\main.js"></script>
237+
<script src="vendor/pristine/pristine.min.js"></script>
237238
</body>
238239
</html>

js/gallery.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { renderPhoto } from './render-thumbnail.js';
22

3-
function renderGallery(photoDataArray) {
4-
renderPhoto(photoDataArray);
5-
}
3+
const renderGallery = (photoDataArray) => renderPhoto(photoDataArray);
64

75
export { renderGallery };

js/main.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { photosData } from './create-photo-descriptions.js';
22
import { renderGallery } from './gallery.js';
3+
import { initPhotoUploadForm } from './photo-upload-form.js';
34

45
renderGallery(photosData);
5-
6+
initPhotoUploadForm();

js/photo-upload-form.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { isEscapeKey, showModal } from './util.js';
2+
import { isValid, resetValidation } from './validations.js';
3+
4+
const photoLoadingElement = document.querySelector('.img-upload__input');
5+
const photoUploadOverlayElement = document.querySelector('.img-upload__overlay');
6+
const photoModalUploadCloseElement = document.querySelector('.img-upload__cancel');
7+
const photoUploadFormElement = document.querySelector('.img-upload__form');
8+
const hashtagsInputElement = photoUploadFormElement.querySelector('.text__hashtags');
9+
const commentInputElement = photoUploadFormElement.querySelector('.text__description');
10+
11+
const onDocumentKeydown = (evt) => {
12+
if (document.activeElement === hashtagsInputElement || document.activeElement === commentInputElement) {
13+
evt.stopPropagation();
14+
return;
15+
}
16+
17+
if (isEscapeKey(evt)) {
18+
evt.preventDefault();
19+
closePhotoUploadModal();
20+
}
21+
};
22+
23+
function closePhotoUploadModal () {
24+
showModal(photoUploadOverlayElement, false);
25+
document.removeEventListener('keydown', onDocumentKeydown);
26+
27+
photoUploadFormElement.reset();
28+
resetValidation();
29+
}
30+
31+
const onCloseButtonClick = (evt) => (evt.preventDefault(), closePhotoUploadModal());
32+
33+
const initPhotoUploadForm = () => {
34+
photoLoadingElement.addEventListener('change', () => {
35+
showModal(photoUploadOverlayElement);
36+
document.addEventListener('keydown', onDocumentKeydown);
37+
});
38+
39+
photoModalUploadCloseElement.addEventListener('click', onCloseButtonClick);
40+
};
41+
42+
hashtagsInputElement.addEventListener('keydown', (evt) => evt.stopPropagation());
43+
commentInputElement.addEventListener('keydown', (evt) => evt.stopPropagation());
44+
45+
photoUploadFormElement.addEventListener('submit', (evt) => !isValid() && evt.preventDefault());
46+
47+
48+
export { initPhotoUploadForm };

js/render-full-size-photo.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
1-
import { isEscapeKey } from './util.js';
1+
import { isEscapeKey, showModal } from './util.js';
22
import { DATA_ELEMENTS } from './photo-modal-elements.js';
33
import { renderNextComments, closeComments, initComments } from './comments.js';
44

5-
const showModal = (isShown = true) => {
6-
if (isShown) {
7-
DATA_ELEMENTS.photoModalElement.classList.remove('hidden');
8-
document.body.classList.add('modal-open');
9-
return;
10-
}
11-
12-
DATA_ELEMENTS.photoModalElement.classList.add('hidden');
13-
document.body.classList.remove('modal-open');
14-
};
15-
16-
function onDocumentKeydown(evt) {
5+
const onDocumentKeydown = (evt) => {
176
if (isEscapeKey(evt)) {
187
evt.preventDefault();
198
closePhotoModal();
209
}
21-
}
10+
};
2211

2312
function closePhotoModal() {
24-
showModal(false);
13+
showModal(DATA_ELEMENTS.photoModalElement, false);
2514
document.removeEventListener('keydown', onDocumentKeydown);
2615
closeComments();
2716
}
@@ -36,7 +25,7 @@ const renderModal = ({ url, description, likes, comments }) => {
3625
};
3726

3827
const openPhotoModal = (photo) => {
39-
showModal();
28+
showModal(DATA_ELEMENTS.photoModalElement);
4029
renderModal(photo);
4130
document.addEventListener('keydown', onDocumentKeydown);
4231
};

js/util.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
function getRandomInteger (min, max) {
1+
const body = document.body;
2+
3+
const getRandomInteger = (min, max) => {
24
const lower = Math.ceil(Math.min(Math.abs(min), Math.abs(max)));
35
const upper = Math.floor(Math.max(Math.abs(min), Math.abs(max)));
46
const result = Math.random() * (upper - lower + 1) + lower;
57

68
return Math.floor(result);
7-
}
9+
};
810

9-
function createRandomIntegerFromRangeGenerator (min, max) {
11+
const createRandomIntegerFromRangeGenerator = (min, max) => {
1012
const previousValues = [];
1113

1214
return function () {
@@ -21,7 +23,7 @@ function createRandomIntegerFromRangeGenerator (min, max) {
2123
previousValues.push(currentValue);
2224
return currentValue;
2325
};
24-
}
26+
};
2527

2628
const getRandomArrayElement = (elements) =>
2729
elements.length
@@ -35,4 +37,15 @@ const createIdGenerator = () => {
3537

3638
const isEscapeKey = (evt) => evt.key === 'Escape';
3739

38-
export {getRandomInteger, createRandomIntegerFromRangeGenerator, getRandomArrayElement, createIdGenerator, isEscapeKey};
40+
const showModal = (modal, isShown = true) => {
41+
if (isShown) {
42+
modal.classList.remove('hidden');
43+
body.classList.add('modal-open');
44+
return;
45+
}
46+
47+
modal.classList.add('hidden');
48+
body.classList.remove('modal-open');
49+
};
50+
51+
export {getRandomInteger, createRandomIntegerFromRangeGenerator, getRandomArrayElement, createIdGenerator, isEscapeKey, showModal};

js/validations.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const RE_VALID_HASHTAG = /^#[a-zа-яё0-9]{1,19}$/i;
2+
const MAX_HASHTAGS = 5;
3+
const MAX_LENGTH_COMMENT = 140;
4+
5+
const photoFormUploadElement = document.querySelector('.img-upload__form');
6+
const hashtagsInputElement = photoFormUploadElement.querySelector('.text__hashtags');
7+
const commentInputElement = photoFormUploadElement.querySelector('.text__description');
8+
9+
const pristine = new Pristine(photoFormUploadElement, {
10+
classTo: 'img-upload__field-wrapper',
11+
errorTextParent: 'img-upload__field-wrapper',
12+
errorTextClass: 'img-upload__error'
13+
});
14+
15+
const getHashtags = (value) => {
16+
if (!value.trim()) {
17+
return [];
18+
}
19+
return value.trim().split(/\s+/).filter((tag) => tag.length > 0);
20+
};
21+
22+
const validateHashtagFormat = (value) => {
23+
const hashtags = getHashtags(value);
24+
return hashtags.every((tag) => RE_VALID_HASHTAG.test(tag));
25+
};
26+
27+
const validateHashtagUnique = (value) => {
28+
const hashtags = getHashtags(value).map((t) => t.toLowerCase());
29+
return hashtags.length === new Set(hashtags).size;
30+
};
31+
32+
const validateHashtagCount = (value) => {
33+
const hashtags = getHashtags(value);
34+
return hashtags.length <= MAX_HASHTAGS;
35+
};
36+
37+
pristine.addValidator(
38+
hashtagsInputElement,
39+
validateHashtagFormat,
40+
'Неверный формат хэштега',
41+
1,
42+
true
43+
);
44+
45+
pristine.addValidator(
46+
hashtagsInputElement,
47+
validateHashtagUnique,
48+
'Хэштеги не могут повторяться',
49+
2,
50+
true
51+
);
52+
53+
pristine.addValidator(
54+
hashtagsInputElement,
55+
validateHashtagCount,
56+
`Нельзя добавить больше ${MAX_HASHTAGS} хэштегов`,
57+
3,
58+
true
59+
);
60+
61+
const validateCommentLength = (value) => value.length <= MAX_LENGTH_COMMENT;
62+
63+
pristine.addValidator(
64+
commentInputElement,
65+
validateCommentLength,
66+
`Комментарий не может превышать ${MAX_LENGTH_COMMENT} символов`
67+
);
68+
69+
export const isValid = () => pristine.validate();
70+
export const resetValidation = () => pristine.reset();

0 commit comments

Comments
 (0)