Skip to content

Commit

Permalink
productcomments - post-comment.js rewritten
Browse files Browse the repository at this point in the history
  • Loading branch information
Oksydan committed Oct 31, 2023
1 parent 467658f commit 6cb2b5b
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 103 deletions.
208 changes: 111 additions & 97 deletions modules/productcomments/views/js/post-comment.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,143 @@
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
*/

jQuery(document).ready(function () {
const $ = jQuery;
$('body').on('click', '.js-post-product-comment', function (event) {
event.preventDefault();
showPostCommentModal();
});
DOMReady(() => {
const DOM_SELECTORS = {
BTN_POST_MODAL_BTN: '.js-post-product-comment',
POST_COMMENT_MODAL: '#post-product-comment-modal',
COMMENT_POSTED_MODAL: '#product-comment-posted-modal',
COMMENT_POST_ERROR_MODAL: '#product-comment-post-error',
COMMENT_POST_ERROR_MESSAGE: '#product-comment-post-error-message',
POST_COMMENT_FORM: '#post-product-comment-form',
POST_COMMENT_FORM_INPUTS: '#post-product-comment-form input[type="text"]',
POST_COMMENT_FORM_TEXTAREA: '#post-product-comment-form textarea',
POST_COMMENT_FORM_CRITERION_RATING: '#post-product-comment-form .criterion-rating input',
};
const postCommentModal = document.querySelector(DOM_SELECTORS.POST_COMMENT_MODAL);
const commentPostedModal = document.querySelector(DOM_SELECTORS.COMMENT_POSTED_MODAL);
const commentPostErrorModal = document.querySelector(DOM_SELECTORS.COMMENT_POST_ERROR_MODAL);
const commentForm = document.querySelector(DOM_SELECTORS.POST_COMMENT_FORM);
const getCommentPostModalInstance = () => bootstrap.Modal.getOrCreateInstance(postCommentModal);
const getCommentPostedModalInstance = () => bootstrap.Modal.getOrCreateInstance(commentPostedModal);
const getCommentPostErrorModalInstance = () => bootstrap.Modal.getOrCreateInstance(commentPostErrorModal);

const clearPostCommentForm = () => {
each(`${DOM_SELECTORS.POST_COMMENT_FORM_INPUTS}, ${DOM_SELECTORS.POST_COMMENT_FORM_TEXTAREA}`, (formElement) => {
formElement.value = '';
formElement.classList.remove('is-invalid');
});
each(DOM_SELECTORS.POST_COMMENT_FORM_CRITERION_RATING, (formElement) => {
formElement.value = 5;

const postCommentModal = $('#post-product-comment-modal');
postCommentModal.on('hidden.bs.modal', function () {
postCommentModal.modal('hide');
const event = new Event('change');
formElement.dispatchEvent(event);
});
}

const showPostErrorModal = (errorMessage) => {
getCommentPostedModalInstance()?.hide();
getCommentPostModalInstance()?.hide();
clearPostCommentForm();
});

const commentPostedModal = $('#product-comment-posted-modal');
const commentPostErrorModal = $('#product-comment-post-error');
const errorMessageElement = document.querySelector(DOM_SELECTORS.COMMENT_POST_ERROR_MESSAGE);

if (errorMessageElement) {
errorMessageElement.innerHTML = errorMessage;
}

function showPostCommentModal() {
commentPostedModal.modal('hide');
commentPostErrorModal.modal('hide');
postCommentModal.modal('show');
getCommentPostErrorModalInstance()?.show();
}

function showCommentPostedModal() {
postCommentModal.modal('hide');
commentPostErrorModal.modal('hide');
const showCommentPostedModal = () => {
getCommentPostErrorModalInstance()?.hide();
getCommentPostModalInstance()?.hide();
getCommentPostedModalInstance()?.show();

clearPostCommentForm();
commentPostedModal.modal('show');
}

function showPostErrorModal(errorMessage) {
postCommentModal.modal('hide');
commentPostedModal.modal('hide');
clearPostCommentForm();
$('#product-comment-post-error-message').html(errorMessage);
commentPostErrorModal.modal('show');
const showPostCommentModal = () => {
getCommentPostErrorModalInstance()?.hide();
getCommentPostedModalInstance()?.hide();
getCommentPostModalInstance()?.show();
}

const handleClickPostModalBtn = (e) => {
e.preventDefault();
showPostCommentModal();
}

function clearPostCommentForm() {
$('#post-product-comment-form input[type="text"]').val('');
$('#post-product-comment-form input[type="text"]').removeClass('vis-invalid');
$('#post-product-comment-form textarea').val('');
$('#post-product-comment-form textarea').removeClass('is-invalid');
$('#post-product-comment-form .criterion-rating input').val(3).change();
const handlePostCommentModalHidden = () => {
clearPostCommentForm();
}

function initCommentModal() {
$('#post-product-comment-modal .grade-stars').rating();
$('body').on('click', '.js-post-product-comment', function (event) {
event.preventDefault();
showPostCommentModal();
const handlePostCommentModal = (url, formData) => {
const { request } = useHttpRequest(url, {
headers: {
accept: '*/*',
}
});

$('#post-product-comment-form').submit(submitCommentForm);
request
.post(formData)
.json((jsonData) => {
if (jsonData) {
if (jsonData.success) {
clearPostCommentForm();
showCommentPostedModal();
} else if (jsonData.errors || jsonData.error) {
if (jsonData.errors) {
const { errors } = jsonData;
const errorList = `
<ul>
${errors.map((error) => `<li>${error}</li>`).join('')}
</ul>
`;

showPostErrorModal(errorList);
} else if (jsonData.error) {
showPostErrorModal(jsonData.error);
}
}
} else {
showPostErrorModal(`<p>${productCommentPostErrorMessage}</p>`);
}
})
.catch(() => {
showPostErrorModal(`<p>${productCommentPostErrorMessage}</p>`);
});
}

function submitCommentForm(event) {
const handleSubmitCommentForm = (event) => {
event.preventDefault();
var formData = $(this).serializeArray();
if (!validateFormData(formData)) {
const form = event.target;
const formDataArray = formSerializeArray(form);
const formData = fromSerialize(form);
const url = form.action;

if (!validateFormData(formDataArray)) {
return;
}
$.post($(this).attr('action'), $(this).serialize(), function(jsonData) {
if (jsonData) {
if (jsonData.success) {
clearPostCommentForm();
showCommentPostedModal();
} else {
if (jsonData.errors) {
var errorList = '<ul>';
for (var i = 0; i < jsonData.errors.length; ++i) {
errorList += '<li>' + jsonData.errors[i] + '</li>';
}
errorList += '</ul>';
showPostErrorModal(errorList);
} else {
const decodedErrorMessage = $("<div/>").html(jsonData.error).text();
showPostErrorModal(decodedErrorMessage);
}
}
} else {
showPostErrorModal(productCommentPostErrorMessage);
}
}).fail(function() {
showPostErrorModal(productCommentPostErrorMessage);
});

handlePostCommentModal(url, formData);
}

function validateFormData(formData) {
var isValid = true;
formData.forEach(function(formField) {
const fieldSelector = '#post-product-comment-form [name="'+formField.name+'"]';
const validateFormData = (formData) => {
let isValid = true;

formData.forEach((formField) => {
const fieldSelector = '[name="'+formField.name+'"]';
const fieldElement = commentForm.querySelector(fieldSelector);

if (!formField.value) {
$(fieldSelector).addClass('is-invalid');
fieldElement.classList.add('is-invalid');
isValid = false;
} else {
$(fieldSelector).removeClass('is-invalid');
fieldElement.classList.remove('is-invalid');
}
});

return isValid;
}

initCommentModal();
eventHandlerOn(document, 'click', DOM_SELECTORS.BTN_POST_MODAL_BTN, handleClickPostModalBtn);
eventHandlerOn(postCommentModal, 'hidden.bs.modal', handlePostCommentModalHidden);
eventHandlerOn(commentForm, 'submit', handleSubmitCommentForm);
});
5 changes: 4 additions & 1 deletion modules/productcomments/views/templates/hook/alert-modal.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-text" data-dismiss="modal" aria-label="{l s='OK' d='Modules.Productcomments.Shop'}">
<button type="button"
class="btn d-block w-100 btn-primary btn-text"
data-bs-dismiss="modal"
aria-label="{l s='OK' d='Modules.Productcomments.Shop'}">
{l s='OK' d='Modules.Productcomments.Shop'}
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<div class="modal-header">
<h5 class="modal-title h5">{l s='Write your review' d='Modules.Productcomments.Shop'}</h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span aria-hidden="true"></span>
</button>
</div>
<form id="post-product-comment-form" action="{$post_comment_url nofilter}" method="POST">
Expand All @@ -44,10 +44,15 @@
<li>
<div class="criterion-rating d-flex">
<label class="mb-0 me-1">{$criterion.name|escape:'html':'UTF-8'}:</label>
<div
class="grade-stars"
data-grade="3"
data-input="criterion[{$criterion.id_product_comment_criterion}]">
<div class="grade-stars">
{for $i=1 to 5}
<input
type="radio"
value="{$i}"
{if $i == 5}checked="checked"{/if}
name="criterion[{$criterion.id_product_comment_criterion}]"
>
{/for}
</div>
</div>
</li>
Expand Down

0 comments on commit 6cb2b5b

Please sign in to comment.