jquery-comments is a jQuery plugin for implementing an out-of-the-box commenting solution to any web application with an existing backend. It provides all the UI functionalities and ties them to callbacks that let you easily define what you want to do with the data. The library is highly customizable and very easy to integrate thanks to a wide variety of settings.

http://viima.github.io/jquery-comments/demo/

1) Add the following to your HTML file

2) Initialize the library

If you are not using Font Awesome for icons, you should replace the icons with custom images by overriding following options when initializing the library:

The library expects the comment (and attachment) data to be provided with the structure demonstrated below. Please note that you can use fieldMappings to map the field names to match with your API.

Current user

profilePictureURL An url for profile picture of the current user. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ profilePictureURL: '/user_profiles/user-icon.png' });

currentUserIsAdmin A boolean value determing whether the current user is administarator DEFAULT false EXAMPLE $('#comments-container').comments({ currentUserIsAdmin: true });

Images

spinnerIconURL An url for spinner icon that is shown before comments have been fetched. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ spinnerIconURL: '/img/spinner.gif' });

upvoteIconURL An url for upvote icon that is used as a button for upvoting. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ upvoteIconURL: '/img/upvote-icon.png' });

replyIconURL An url for reply icon that is shown after the author of the comment if the comment is a reply. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ replyIconURL: '/img/reply-icon.png' });

uploadIconURL An url for upload icon that is used as a button for uploading attachments. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ uploadIconURL: '/img/upload-icon.png' });

attachmentIconURL An url for attachment icon that is used as a symbol for attachments. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ attachmentIconURL: '/img/attachment-icon.png' });

closeIconURL An url for close icon that is used as a button for closing commenting field. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ closeIconURL: '/img/close-icon.png' });

noCommentsIconURL An url for no-comments icon that is shown if there are no comments to show. Not required if Font Awesome is used. DEFAULT "" EXAMPLE $('#comments-container').comments({ noCommentsIconURL: '/img/no-comments-icon.png' });

Strings

textareaPlaceholderText A string that is displayed as a placeholder in commenting fields DEFAULT "Add a comment" EXAMPLE $('#comments-container').comments({ textareaPlaceholderText: 'Leave a comment' });

newestText A string that is displayed on sorting button for newest comments DEFAULT "Newest" EXAMPLE $('#comments-container').comments({ newestText: 'New' });

oldestText A string that is displayed on sorting button for oldest comments DEFAULT "Oldest" EXAMPLE $('#comments-container').comments({ oldestText: 'Old' });

popularText A string that is displayed on sorting button for most popular comments DEFAULT "Popular" EXAMPLE $('#comments-container').comments({ popularText: 'Most popular' });

attachmentsText A string that is displayed on sorting button for attachments DEFAULT "Attachments" EXAMPLE $('#comments-container').comments({ attachmentsText: 'Show attachments' });

sendText A string that is displayed on send button DEFAULT "Send" EXAMPLE $('#comments-container').comments({ sendText: 'Comment' });

replyText A string that is displayed on reply button DEFAULT "Reply" EXAMPLE $('#comments-container').comments({ replyText: 'Answer' });

editText A string that is displayed on edit button DEFAULT "Edit" EXAMPLE $('#comments-container').comments({ editText: 'Modify' });

editedText A string that is displayed on edited timestamp DEFAULT "Edited" EXAMPLE $('#comments-container').comments({ editedText: 'Modified' });

youText A string that is displayed as a name of the user for new comments by default DEFAULT "You" EXAMPLE $('#comments-container').comments({ youText: 'Me' });

saveText A string that is displayed on save button DEFAULT "Save" EXAMPLE $('#comments-container').comments({ saveText: 'Update' });

deleteText A string that is displayed on delete button DEFAULT "Delete" EXAMPLE $('#comments-container').comments({ deleteText: 'Remove' });

