Skip to content

Commit 3d1279f

Browse files
authored
Merge pull request #9 from NoaVel/module9-task1
2 parents 03ad2c4 + f97d4ec commit 3d1279f

5 files changed

Lines changed: 161 additions & 9 deletions

File tree

index.html

Lines changed: 2 additions & 2 deletions
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">
@@ -233,7 +233,7 @@ <h2 class="success__title">Изображение успешно загруже
233233
<h2 class="data-error__title">Не удалось загрузить данные</h2>
234234
</section>
235235
</template>
236-
236+
<script src="vendor/pristine/pristine.min.js"></script>
237237
<script src="js/main.js" type="module"></script>
238238
<script src="js/functions.js"></script>
239239
</body>

js/check-hashtag-validity.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const MAX_HASHTAG_COUNT = 5;
2+
const MAX_HASHTAG_LENGTH = 20;
3+
const HASHTAG_REGEXP = /^#[a-zа-яё0-9]+$/i;
4+
5+
const normalizeHashtags = (value) => value
6+
.trim()
7+
.toLowerCase()
8+
.split(/\s+/)
9+
.filter((hashtag) => hashtag.length > 0);
10+
11+
const hasValidHashtagCount = (value) =>
12+
normalizeHashtags(value).length <= MAX_HASHTAG_COUNT;
13+
14+
const hasValidHashtagLength = (value) =>
15+
normalizeHashtags(value).every((hashtag) => hashtag.length <= MAX_HASHTAG_LENGTH);
16+
17+
const hasValidHashtagFormat = (value) =>
18+
normalizeHashtags(value).every((hashtag) => HASHTAG_REGEXP.test(hashtag));
19+
20+
const hasUniqueHashtags = (value) => {
21+
const hashtags = normalizeHashtags(value);
22+
return hashtags.length === new Set(hashtags).size;
23+
};
24+
25+
export {
26+
hasValidHashtagCount,
27+
hasValidHashtagLength,
28+
hasValidHashtagFormat,
29+
hasUniqueHashtags
30+
};

js/full-size-picture.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@ const likesCountNode = bigPictureNode.querySelector('.likes-count');
77
const commentsCaptionNode = bigPictureNode.querySelector('.social__caption');
88
const bigPictureCancelNode = bigPictureNode.querySelector('.big-picture__cancel');
99

10+
const onEscKeydown = (evt) => {
11+
if (evt.key === 'Escape') {
12+
evt.preventDefault();
13+
clearComments();
14+
bigPictureNode.classList.add('hidden');
15+
document.body.classList.remove('modal-open');
16+
document.removeEventListener('keydown', onEscKeydown);
17+
}
18+
};
19+
1020
const closeBigPicture = () => {
1121
clearComments();
1222
bigPictureNode.classList.add('hidden');
1323
document.body.classList.remove('modal-open');
1424
document.removeEventListener('keydown', onEscKeydown);
1525
};
1626

