Limit comment size to 1000 in UI
Whenever the limit is almost reached (90% of the length), a tooltip will appear. Once the limit is exceeded, the "Post" button will be disabled and the field will become red.
This commit is contained in:
parent
0196f0e546
commit
142a2dd2eb
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#commentsTabView .newCommentForm .message {
|
#commentsTabView .newCommentForm .message {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
resize: none;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
#commentsTabView .newCommentForm .submitLoading {
|
#commentsTabView .newCommentForm .submitLoading {
|
||||||
|
@ -77,6 +77,14 @@
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#commentsTabView .message.error {
|
||||||
|
color: #e9322d;
|
||||||
|
border-color: #e9322d;
|
||||||
|
-webkit-box-shadow: 0 0 6px #f8b9b7;
|
||||||
|
-moz-box-shadow: 0 0 6px #f8b9b7;
|
||||||
|
box-shadow: 0 0 6px #f8b9b7;
|
||||||
|
}
|
||||||
|
|
||||||
.app-files .action-comment>img {
|
.app-files .action-comment>img {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
'click .cancel': '_onClickCloseComment'
|
'click .cancel': '_onClickCloseComment'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_commentMaxLength: 1000,
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
|
OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
|
||||||
this.collection = new OCA.Comments.CommentCollection();
|
this.collection = new OCA.Comments.CommentCollection();
|
||||||
|
@ -80,7 +82,10 @@
|
||||||
|
|
||||||
this._avatarsEnabled = !!OC.config.enable_avatars;
|
this._avatarsEnabled = !!OC.config.enable_avatars;
|
||||||
|
|
||||||
|
this._commentMaxThreshold = this._commentMaxLength * 0.9;
|
||||||
|
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
|
_.bindAll(this, '_onTypeComment');
|
||||||
},
|
},
|
||||||
|
|
||||||
template: function(params) {
|
template: function(params) {
|
||||||
|
@ -162,6 +167,7 @@
|
||||||
this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28);
|
this.$el.find('.avatar').avatar(OC.getCurrentUser().uid, 28);
|
||||||
}
|
}
|
||||||
this.delegateEvents();
|
this.delegateEvents();
|
||||||
|
this.$el.find('textarea').on('keyup input change', this._onTypeComment);
|
||||||
},
|
},
|
||||||
|
|
||||||
_formatItem: function(commentModel) {
|
_formatItem: function(commentModel) {
|
||||||
|
@ -262,6 +268,7 @@
|
||||||
// spawn form
|
// spawn form
|
||||||
$comment.after($formRow);
|
$comment.after($formRow);
|
||||||
$formRow.data('commentEl', $comment);
|
$formRow.data('commentEl', $comment);
|
||||||
|
$formRow.find('textarea').on('keyup input change', this._onTypeComment);
|
||||||
|
|
||||||
// copy avatar element from original to avoid flickering
|
// copy avatar element from original to avoid flickering
|
||||||
$formRow.find('.avatar').replaceWith($comment.find('.avatar').clone());
|
$formRow.find('.avatar').replaceWith($comment.find('.avatar').clone());
|
||||||
|
@ -270,6 +277,27 @@
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onTypeComment: function(ev) {
|
||||||
|
var $field = $(ev.target);
|
||||||
|
var len = $field.val().length;
|
||||||
|
var $submitButton = $field.data('submitButtonEl');
|
||||||
|
if (!$submitButton) {
|
||||||
|
$submitButton = $field.closest('form').find('.submit');
|
||||||
|
$field.data('submitButtonEl', $submitButton);
|
||||||
|
}
|
||||||
|
$field.tooltip('hide');
|
||||||
|
if (len > this._commentMaxThreshold) {
|
||||||
|
$field.attr('data-original-title', t('comments', 'Allowed characters {count} of {max}', {count: len, max: this._commentMaxLength}));
|
||||||
|
$field.tooltip({trigger: 'manual'});
|
||||||
|
$field.tooltip('show');
|
||||||
|
$field.addClass('error');
|
||||||
|
}
|
||||||
|
|
||||||
|
var limitExceeded = (len > this._commentMaxLength);
|
||||||
|
$field.toggleClass('error', limitExceeded);
|
||||||
|
$submitButton.prop('disabled', limitExceeded);
|
||||||
|
},
|
||||||
|
|
||||||
_onClickCloseComment: function(ev) {
|
_onClickCloseComment: function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
var $row = $(ev.target).closest('.comment');
|
var $row = $(ev.target).closest('.comment');
|
||||||
|
@ -318,7 +346,7 @@
|
||||||
var message = $textArea.val().trim();
|
var message = $textArea.val().trim();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!message.length) {
|
if (!message.length || message.length > this._commentMaxLength) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,20 @@ describe('OCA.Comments.CommentsTabView tests', function() {
|
||||||
var testComments;
|
var testComments;
|
||||||
var clock;
|
var clock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dummy message with the given length
|
||||||
|
*
|
||||||
|
* @param {int} len length
|
||||||
|
* @return {string} message
|
||||||
|
*/
|
||||||
|
function createMessageWithLength(len) {
|
||||||
|
var bigMessage = '';
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
bigMessage += 'a';
|
||||||
|
}
|
||||||
|
return bigMessage;
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
|
clock = sinon.useFakeTimers(Date.UTC(2016, 1, 3, 10, 5, 9));
|
||||||
fetchStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'fetchNext');
|
fetchStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'fetchNext');
|
||||||
|
@ -201,7 +215,55 @@ describe('OCA.Comments.CommentsTabView tests', function() {
|
||||||
|
|
||||||
expect(createStub.notCalled).toEqual(true);
|
expect(createStub.notCalled).toEqual(true);
|
||||||
});
|
});
|
||||||
|
it('does not create a comment if the field length is too large', function() {
|
||||||
|
var bigMessage = '';
|
||||||
|
for (var i = 0; i < view._commentMaxLength * 2; i++) {
|
||||||
|
bigMessage += 'a';
|
||||||
|
}
|
||||||
|
view.$el.find('.message').val(bigMessage);
|
||||||
|
view.$el.find('form').submit();
|
||||||
|
|
||||||
|
expect(createStub.notCalled).toEqual(true);
|
||||||
|
});
|
||||||
|
describe('limit indicator', function() {
|
||||||
|
var tooltipStub;
|
||||||
|
var $message;
|
||||||
|
var $submitButton;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
tooltipStub = sinon.stub($.fn, 'tooltip');
|
||||||
|
$message = view.$el.find('.message');
|
||||||
|
$submitButton = view.$el.find('.submit');
|
||||||
|
});
|
||||||
|
afterEach(function() {
|
||||||
|
tooltipStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not displays tooltip when limit is far away', function() {
|
||||||
|
$message.val(createMessageWithLength(3));
|
||||||
|
$message.trigger('change');
|
||||||
|
|
||||||
|
expect(tooltipStub.calledWith('show')).toEqual(false);
|
||||||
|
expect($submitButton.prop('disabled')).toEqual(false);
|
||||||
|
expect($message.hasClass('error')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('displays tooltip when limit is almost reached', function() {
|
||||||
|
$message.val(createMessageWithLength(view._commentMaxLength - 2));
|
||||||
|
$message.trigger('change');
|
||||||
|
|
||||||
|
expect(tooltipStub.calledWith('show')).toEqual(true);
|
||||||
|
expect($submitButton.prop('disabled')).toEqual(false);
|
||||||
|
expect($message.hasClass('error')).toEqual(false);
|
||||||
|
});
|
||||||
|
it('displays tooltip and disabled button when limit is exceeded', function() {
|
||||||
|
$message.val(createMessageWithLength(view._commentMaxLength + 2));
|
||||||
|
$message.trigger('change');
|
||||||
|
|
||||||
|
expect(tooltipStub.calledWith('show')).toEqual(true);
|
||||||
|
expect($submitButton.prop('disabled')).toEqual(true);
|
||||||
|
expect($message.hasClass('error')).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('editing comments', function() {
|
describe('editing comments', function() {
|
||||||
var saveStub;
|
var saveStub;
|
||||||
|
@ -336,6 +398,22 @@ describe('OCA.Comments.CommentsTabView tests', function() {
|
||||||
|
|
||||||
destroyStub.restore();
|
destroyStub.restore();
|
||||||
});
|
});
|
||||||
|
it('does not submit comment if the field is empty', function() {
|
||||||
|
var $comment = view.$el.find('.comment[data-id=1]');
|
||||||
|
$comment.find('.action.edit').click();
|
||||||
|
$comment.find('.message').val(' ');
|
||||||
|
$comment.find('form').submit();
|
||||||
|
|
||||||
|
expect(saveStub.notCalled).toEqual(true);
|
||||||
|
});
|
||||||
|
it('does not submit comment if the field length is too large', function() {
|
||||||
|
var $comment = view.$el.find('.comment[data-id=1]');
|
||||||
|
$comment.find('.action.edit').click();
|
||||||
|
$comment.find('.message').val(createMessageWithLength(view._commentMaxLength * 2));
|
||||||
|
$comment.find('form').submit();
|
||||||
|
|
||||||
|
expect(saveStub.notCalled).toEqual(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('read marker', function() {
|
describe('read marker', function() {
|
||||||
var updateMarkerStub;
|
var updateMarkerStub;
|
||||||
|
|
Loading…
Reference in New Issue