scinote-web/app/assets/javascripts/comments.js.erb

570 lines
18 KiB
Text
Raw Normal View History

var Comments = (function() {
'use strict';
/**
* Initializes the comments
*
*/
function initializeComments(){
var comments;
if ( $('.step-comment') && $('.step-comment').length > 0 ) {
comments = $('.step-comment');
} else if ( $('.result-comment') && $('.result-comment').length > 0 ) {
comments = $('.result-comment');
}
if(!_.isUndefined(comments)) {
$.each(comments, function(){
var that = $(this);
var link = that.attr('data-href');
if(that.html().length === 0) {
$.ajax({ method: 'GET',
url: link,
beforeSend: animateSpinner(that, true) })
.done(function(data) {
that.html(data.html);
})
.always(function() {
animateSpinner(that, false);
});
}
initCommentForm(that);
initCommentFormNew(that);
initCommentsLink(that);
initCommentsLinkNew(that);
initDeleteCommentNew(that);
initEditCommentNew(that);
var scrollItem = that.find('.content-comments'); // Check for new version of comments
if (that.hasClass('content-comments')) {
scrollItem = that
}
scrollBottom(scrollItem);
});
}
}
// scroll to the botttom
function scrollBottom(id) {
var list;
if ( id.hasClass('content-comments') ) {
list = id;
} else {
list = id.find('.content-comments');
}
if ( list && list.length > 0) {
list.scrollTop($(list)[0].scrollHeight);
}
}
// Initialize show more comments link.
function initCommentsLink($el) {
$el.find('.btn-more-comments').off()
.on('ajax:success', function (e, data) {
if (data.html) {
var list = $(this).parents('ul');
var moreBtn = list.find('.btn-more-comments');
var listItem = moreBtn.parents('li');
$(data.html).insertAfter(listItem);
2016-09-27 23:31:37 +08:00
if (data.resultsNumber < data.perPage) {
moreBtn.remove();
} else {
2016-09-27 23:31:37 +08:00
moreBtn.attr('href', data.moreUrl);
moreBtn.trigger('blur');
}
var date;
$.each(list.find('.comment-date-separator'), function() {
if ( $(this).find('p').html() === date ) {
$(this).remove();
} else {
date = $(this).find('p').html();
}
});
// Reposition dropdown comment options
scrollCommentOptions(listItem
.closest('.content-comments')
.find('.dropdown-comment'));
2016-10-03 18:34:16 +08:00
} else {
$('.btn-more-comments').remove();
}
});
}
function initCommentsLinkNew($el) {
$el.find('.btn-more-comments-new').off()
.on('ajax:success', function (e, data) {
if (data.html) {
var stepId = $(this).data('step-id')
var list = $('#comments-list-' + stepId);
var moreBtn = $(this);
list.prepend(data.html);
if (data.resultsNumber < data.perPage) {
moreBtn.remove();
} else {
moreBtn.attr('href', data.moreUrl);
moreBtn.trigger('blur');
}
} else {
$('.btn-more-comments').remove();
}
});
}
// Initialize comment form.
function initCommentForm($el) {
var $form = $el.find('ul form');
$('.help-block', $form).addClass('hide');
$form.off().on('ajax:send', function () {
$('#comment_message', $form).attr('readonly', true);
})
.on('ajax:success', function (e, data) {
if (data.html) {
var list = $form.parents('ul');
// Remove potential 'no comments' element
list.parent().find('.content-comments')
.find('li.no-comments').remove();
// Find previous date separator
var dateSeparator = list.parent().find('.comment-date-separator:last');
if (dateSeparator.length > 0) {
// Parse string with creation date
var pr = dateSeparator.text().split('.');
var comm = data.date.split('.');
// Build Date objects and compare
var sepDate = new Date(pr[2], pr[1] - 1, pr[0]);
var commDate = new Date(comm[2], comm[1] - 1, comm[0]);
if (commDate > sepDate) {
// Add date separator
list.parent().find('.content-comments')
.append('<li class="comment-date-separator">\
<p class="text-center">' + data.date + '</p>\
</li>');
}
} else {
// Comment is the first one so add date separator
list.parent().find('.content-comments')
.append('<li class="comment-date-separator">\
<p class="text-center">' + data.date + '</p>\
</li>');
}
CounterBadge.updateCounterBadge(data.counter,
data.linked_id, 'comments');
list.parent().find('.content-comments')
.append('<li class="comment">' + data.html + '</li>')
.scrollTop(0);
list.parents('ul').find('> li.comment:gt(8)').remove();
$('#comment_message', $form).val('');
$('.form-group', $form)
.removeClass('has-error');
$('.help-block', $form)
.html('')
.addClass('hide');
scrollBottom($el);
}
})
.on('ajax:error', function (ev, xhr) {
if (xhr.status === 400) {
var messageError = xhr.responseJSON.errors.message;
if (messageError) {
$('.form-group', $form)
.addClass('has-error');
$('.help-block', $form)
.html(messageError[0])
.removeClass('hide');
}
}
})
.on('ajax:complete', function () {
scrollBottom($('#comment_message', $form));
$('#comment_message', $form)
.attr('readonly', false)
.focus();
});
}
function initCommentFormNew($el) {
var stepId = $el.data('step-id');
var $form = $('#new-message-' + stepId).find('form');
var $list = $el.find('.comments-list');
var $submitBtn = $form.find('.new-comment-button')
$submitBtn.on('click', function() {
$form.submit();
});
$('.help-block', $form).addClass('hide');
$form.off().on('ajax:send', function () {
$('#comment_message', $form).attr('readonly', true);
$submitBtn.off('click');
})
.on('ajax:success', function (e, data) {
if (data.html) {
$list.append(data.html).scrollTop(0);
scrollBottom($el);
$('#comment_message', $form).val('');
$('.form-group', $form).removeClass('has-error');
$('.help-block', $form).html('').addClass('hide');
$submitBtn.removeClass('has-error');
var currnetCount = $('#counter-' + stepId).html()
$('#counter-' + stepId).html(parseInt(currnetCount) + 1)
}
})
.on('ajax:error', function (ev, xhr) {
if (xhr.status === 400) {
var messageError = xhr.responseJSON.errors.message;
if (messageError) {
$('.form-group', $form).addClass('has-error');
$('.help-block', $form).html(messageError[0]).removeClass('hide');
$submitBtn.addClass('has-error');
}
}
})
.on('ajax:complete', function () {
scrollBottom($('#comment_message', $form));
$('#comment_message', $form).attr('readonly', false).focus();
$submitBtn.on('click', function() {
$form.submit();
});
});
}
function initCommentOptions(scrollableContainer, useParentOffset) {
if ( ! _.isUndefined(useParentOffset) ) {
2016-09-27 23:31:37 +08:00
useParentOffset = useParentOffset;
} else {
useParentOffset = true;
}
2016-10-05 21:39:54 +08:00
scrollCommentOptions($('.dropdown-comment'), useParentOffset);
// Reposition dropdown to the left
// (only do this when using parent offset)
if (useParentOffset) {
$(document).on('shown.bs.dropdown', '.dropdown-comment', function() {
var $el = $(this);
var menu = $el.find('.dropdown-menu');
var leftPos = $el.offset().left;
var parentTopPos = $el.offset().top;
if (leftPos + menu.width() > $(window).width()) {
menu.offset({ left: leftPos - menu.width(),
top: (parentTopPos +
<%= Constants::DROPDOWN_TOP_OFFSET_PX %>)});
}
});
}
// Reposition dropdowns vertically on scroll events
document.addEventListener('scroll', function (event) {
var $target = $(event.target);
var parent = $(scrollableContainer);
if ($target.length) {
2016-10-05 21:39:54 +08:00
scrollCommentOptions(parent.find('.dropdown-comment'), useParentOffset);
}
}, true);
}
2016-10-05 21:39:54 +08:00
function scrollCommentOptions(selector, useParentOffset) {
if ( ! _.isUndefined(useParentOffset) ) {
2016-10-05 21:39:54 +08:00
useParentOffset = useParentOffset;
} else {
useParentOffset = true;
}
_.each(selector, function(el) {
var $el = $(el);
2016-10-05 21:39:54 +08:00
var offset = useParentOffset ? $el.offset().top : $el.position().top;
$el.find('.dropdown-menu-fixed')
.offset({ top: (offset + <%= Constants::DROPDOWN_TOP_OFFSET_PX %>) });
$el.find('.dropdown-menu-fixed')
.position({ top: $el.position().top });
});
}
function initDeleteComments(parent) {
$(parent).on('click', '[data-action=delete-comment]', function(ev) {
ev.preventDefault();
var $this = $(this);
if (confirm($this.attr('data-confirm-message'))) {
$.ajax({
url: $this.attr('data-url'),
type: 'DELETE',
dataType: 'json',
success: function(data) {
// There are 3 possible actions:
// - (A) comment is the last comment in project
2016-09-27 17:03:10 +08:00
// - (B) comment is the last comment inside specific date
// (remove the date separator)
// - (C) comment is a usual comment
var commentEl = $this.closest('.comment');
// Case A
2016-09-27 17:03:10 +08:00
if (commentEl.prevAll('.comment').length === 0 &&
commentEl.next().length === 0) {
commentEl.after('<li class="no-comments"><em>' +
I18n.t('projects.index.no_comments') + '</em></li>');
}
// Case B
2016-09-27 17:03:10 +08:00
if (commentEl.prev('.comment-date-separator').length > 0 &&
commentEl.next('.comment').length === 0) {
commentEl.prev('.comment-date-separator').remove();
}
commentEl.remove();
CounterBadge.updateCounterBadge(data.counter,
data.linked_id,
'comments');
scrollCommentOptions($(parent).find('.dropdown-comment'));
},
error: function(data) {
// Display alert
alert(data.responseJSON.message);
}
});
}
});
}
function initDeleteCommentNew($el) {
var parents = $el.find('.comments-list')
$(parents).unbind('click').on('click', '[data-action=delete-comment-new]', function(e) {
e.preventDefault();
var $this = $(this)
if (confirm($this.attr('data-confirm-message'))) {
$.ajax({
url: $this.attr('data-url'),
type: 'DELETE',
dataType: 'json',
success: function(data) {
var commentEl = $this.closest('.comment-row').hide()
commentEl.remove();
var stepID = $this.attr('data-step-id')
var currnetCount = $('#counter-' + stepID).html()
$('#counter-' + stepID).html(parseInt(currnetCount) - 1)
},
error: function(data) {
// Display alert
alert(data.responseJSON.message);
}
});
}
});
}
function initEditComments(parent) {
$(parent).unbind('click').on('click', '[data-action=edit-comment]', function() {
2016-09-27 22:22:09 +08:00
var $this = $(this);
// close dropdown on click
var dropdown = $($this.parents(".dropdown-comment.open").get(0));
if(dropdown.length) { // safety first
dropdown.removeClass('open');
}
$.ajax({
url: $this.attr('data-url'),
type: 'GET',
dataType: 'json',
success: function(data) {
var commentEl = $this.closest('.comment');
2016-09-27 17:03:10 +08:00
var container = commentEl
.find('[data-role=comment-message-container]');
var oldMessage = container.find('[data-role=comment-message]');
var optionsBtn = commentEl.find('[data-role=comment-options]');
// Hide old message, append new HTML
oldMessage.hide();
optionsBtn.hide();
container.append(data.html);
var form = container.find('[data-role=edit-comment-message-form]');
2016-11-08 18:29:55 +08:00
var input = form.find('[data-role=message-input]');
var submitBtn = form.find('[data-action=save]');
var cancelBtn = form.find('[data-action=cancel]');
input.focus();
form
.on('ajax:send', function() {
input.attr('readonly', true);
})
.on('ajax:success', function(ev, data) {
var newMessage = input.val();
if (!_.isUndefined(data.comment)) {
newMessage = data.comment;
}
oldMessage.html(newMessage);
form.off('ajax:send ajax:success ajax:error ajax:complete');
submitBtn.off('click');
cancelBtn.off('click');
form.remove();
oldMessage.show();
optionsBtn.show();
})
.on('ajax:error', function(ev, xhr) {
if (xhr.status === 422) {
var messageError = xhr.responseJSON.errors.message;
if (messageError) {
$('.form-group', form)
.addClass('has-error');
$('.help-block', form)
.html(messageError[0] + ' |')
.removeClass('hide');
}
}
})
.on('ajax:complete', function() {
input.attr('readonly', false).focus();
});
submitBtn.on('click', function() {
form.submit();
});
cancelBtn.on('click', function() {
form.off('ajax:send ajax:success ajax:error ajax:complete');
submitBtn.off('click');
cancelBtn.off('click');
form.remove();
oldMessage.show();
optionsBtn.show();
});
},
2016-09-27 17:03:10 +08:00
error: function() {
// TODO
}
});
});
}
function initEditCommentNew($el) {
var editBtnSelector = '[data-action=edit-comment-new]';
var cancelBtnSelector = '[data-action=cancel-comment-new]';
var saveBtnSelector = '[data-action=save-comment-new]';
var commentMessageSelector = '.comment-message';
var textareaSelector = '.comment-textarea'
var parents = $el.find('.comments-list')
$(parents).on('click', commentMessageSelector, function(e) {
var $this = $(this);
startEditingMode($this.data('comment-id'))
})
$(parents).on('click', editBtnSelector, function(e) {
e.preventDefault();
var $this = $(this);
startEditingMode($this.closest('.comment-row').data('comment-id'))
})
$(parents).on('click', cancelBtnSelector, function(e) {
e.preventDefault();
var $this = $(this);
var commentId = $this.closest('.comment-row').data('comment-id')
var $commentTextArea = $('#comment-textarea-' + commentId);
$commentTextArea.val($commentTextArea.data('message'));
resetAllEditingModes();
})
$(parents).on('focusout', textareaSelector, function(e) {
var $this = $(this);
var $comment = $this.closest('.comment-row')
var commentId = $comment.data('comment-id');
if($this[0].dataset.editing == 0) return;
updateComment(commentId);
})
$(parents).on('click', saveBtnSelector, function(e) {
e.preventDefault();
var commentId = $(this).closest('.comment-row').data('comment-id');
updateComment(commentId);
});
}
function updateComment(commentId){
var $comment = $('#comment-' + commentId);
var $form = $comment.find('form');
var $textarea = $form.find('textarea');
var $commentMessage = $('#comment-message-' + commentId);
var $saveBtn = $comment.find('.save-comment-new');
$form
.off('ajax:send').on('ajax:send', function() {
$textarea.attr('readonly', true);
$saveBtn.addClass('hidden');
$textarea[0].dataset.editing = 0;
})
.off('ajax:success').on('ajax:success', function(ev, data) {
$commentMessage.html(data.comment);
$textarea.data('message', $textarea.val());
resetAllEditingModes();
})
.off('ajax:error').on('ajax:error', function(ev, xhr) {
if (xhr.status === 422) {
alert(xhr.responseJSON.errors.message)
}
else{
alert('Error. Cannot update comment!')
}
})
.off('ajax:complete').on('ajax:complete', function() {
$textarea.attr('readonly', false).focus();
$saveBtn.removeClass('hidden');
});
$form.submit();
}
function startEditingMode(commentId){
resetAllEditingModes();
var $commentTextArea = $('#comment-textarea-' + commentId);
var tempContent = $commentTextArea.val();
$commentTextArea[0].dataset.editing = 1;
$('#comment-'+commentId + ' > .comment-container').addClass('edit');
$commentTextArea.focus().val('').val(tempContent);
}
function resetAllEditingModes() {
$('.comment-container').removeClass('edit');
}
return {
initialize: initializeComments,
scrollBottom: scrollBottom,
moreComments: initCommentsLink,
initCommentsLinkNew: initCommentsLinkNew,
initCommentFormNew: initCommentFormNew,
initDeleteCommentNew: initDeleteCommentNew,
initEditCommentNew: initEditCommentNew,
form: initCommentForm,
initCommentOptions: initCommentOptions,
initDeleteComments: initDeleteComments,
initEditComments: initEditComments
};
})();