viewAllRepliesText A string that is displayed to show all replies when there are more replies than defined in maxRepliesVisible option. Variable __replyCount__ is used as a placeholder for the reply count. DEFAULT "View all __replyCount__ replies" EXAMPLE $('#comments-container').comments({ viewAllRepliesText: 'Show all replies (__replyCount__)' });

hideRepliesText A string that is displayed to hide replies that weren't visible initially DEFAULT "Hide replies" EXAMPLE $('#comments-container').comments({ hideRepliesText: 'Hide' });

noCommentsText A string that is displayed if there are no comments to show DEFAULT "No comments" EXAMPLE $('#comments-container').comments({ noCommentsText: 'There are no comments' });

noAttachmentsText A string that is displayed if there are no attachments to show DEFAULT "No attachments" EXAMPLE $('#comments-container').comments({ noAttachmentsText: 'There are no attachments' });

attachmentDropText A string that is used to inform the user where the attachments can be dropped DEFAULT "Drop files here" EXAMPLE $('#comments-container').comments({ attachmentDropText: 'Drop here' });

Colors

highlightColor

A css value for the highlight color that is used for example to highlight active sorting button and comments by admin DEFAULT #337AB7 EXAMPLE $('#comments-container').comments({ highlightColor: '#23A6F0' });

deleteButtonColor A css value for the color of the delete button DEFAULT #C9302C EXAMPLE $('#comments-container').comments({ deleteButtonColor: 'red' });

Functionalities

enableReplying A boolean value determing whether replying is enabled DEFAULT true EXAMPLE $('#comments-container').comments({ enableReplying: false });

enableEditing A boolean value determing whether editing is enabled DEFAULT true EXAMPLE $('#comments-container').comments({ enableEditing: false });

enableUpvoting A boolean value determing whether upvoting is enabled DEFAULT true EXAMPLE $('#comments-container').comments({ enableUpvoting: false });

enableDeleting A boolean value determing whether deleting is enabled DEFAULT true EXAMPLE $('#comments-container').comments({ enableDeleting: false });

enableDeletingCommentWithReplies A boolean value determing whether user is allowed to delete own comment that has replies (replies will be deleted as well) DEFAULT true EXAMPLE $('#comments-container').comments({ enableDeletingCommentWithReplies: false });

enableAttachments A boolean value determing whether attachments are enabled DEFAULT false EXAMPLE $('#comments-container').comments({ enableAttachments: true });

enableHashtags A boolean value determing whether hashtags are enabled. Enabling this functionality highlights the hashtags and the hashtagClicked callback function will be executed once the user has clicked a hashtag. DEFAULT false EXAMPLE $('#comments-container').comments({ enableHashtags: true });

enablePinging A boolean value determing whether pinging users is enabled. Enabling this functionality highlights the pings and the pingClicked callback function will be executed once the user has clicked a ping.



N.B.

The feature is depended on a javascript library called jquery-textcomplete

You need to implement the searchUsers callback function which returns a list of all users matching the ping

callback function which returns a list of all users matching the ping jquery-comments assumes that the pings are sent to the server in format @<user_id> , for example @145

, for example jquery-comments assumes that the pings are returned from the server in format @<user_fullname> , for example @Bryan Connery together with a dictionary of pinged users and respective full names

EXAMPLE { content: "What do you think @Bryan Connery?", pings: {254: "Bryan Connery"}, ... } Switching the ping format is required in order to keep the link between the user model and the ping so that the ping won't get broken in case the user changes her name for example. On the other hand, we expect the server to return the ping in user friendly format so that the API will always return comments in a format that can be displayed without processing. DEFAULT false EXAMPLE $('#comments-container').comments({ enablePinging: true });

enableNavigation A boolean value determing whether navigation is enabled DEFAULT true EXAMPLE $('#comments-container').comments({ enableNavigation: false });

postCommentOnEnter A boolean value determing whether comments will be posted by pressing enter DEFAULT false EXAMPLE $('#comments-container').comments({ postCommentOnEnter: true });

