Skip to content

Commit d1002f0

Browse files
authored
Merge pull request #10 from NikitaKir98/module9-task1
Правда или действие
2 parents 40b890e + 25bb83b commit d1002f0

File tree

5 files changed

+151
-4
lines changed

5 files changed

+151
-4
lines changed

index.html

Lines changed: 3 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" autocomplete="off" method="post" action="https://32.javascript.htmlacademy.pro/kekstagram" type="multipart/form-data">
3434

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

js/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import { renderThumbnails } from './thumbnail_render.js';
2+
import './photo_upload_form.js';
3+
import './validation.js';
24

35
renderThumbnails();

js/photo_upload_form.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { isEscapeKey } from './util.js';
2+
import { validateDescription, validateHashtags, getError } from './validation.js';
3+
4+
const GET_ERROR_TAGS = 'tags';
5+
const GET_ERROR_DESCRIPTION = 'description';
6+
7+
const body = document.querySelector('body');
8+
const overlayForm = document.querySelector('.img-upload__overlay');
9+
const closeBtnForm = overlayForm.querySelector('.img-upload__cancel');
10+
const uploadForm = document.querySelector('.img-upload__form');
11+
const inputDescription = uploadForm.querySelector('.text__description');
12+
const inputHashtags = uploadForm.querySelector('.text__hashtags');
13+
const uploadSubmit = uploadForm.querySelector('.img-upload__submit');
14+
const uploadFile = document.querySelector('#upload-file');
15+
16+
const pristine = new Pristine(uploadForm, {
17+
classTo: 'img-upload__field-wrapper',
18+
errorTextParent: 'img-upload__field-wrapper',
19+
errorTextClass: 'img-upload__field-wrapper--error'
20+
});
21+
22+
const onHashtagsInput = () => {
23+
if (pristine.validate()) {
24+
uploadSubmit.disabled = false;
25+
return;
26+
}
27+
28+
uploadSubmit.disabled = true;
29+
};
30+
31+
const onDescriptionInput = () => {
32+
if (pristine.validate()) {
33+
uploadSubmit.disabled = false;
34+
return;
35+
} uploadSubmit.disabled = true;
36+
};
37+
38+
const onDocumentKeydown = (event) => {
39+
if (isEscapeKey(event) && (document.activeElement === inputHashtags || document.activeElement === inputDescription)){
40+
return;
41+
}
42+
if (isEscapeKey(event)){
43+
/* eslint-disable no-use-before-define*/
44+
closeFormUpload();
45+
}
46+
};
47+
48+
const onClickFormUpload = () => {
49+
body.classList.add('modal-open');
50+
overlayForm.classList.remove('hidden');
51+
document.addEventListener('keydown', onDocumentKeydown);
52+
closeBtnForm.addEventListener('click', closeFormUpload);
53+
};
54+
55+
const closeFormUpload = () => {
56+
overlayForm.classList.add('hidden');
57+
body.classList.remove('modal-open');
58+
document.removeEventListener('keydown', onDocumentKeydown);
59+
closeBtnForm.removeEventListener('click', closeFormUpload);
60+
};
61+
62+
uploadFile.addEventListener('change', onClickFormUpload);
63+
64+
pristine.addValidator(inputHashtags, validateHashtags, getError(GET_ERROR_TAGS), false);
65+
inputHashtags.addEventListener('input', onHashtagsInput);
66+
67+
pristine.addValidator(inputDescription, validateDescription, getError(GET_ERROR_DESCRIPTION), false);
68+
inputDescription.addEventListener('input', onDescriptionInput);

js/post.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,15 @@ const onShowMoreClick = () => {
6666
const onDocumentKeydown = (event) => {
6767
if (isEscapeKey(event)) {
6868
event.preventDefault();
69-
closePost(); // eslint-disable-line
69+
/* eslint-disable no-use-before-define*/
70+
closePost();
7071
}
7172
};
7273

7374
const onPhotoCloseClick = (event) => {
7475
event.preventDefault();
75-
closePost(); // eslint-disable-line
76+
/* eslint-disable no-use-before-define*/
77+
closePost();
7678
};
7779

7880
const openPost = (post) => {

js/validation.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const DESCRIPTION_SYMBOLS_MAX = 140;
2+
const HASHTAGS_SYMBOLS_MAX = 20;
3+
const HASHTAGS_MAX = 5;
4+
5+
const errors = {
6+
tags: '',
7+
description: '',
8+
};
9+
10+
const validateDescription = (inputText) => {
11+
if (!inputText) {
12+
return true;
13+
}
14+
15+
const errorDescription = `Максимальная длина описания ${DESCRIPTION_SYMBOLS_MAX} символов.`;
16+
17+
if (inputText.length >= DESCRIPTION_SYMBOLS_MAX) {
18+
errors.description = errorDescription;
19+
return false;
20+
}
21+
return true;
22+
};
23+
24+
const validateHashtags = (value) => {
25+
const inputText = value.toLowerCase().trim();
26+
if (!inputText) {
27+
return true;
28+
}
29+
30+
const inputData = inputText.split(/\s+/);
31+
const rules = [
32+
{
33+
check: inputData.some((item) => item[0] !== '#'),
34+
error: 'Хэштег должен начинаться с символа "#".',
35+
},
36+
{
37+
check: inputData.some((item) => item === '#'),
38+
error: 'Хэштег не может состоять только из символа "#".',
39+
},
40+
{
41+
check: inputData.some((item) => item.indexOf('#', 1) >= 1),
42+
error: 'Хэштеги разделяются пробелами.'
43+
},
44+
{
45+
check: inputData.some((item, i) => inputData.includes(item, i + 1)),
46+
error: 'Хэштеги не должны повторяться.'
47+
},
48+
{
49+
check: inputData.some((item) => item.length > HASHTAGS_SYMBOLS_MAX),
50+
error: `Максимальная длина одного хэштега ${HASHTAGS_SYMBOLS_MAX} символов, включая символ "#".`
51+
},
52+
{
53+
check: inputData.length > HASHTAGS_MAX,
54+
error: `Хэштегов должно быть не больше ${HASHTAGS_MAX}.`
55+
},
56+
{
57+
check: inputData.some((item) => !/^#[a-zа-яё0-9]{1,19}$/i.test(item)),
58+
error: 'Хэштег содержит недопустимый символ.'
59+
},
60+
];
61+
62+
return rules.every((rule) => {
63+
if (rule.check) {
64+
errors.tags = rule.error;
65+
return false;
66+
}
67+
return true;
68+
});
69+
};
70+
71+
const getError = (field) => () => errors[field];
72+
73+
74+
export { validateDescription, validateHashtags, getError };

0 commit comments

Comments
 (0)