Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h2 class="pictures__title visually-hidden">Фотографии других
<section class="img-upload">
<div class="img-upload__wrapper">
<h2 class="img-upload__title visually-hidden">Загрузка фотографии</h2>
<form class="img-upload__form" id="upload-select-image" autocomplete="off">
<form class="img-upload__form" id="upload-select-image" method="post" enctype="multipart/form-data" action="https://31.javascript.htmlacademy.pro/kekstagram" autocomplete="off">

<!-- Изначальное состояние поля для загрузки изображения -->
<fieldset class="img-upload__start">
Expand Down Expand Up @@ -233,7 +233,7 @@ <h2 class="success__title">Изображение успешно загруже
<h2 class="data-error__title">Не удалось загрузить данные</h2>
</section>
</template>

<script src="vendor/pristine/pristine.min.js"></script>
<script src="js/main.js" type="module"></script>
<script src="js/functions.js"></script>
</body>
Expand Down
30 changes: 30 additions & 0 deletions js/check-hashtag-validity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const MAX_HASHTAG_COUNT = 5;
const MAX_HASHTAG_LENGTH = 20;
const HASHTAG_REGEXP = /^#[a-zа-яё0-9]+$/i;

const normalizeHashtags = (value) => value
.trim()
.toLowerCase()
.split(/\s+/)
.filter((hashtag) => hashtag.length > 0);

const hasValidHashtagCount = (value) =>
normalizeHashtags(value).length <= MAX_HASHTAG_COUNT;

const hasValidHashtagLength = (value) =>
normalizeHashtags(value).every((hashtag) => hashtag.length <= MAX_HASHTAG_LENGTH);

const hasValidHashtagFormat = (value) =>
normalizeHashtags(value).every((hashtag) => HASHTAG_REGEXP.test(hashtag));

const hasUniqueHashtags = (value) => {
const hashtags = normalizeHashtags(value);
return hashtags.length === new Set(hashtags).size;
};

export {
hasValidHashtagCount,
hasValidHashtagLength,
hasValidHashtagFormat,
hasUniqueHashtags
};
17 changes: 10 additions & 7 deletions js/full-size-picture.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ const likesCountNode = bigPictureNode.querySelector('.likes-count');
const commentsCaptionNode = bigPictureNode.querySelector('.social__caption');
const bigPictureCancelNode = bigPictureNode.querySelector('.big-picture__cancel');

const onEscKeydown = (evt) => {
if (evt.key === 'Escape') {
evt.preventDefault();
clearComments();
bigPictureNode.classList.add('hidden');
document.body.classList.remove('modal-open');
document.removeEventListener('keydown', onEscKeydown);
}
};

const closeBigPicture = () => {
clearComments();
bigPictureNode.classList.add('hidden');
document.body.classList.remove('modal-open');
document.removeEventListener('keydown', onEscKeydown);
};

const onEscKeydown = (evt) => {
if (evt.key === 'Escape') {
evt.preventDefault();
closeBigPicture();
}
};

const onBigPictureCancelClick = (evt) => {
evt.preventDefault();
closeBigPicture();
Expand Down
2 changes: 2 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { photos } from './create-array-photos.js';
import { renderThumbnails } from './render-thumbnails.js';
import { initUploadPhotoForm } from './upload-photo-form.js';

renderThumbnails(photos);
initUploadPhotoForm();

117 changes: 117 additions & 0 deletions js/upload-photo-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
hasValidHashtagCount,
hasValidHashtagLength,
hasValidHashtagFormat,
hasUniqueHashtags
} from './check-hashtag-validity.js';

const MAX_COMMENT_LENGTH = 140;

const bodyNode = document.body;
const uploadFormNode = document.querySelector('.img-upload__form');
const uploadFileControl = uploadFormNode.querySelector('#upload-file');
const uploadOverlayNode = uploadFormNode.querySelector('.img-upload__overlay');
const uploadCancelButtonNode = uploadFormNode.querySelector('#upload-cancel');
const hashtagsInputNode = uploadFormNode.querySelector('.text__hashtags');
const descriptionInputNode = uploadFormNode.querySelector('.text__description');

const pristine = new Pristine(uploadFormNode, {
classTo: 'img-upload__field-wrapper',
errorTextParent: 'img-upload__field-wrapper',
errorTextTag: 'div',
errorTextClass: 'img-upload__field-wrapper--error'
});

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

const hasValidCommentLength = (value) => value.length <= MAX_COMMENT_LENGTH;

const resetUploadPhotoForm = () => {
uploadFormNode.reset();
uploadFileControl.value = '';
pristine.reset();
};

const stopEscapePropagation = (evt) => {
if (isEscapeKey(evt)) {
evt.stopPropagation();
}
};

const onDocumentKeydown = (evt) => {
if (isEscapeKey(evt)) {
evt.preventDefault();
uploadOverlayNode.classList.add('hidden');
bodyNode.classList.remove('modal-open');
document.removeEventListener('keydown', onDocumentKeydown);
resetUploadPhotoForm();
}
};

const openUploadPhotoForm = () => {
uploadOverlayNode.classList.remove('hidden');
bodyNode.classList.add('modal-open');
document.addEventListener('keydown', onDocumentKeydown);
};

const closeUploadPhotoForm = () => {
uploadOverlayNode.classList.add('hidden');
bodyNode.classList.remove('modal-open');
document.removeEventListener('keydown', onDocumentKeydown);
resetUploadPhotoForm();
};

const onUploadFileControlChange = () => {
openUploadPhotoForm();
};

const onUploadCancelButtonClick = (evt) => {
evt.preventDefault();
closeUploadPhotoForm();
};

const onUploadFormSubmit = (evt) => {
if (!pristine.validate()) {
evt.preventDefault();
}
};

pristine.addValidator(
hashtagsInputNode,
hasValidHashtagCount,
'Нельзя указать больше пяти хэштегов'
);

pristine.addValidator(
hashtagsInputNode,
hasValidHashtagLength,
'Максимальная длина одного хэштега — 20 символов'
);

pristine.addValidator(
hashtagsInputNode,
hasValidHashtagFormat,
'Хэштег должен начинаться с # и содержать только буквы и цифры'
);

pristine.addValidator(
hashtagsInputNode,
hasUniqueHashtags,
'Хэштеги не должны повторяться'
);

pristine.addValidator(
descriptionInputNode,
hasValidCommentLength,
'Длина комментария не может составлять больше 140 символов'
);

const initUploadPhotoForm = () => {
uploadFileControl.addEventListener('change', onUploadFileControlChange);
uploadCancelButtonNode.addEventListener('click', onUploadCancelButtonClick);
uploadFormNode.addEventListener('submit', onUploadFormSubmit);
hashtagsInputNode.addEventListener('keydown', stopEscapePropagation);
descriptionInputNode.addEventListener('keydown', stopEscapePropagation);
};

export { initUploadPhotoForm };
Loading