17-
const onEscKeydown = (evt) => {
18-
if (evt.key === 'Escape') {
19-
evt.preventDefault();
20-
closeBigPicture();
21-
}
22-
};
23-
2427
const onBigPictureCancelClick = (evt) => {
2528
evt.preventDefault();
2629
closeBigPicture();

js/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { photos } from './create-array-photos.js';
22
import { renderThumbnails } from './render-thumbnails.js';
3+
import { initUploadPhotoForm } from './upload-photo-form.js';
34

45
renderThumbnails(photos);
6+
initUploadPhotoForm();
57

js/upload-photo-form.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import {
2+
hasValidHashtagCount,
3+
hasValidHashtagLength,
4+
hasValidHashtagFormat,
5+
hasUniqueHashtags
6+
} from './check-hashtag-validity.js';
7+
8+
const MAX_COMMENT_LENGTH = 140;
9+
10+
const bodyNode = document.body;
11+
const uploadFormNode = document.querySelector('.img-upload__form');
12+
const uploadFileControl = uploadFormNode.querySelector('#upload-file');
13+
const uploadOverlayNode = uploadFormNode.querySelector('.img-upload__overlay');
14+
const uploadCancelButtonNode = uploadFormNode.querySelector('#upload-cancel');
15+
const hashtagsInputNode = uploadFormNode.querySelector('.text__hashtags');
16+
const descriptionInputNode = uploadFormNode.querySelector('.text__description');
17+
18+
const pristine = new Pristine(uploadFormNode, {
19+
classTo: 'img-upload__field-wrapper',
20+
errorTextParent: 'img-upload__field-wrapper',
21+
errorTextTag: 'div',
22+
errorTextClass: 'img-upload__field-wrapper--error'
23+
});
24+
25+
const isEscapeKey = (evt) => evt.key === 'Escape';
26+
27+
const hasValidCommentLength = (value) => value.length <= MAX_COMMENT_LENGTH;
28+
29+
const resetUploadPhotoForm = () => {
30+
uploadFormNode.reset();
31+
uploadFileControl.value = '';
32+
pristine.reset();
33+
};
34+
35+
const stopEscapePropagation = (evt) => {
36+
if (isEscapeKey(evt)) {
37+
evt.stopPropagation();
38+
}
39+
};
40+
41+
const onDocumentKeydown = (evt) => {
42+
if (isEscapeKey(evt)) {
43+
evt.preventDefault();
44+
uploadOverlayNode.classList.add('hidden');
45+
bodyNode.classList.remove('modal-open');
46+
document.removeEventListener('keydown', onDocumentKeydown);
47+
resetUploadPhotoForm();
48+
}
49+
};
50+
51+
const openUploadPhotoForm = () => {
52+
uploadOverlayNode.classList.remove('hidden');
53+
bodyNode.classList.add('modal-open');
54+
document.addEventListener('keydown', onDocumentKeydown);
55+
};
56+
57+
const closeUploadPhotoForm = () => {
58+
uploadOverlayNode.classList.add('hidden');
59+
bodyNode.classList.remove('modal-open');
60+
document.removeEventListener('keydown', onDocumentKeydown);
61+
resetUploadPhotoForm();
62+
};
63+
64+
const onUploadFileControlChange = () => {
65+
openUploadPhotoForm();
66+
};
67+
68+
const onUploadCancelButtonClick = (evt) => {
69+
evt.preventDefault();
70+
closeUploadPhotoForm();
71+
};
72+
73+
const onUploadFormSubmit = (evt) => {
74+
if (!pristine.validate()) {
75+
evt.preventDefault();
76+
}
77+
};
78+
79+
pristine.addValidator(
80+
hashtagsInputNode,
81+
hasValidHashtagCount,
82+
'Нельзя указать больше пяти хэштегов'
83+
);
84+
85+
pristine.addValidator(
86+
hashtagsInputNode,
87+
hasValidHashtagLength,
88+
'Максимальная длина одного хэштега — 20 символов'
89+
);
90+
91+
pristine.addValidator(
92+
hashtagsInputNode,
93+
hasValidHashtagFormat,
94+
'Хэштег должен начинаться с # и содержать только буквы и цифры'
95+
);
96+
97+
pristine.addValidator(
98+
hashtagsInputNode,
99+
hasUniqueHashtags,
100+
'Хэштеги не должны повторяться'
101+
);
102+
103+
pristine.addValidator(
104+
descriptionInputNode,
105+
hasValidCommentLength,
106+
'Длина комментария не может составлять больше 140 символов'
107+
);
108+
109+
const initUploadPhotoForm = () => {
110+
uploadFileControl.addEventListener('change', onUploadFileControlChange);
111+
uploadCancelButtonNode.addEventListener('click', onUploadCancelButtonClick);
112+
uploadFormNode.addEventListener('submit', onUploadFormSubmit);
113+
hashtagsInputNode.addEventListener('keydown', stopEscapePropagation);
114+
descriptionInputNode.addEventListener('keydown', stopEscapePropagation);
115+
};
116+
117+
export { initUploadPhotoForm };

0 commit comments

Comments
 (0)