Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for multiple comments on a single page #35

Closed
shelane opened this issue Feb 1, 2016 · 15 comments
Closed

support for multiple comments on a single page #35

shelane opened this issue Feb 1, 2016 · 15 comments

Comments

@shelane
Copy link
Contributor

shelane commented Feb 1, 2016

We are working to implement this plugin on several sites through a framework. We provide the script automatically and it is included on the site. The include a div with a 'framework-comments' class and an id. We then do this:
$('.framework-comments').each(function(index, element) {
var ID = this.id;
$('#' + ID).comments({
... });
});

What we have noticed when two threads are placed on the same page, the first calls to get the comments work fine - they get the comments for the right ID. However, as soon as you go to post a new comment or reply, the ID remains that of the second div.

Any suggestions on how we might allow multiple threads on the same page?

@jjtykkyl
Copy link
Contributor

jjtykkyl commented Feb 2, 2016

I didn't quite understand what is the problem in your case. Would you happen to have a public demo site where I could reproduce the problem? If the problem is with the comment ids, as I interpreted, I hope you know that it's the responsibility of the backend to provide the correct ids to the created comments are replies.

@shelane
Copy link
Contributor Author

shelane commented Feb 4, 2016

So, I have removed the jQuery each from the equation and hard-code the call to two unique IDs.
http://codepen.io/shelanem/pen/eJLRro/
If you try to post anything on the left (new comment, update, upvote),it appears to "post" on the left, but the console shows it's acting on the object on the right. There is a console output to show this issue. Please let me know if this explains the issue.

@jjtykkyl
Copy link
Contributor

jjtykkyl commented Feb 4, 2016

One thing that comes to my mind is that the plugin instances utilize exactly the same callback function when there should be separate callback handler for each plugin instance. See the examples below:

Global handler

var globalPostCommentCallback = function() {
    console.log('Project unknown');
    ...
}

$('.framework-comments').each(function(index, element) {
    var ID = this.id;
    $('#' + ID).comments({
        postComment: globalPostCommentCallback
        ...
    });
});

Local handler

$('.framework-comments').each(function(index, element) {
    var ID = this.id;

    var localPostCommentCallback = function() {
        console.log('posting to project ' + ID);
        ...
    }

    $('#' + ID).comments({
        postComment: localPostCommentCallback
        ...
    });
});

@shelane
Copy link
Contributor Author

shelane commented Feb 4, 2016