forceResponsive A boolean value determing whether the main navigation elements are presented in a dropdown DEFAULT false EXAMPLE $('#comments-container').comments({ forceResponsive: true });

readOnly A boolean value determing whether any actions are enabled DEFAULT false EXAMPLE $('#comments-container').comments({ readOnly: true });

Field mappings

fieldMappings A dictionary that is used to map the fields between jquery-comments and the server. The keys of the dictionary represent field names used within the jquery-comments whereas the values represent the field names from your API. In callback functions the data is remapped to match with your API so you can use the comment data as such. FIELDS id // Required parent // Required if replying is enabled created // Required modified // Required if editing is enabled content // Optional attachments // Required if attachments are enabled pings // Required if pinging is enabled creator // Required if pinging is enabled fullname // Required profilePictureURL // Optional isNew // Optional createdByAdmin // Optional createdByCurrentUser // Required if editing is enabled upvoteCount // Required if upvoting is enabled userHasUpvoted // Required if upvoting is enabled DEFAULT fieldMappings: { id: 'id', parent: 'parent', created: 'created', modified: 'modified', content: 'content', attachments: 'attachments', pings: 'pings', creator: 'creator', fullname: 'fullname', profilePictureURL: 'profile_picture_url', isNew: 'is_new', createdByAdmin: 'created_by_admin', createdByCurrentUser: 'created_by_current_user', upvoteCount: 'upvote_count', userHasUpvoted: 'user_has_upvoted' } EXAMPLE $('#comments-container').comments({ fieldMappings: { parent: 'comment_id', modified: 'edited', fullname: 'name', profilePictureURL: 'user_image', upvoteCount: 'upvotes', } });

Callbacks

refresh A callback function that is called after the comments have been rendered DEFAULT function() {} EXAMPLE $('#comments-container').comments({ refresh: function() { $('#comments-container').addClass('rendered'); } });

getComments A callback function that is used to fetch the comments array from the server. The callback provides both success and error callbacks which should be called based on the result from the server. The success callback takes the comment array as a parameter. DEFAULT function(success, error) { success([]); } EXAMPLE $('#comments-container').comments({ getComments: function(success, error) { $.ajax({ type: 'get', url: '/api/comments/', success: function(commentsArray) { success(commentsArray) }, error: error }); } });

searchUsers A callback function that is used for searching users when pinging. The callback provides both success and error callbacks which should be called based on the result from the server. The success callback takes the user array as a parameter. DEFAULT function(term, success, error) { success([]); } EXAMPLE $('#comments-container').comments({ searchUsers: function(term, success, error) { $.ajax({ type: 'get', url: '/api/users/?search=' + term, success: function(userArray) { success(userArray) }, error: error }); } });

postComment A callback function that is used to create a new comment to the server. The first parameter of the callback is commentJSON that contains the data of the new comment. The callback provides both success and error callbacks which should be called based on the result from the server. The success callback takes the created comment as a parameter. DEFAULT function(commentJSON, success, error) { success(commentJSON); } EXAMPLE $('#comments-container').comments({ postComment: function(commentJSON, success, error) { $.ajax({ type: 'post', url: '/api/comments/', data: commentJSON, success: function(comment) { success(comment) }, error: error }); } });

putComment A callback function that is used to update an existing comment to the server. The first parameter of the callback is commentJSON that contains the data of the updated comment. The callback provides both success and error callbacks which should be called based on the result from the server. The success callback takes the updated comment as a parameter. DEFAULT function(commentJSON, success, error) { success(commentJSON); } EXAMPLE $('#comments-container').comments({ putComment: function(commentJSON, success, error) { $.ajax({ type: 'put', url: '/api/comments/' + commentJSON.id, data: commentJSON, success: function(comment) { success(comment) }, error: error }); } });

deleteComment A callback function that is used to delete a comment from the server. The first parameter of the callback is commentJSON that contains the data of the comment to be deleted. The callback provides both success and error callbacks which should be called based on the result from the server. DEFAULT function(commentJSON, success, error) { success(); } EXAMPLE $('#comments-container').comments({ deleteComment: function(commentJSON, success, error) { $.ajax({ type: 'delete', url: '/api/comments/' + commentJSON.id, success: success, error: error }); } });

upvoteComment A callback function that is used to create or delete an upvote. The first parameter of the callback is commentJSON that contains the data of the upvoted comment. The callback provides both success and error callbacks which should be called based on the result from the server. The success callback takes the updated comment as a parameter. DEFAULT function(commentJSON, success, error) { success(commentJSON); } EXAMPLE $('#comments-container').comments({ upvoteComment: function(commentJSON, success, error) { var commentURL = '/api/comments/' + commentJSON.id; var upvotesURL = commentURL + '/upvotes/'; if(commentJSON.userHasUpvoted) { $.ajax({ type: 'post', url: upvotesURL, data: { comment: commentJSON.id }, success: function() { success(commentJSON) }, error: error }); } else { $.ajax({ type: 'delete', url: upvotesURL + upvoteId, success: function() { success(commentJSON) }, error: error }); } } });

validateAttachments A callback function that is used to validate attachments prior uploading them to server. The first parameter of the callback is attachments array including all the attachments to be uploaded. The callback function takes an array of validated attachments as a parameter.



Please see Working with attachments for more information. DEFAULT function(attachments, callback) { callback(attachments); } EXAMPLE $('#comments-container').comments({ validateAttachments: function(attachments, callback) { var validAttachments = []; $(attachments).each(function(index, attachment) { var maxFileSizeMb = 10; var fileSizeMb = attachment.file.size / 1000000; if(fileSizeMb <= maxFileSizeMb) { validAttachments.push(attachment); } }); callback(validAttachments); } });

hashtagClicked A callback function that is called after user has clicked a hashtag DEFAULT function(hashtag) {} EXAMPLE $('#comments-container').comments({ hashtagClicked: function(hashtag) { location.hash = 'tags/' + hashtag } });

pingClicked A callback function that is called after user has clicked a ping DEFAULT function(ping) {} EXAMPLE $('#comments-container').comments({ pingClicked: function(ping) { location.hash = 'users/' + ping } });

Formatters

textFormatter A callback function that is called for strings before inserting to DOM. Can be used for localization for instance. DEFAULT function(text) { return text; } EXAMPLE $('#comments-container').comments({ textFormatter: function(text) { return i18n.translate(text); } });

timeFormatter A callback function that is called for timestamps before inserting to DOM. Can be used for relative times for instance. DEFAULT function(time) { return new Date(time).toLocaleDateString(); } EXAMPLE $('#comments-container').comments({ timeFormatter: function(time) { return moment(time).fromNow(); } });

Miscellaneous

defaultNavigationSortKey A string value determing the default sorting. Possible values are newest , oldest , popularity and attachments DEFAULT "newest" EXAMPLE $('#comments-container').comments({ defaultNavigationSortKey: 'popularity' });

roundProfilePictures A boolean value determing whether profile pictures are rounded DEFAULT false EXAMPLE $('#comments-container').comments({ roundProfilePictures: true });

textareaRows An integer value determing how many rows there are in the commenting fields DEFAULT 2 EXAMPLE $('#comments-container').comments({ textareaRows: 1 });

textareaRowsOnFocus An integer value determing how many rows there are in the commenting fields on focus DEFAULT 2 EXAMPLE $('#comments-container').comments({ textareaRowsOnFocus: 4 });

textareaMaxRows An integer or a boolean value determing the maximum amount of rows in commenting fields as they increase when typing. If set to false , commenting fields will increase infinitely. DEFAULT 5 EXAMPLE $('#comments-container').comments({ textareaMaxRows: false });