I gave that a try and I was hopeful, but the log still shows that it is posting for the second project only. In my code pen posted above, I wasn't even using jQuery each, but just two distinctly defined comments with the local function as:
postComment: function(data, success, error) { console.log("POST com LEFT");
and
postComment: function(data, success, error) { console.log("POST com RIGHT");

However, the log will always show POST com RIGHT.

Your success function in the callback is always posting to the correct place though. I am going to look through your code to see if I can see why that is the case. You would know better than I in that case though.

@jjtykkyl
Copy link
Contributor

I was able to repeat the issue but unfortunately couldn't solve it in the given time. I shall look into this a bit later. If you're able to figure out the issue, we'd be more than delighted to review your pull request on this.

@shelane
Copy link
Contributor Author

shelane commented Mar 1, 2016

I have submitted a pull request. We found that the options were being overridden on the second call of the plugin. By moving the options defaults to a variable inside of the init function, it prevents the global Comments variable values from being overridden. The pull request also removes the the section that copied the fieldMappings then deleted them. By doing a deep extend, the fieldMapping values are set correctly. I did tests where I hard coded two calls with two different fieldMapping values and they retained the value correctly. I then did tests based on my original desire to do a jQuery.each on any div I had with a class of 'framework-comments' and outputted the ID of the div during the postComment function and it was working correctly. I did not minify the js file.

@blimey85
Copy link

@shelane would you mind sharing the JS you're using to handle multiple comment instances on the same page? I'm using your modified version but I'm not sure how to properly set it up. Do I need the entire blocked loaded over and over or just some parts specific to each comment block with a main configuration type block loaded first? Seems redundant to post huge blocks over and over on the page.

@shelane
Copy link
Contributor Author

shelane commented Apr 15, 2016

@blimey85
The HTML... are div tags that look like:

<div class="my-comments" id="thread-one"></div>

<div class="my-comments" id="thread-two"></div>

The JS (nevermind the formatting):
$('.my-comments').each(function(index, element) { var ID = this.id; $('#' + ID).comments({ getComments: function(success, error) { rqstComment('get', ID, success, error); }, postComment: function(commentOBJ, success, error) { rqstComment('post', ID, success, error, commentOBJ); }, putComment: function(commentOBJ, success, error) { rqstComment('put', ID, success, error, commentOBJ); }, deleteComment: function(commentOBJ, success, error) { rqstComment('delete', ID, success, error, commentOBJ); }, upvoteComment: function(commentOBJ, success, error) { rqstComment('upvote', ID, success, error, commentOBJ); } }) });

Of course the rqstComment function is where all our calls to the server are made.

@blimey85
Copy link

Thank you very much for the info. I have a small block that sets up the comments as the page loads (it's a Rails app and I load the comments in a single query with the items being commented on, rather than via ajax) and then the code as you showed loads on the page once, and handles everything else. And it works now!!! Thanks again!

@jessenieminen
Copy link
Member

@shelane Tons of thanks for your contribution, it is greatly appreciated!

We're terrible sorry for taking so long to react on the issue, we've had an incredibly busy spring and it will continue for a little while longer.

We'll definitely look into your pull request and are hoping to merge it a month or so, we unfortunately have our calendar swamped for now and need to test the PR thoroughly to ensure it's working correctly and will not create any new issues.

@wictorio
Copy link

@jessenieminen I am implementing around 18 comment elements on the same page using your plugin, thank you. @shelane, thanks for sharing and saving us time and nervs :) - I'm developing my backend in PHP - Codeigniter and I was wondering if you could also share with us how you built yours. Do you make ajax calls to the same URL and process it from there based on what parameters are submited or you call different URLs? Would you also share with us the rqstComment function or the whole working js?

@jlennoxmht
Copy link

Hi All,

We have used the jQuery-Comments and surface it inside a separate plugin called Fancy Box. It works simply because there is only one Fancy Box up at a time even though we have many SharePoint web parts using jQuery comments. I realize this is not quite what you are looking for but part of what we did is pertinent to your question. We are also wanting to have multiple comment displays on our page at the same time.

We created a module using a revealing module pattern with functions to get comments, create comments, update comments, delete comments, and to support the like and rating functions. We use 2 lists with a lookup column from the comments list back to the posts list. In our case we use AJAX calls with promises to surface the posts and the comments via search driven web parts.

The Viima code hands us back the current item so that we can easily couple it to our backend.

Here is an excerpt:

function BuildComments(Url, parentID, blogListId, blogListName, commentItems) {

    $('#comments-container').comments({

            profilePictureURL: 'https://viima-app.s3.amazonaws.com/media/user_profiles/user-icon.png',

            roundProfilePictures: true,

            textareaRows: 1,

            enableAttachments: true,

            getComments: function(success, error) {

                setTimeout(function() {

                    success(commentItems);

                }, 500);

            },

            postComment: function(data, success, error) {



                var self = this;

                setTimeout(function() {



                    var userName;

                    var userNamePromise = GetCurrentUser();

                    userNamePromise.done(function(userInfo) {

                        userName = userInfo.d.LoginName;



                        data.ParentPostID = parentID;

                        var commentsPromise = AddCommentItem(blogListName, data);

                        commentsPromise.done(function(comments) {

                            var item = JSON.parse(comments.body).d;

                            item.fullName = userName;                   

                            success(ConvertToJSON(item));                   

                        });

                    });



                }, 500);

            },

            putComment: function(data, success, error) {

                setTimeout(function() {

                    data.ParentPostID = parentID;

                    var updatePromise = UpdateCommentItem(blogListName, data);

                    updatePromise.done(function(comment) {

                        success(data);

                    });



                }, 500);

            },

            deleteComment: function(data, success, error) {

                setTimeout(function() {



                    data.ParentPostID = parentID;

                    var deletePromise = DeleteCommentItem(blogListName, data);

                    deletePromise.done(function(comment) {

                        success();

                    });



                }, 500);

            },

            upvoteComment: function(data, success, error) {

                setTimeout(function() {



                    var userVotedPromise = ICSNYComments.likeManager.GetUserLikedComment(Url, blogListId, data.id);

                    userVotedPromise.done(function(likes) {



                        var likesPromise = ICSNYComments.likeManager.LikeComment(Url, blogListId, data.id, likes.liked);

                        likesPromise.done(function() {

                            console.log('upvoted: ' + data.user_has_upvoted);

                            console.log('count: ' + data.upvote_count);

                            success(data);

                        });

                    });



                }, 500);

            },

            uploadAttachments: function(dataArray, success, error) {

                setTimeout(function() {

                    success(dataArray);

                }, 500);

            },

    });

}

From: wictorio [mailto:notifications@github.com]
Sent: Tuesday, April 19, 2016 8:05 AM
To: Viima/jquery-comments jquery-comments@noreply.github.com
Cc: jlennoxmht jim.lennox@acm.org
Subject: Re: [Viima/jquery-comments] support for multiple comments on a single page (#35)

@jessenieminen https://github.com/jessenieminen I am implementing around 18 comment elements on the same page using your plugin, thank you. @shelane https://github.com/shelane , thanks for sharing and saving us time and nervs :) - I'm developing my backend in PHP - Codeigniter and I was wondering if you could also share with us how you built yours. Do you make ajax calls to the same URL and process it from there based on what parameters are submited or you call different URLs? Would you also share with us the rqstComment function or the whole working js?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub #35 (comment) https://github.com/notifications/beacon/AJEMRdfbTfG5Wp0DwFSM7BA4HOUMUlQPks5p5MUFgaJpZM4HQ73r.gif

@shelane
Copy link
Contributor Author

shelane commented Apr 19, 2016

@jlennoxmht I have attached our rqstComment function...
The first call it makes is to the current site comment.php. This file (which I cannot share) creates a timestamp and a security token and returns that and the logged in username back to the request function. The token, time stamp, user, and some other data is then used with each call we make to our back end service. Our backend service is in Java which then checks the security token, validates user permissions, and saves that data.

The actual working code has a mixture of php and javascript. The php outputs some different items based on if the user is logged in. If the user is not logged in, javascript code to replace the comment text box with a log in link is displayed. If they are logged in, we know from the initial log in if the user is admin and will output the proper config items to jquery-comments.

rqstComment.txt

@wictorio
Copy link

@shelane very nicely designed, thanks for the generous share. I'm utilising session variables and my comments are lazy loaded with mediaelements via ajax. Before getting your reply I wrote simple function that does 'get' and 'post' comments and it works. It can be extended to the rest of the comments functionality.

function rqstComment(type, ID, success, error, commentJSON){
    jQuery.ajax({
        type: type,
        url: base_url + 'comments/'+ID,
        data: commentJSON,
        success: function(commentsArray) {
            success(commentsArray)
        },
        error: error
    });
}

Your function is much more sophisticated so I'm goint to incorporate some of the logic.

I think I will have to call .comments() function for each comment element separatelly.
Because my comments are lazy loading I can only fire up the $('.my-comments').each after all coments are loaded, which doesn't give a good user experiance.

@jjtykkyl
Copy link
Contributor

jjtykkyl commented Jul 4, 2016

We were finally able to check the pull-request and has now been merged into master branch. Thank you all for contributing, especially @shelane :)

@jjtykkyl jjtykkyl closed this as completed Jul 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants