Personal website Comment Message area production

Source: Internet
Author: User
Tags prev

First, on the personal site of the message page, you can see the effect: Message board

There's also an effect chart here.

In order to save the front end, use jquery to write, backstage use PHP simple read and write MySQL database. database design and implementation ideas

The database creates a table: comments, structure as follows:

All comments (including article comment reply, message board) are written in the same table, different comment areas with field belong distinguish

In the same comment area, the parent is 0 for comments, parent for a certain value of the comments expressed as the reply, the idea is not complicated.

Note, here does not speak CSS, everyone according to their needs customization, now start Packaging: set the function

We have to set the function according to their own needs, first of all, my website does not realize message reminders, instant Messaging functions, so comments reply will not prompt webmaster or users, will only have effect on the message area, so we simply realize the following functions:

Show Comments List

Ability to submit comments

Reply to comment class

We encapsulate the functionality of the comments into a class that can be instantiated to create different comment areas, so it's not hard to think

When instantiated, we need to pass in parameters that might include the ID of the comment area, the PHP address for the comment, and the PHP address for submitting the comment.

So we can assume that the code for the instantiated comment area might be:

var ocmt = new Comment ({
    Parent: $ (' #box '),                       //You want to put this comment on the page which element
    id:0,
    getcmturl: './php/ Getcomment.php ',
    setcmturl: './php/comment.php '
})

Of course, I'm defining a static method on the comment class.

Comment.allocate ({
   Parent: $ (' #box '),
   id:0,
   getcmturl: './php/getcomment.php ',
   setcmturl: './php/ comment.php '
})

It's a different place, just the initialization. Constructors

function Comment (options) {
    this.belong = options.id;
    This.getcmturl = Options.getcmturl;
    This.setcmturl = Options.setcmturl;
    This.lists = [];
    This.keys = {};
    This.offset = 5;
}

var fn = Comment.prototype;

Comment.allocate = function (options) {
    var ocmt = new Comment (options);
    if (Ocmt.belong = = undefined | |!ocmt.getcmturl | |!ocmt.setcmturl) {return
        null;
    };
    Ocmt.init (options);
    return OCMT;
};

Inside the variables and methods we slowly explain, if you do not define a allocate method, then you can write:

function Comment (options) {
    this.belong = options.id;
    This.getcmturl = Options.getcmturl;
    This.setcmturl = Options.setcmturl;
    This.lists = [];
    This.keys = {};
    This.offset = 5;
    if (This.belong = = undefined | |!this.getcmturl | |!this.setcmturl) {return
        null;
    };
    This.init (Options)
}

var fn = Comment.prototype;

Variable first, like I write the function first, and then need to add the property variable to go back to add, we just need to see the constructor finally executed:

This.init (Options)

The name can be seen as the initialization function. init function

Fn.init = function (options) {
    //Initialize node
    this.initnode (options);
    Putting the contents into the container
    this.parent.html (this.body);
    Initialize event
    this.initevent ();
    Get list
    this.getlist ();
};

fn for Comment.prototype, only say once, the following is no longer said.

Initialization is to have 4 jobs to do, from the code annotation can be seen, now a explain initnode function

The primary initialization node or cache Dom can be seen from the name

Fn.initnode = function (options) {//init wrapper box if (!!
    options.parent) {this.parent = Options.parent[0].nodetype = 1? Options.parent: $ (' # ' + options.parent);
    };
        if (!this.parent) {this.parent = $ (' div ');
    $ (' body '). Append (this.parent);
                          }//init Content This.body = (function () {var strhtml = ' <div class= ' m-comment ' > ' + "<div class=" Cmt-form "> ' + ' <textarea class=" Cmt-text "placeholder=" welcome suggestions, Ask questions and learn together. 
                          "></textarea> ' + ' <button class=" U-button u-login-btn "> Submit comments </button> ' +
                              ' </div> ' + ' <div class= ' cmt-content ' > ' + ' <div class= ' u-loading1 ' ></div> ' + ' <div class= ' NO-CMT ' > Not yet
  Comments </div> ' + ' <ul class= ' cmt-list ' ></ul> ' +                            ' <div class= ' f-clear ' > ' + ' <div class= ' Pager-box ' &G
                      T;</div> ' + ' </div> ' + ' </div> ' +
        ' </div> ';
    return $ (strhtml);
    })();
    init other node This.text = This.body.find ('. Cmt-text ')-eq (0);
    THIS.CMTBTN = This.body.find ('. U-button '). EQ (0);
    THIS.NOCMT = This.body.find ('. NO-CMT '). EQ (0);
    This.cmtlist = This.body.find ('. Cmt-list '). EQ (0);
    this.loading = This.body.find ('. u-loading1 '). EQ (0);
This.pagerbox = This.body.find ('. Pager-box '). EQ (0); };

In the code we can see that:

This.parent: The container node is saved
This.body: The HTML of the comment area is saved
This.text: Preserving the TEXTAREA elements of the commentary
THIS.CMTBTN: Save the Submit button
THIS.NOCMT: Save a text reminder when there is no comment
This.cmtlist: The container for the list is saved
This.loading: Save a loading GIF picture when loading a list
This.pagerbox: Pager Container When paging is required

JS is not difficult, are some jquery method to put the content into the container

This.parent.html (This.body)

This is nothing to say, very simple, at this time our comment component should be displayed on the page, but now does not load the comment list, also cannot comment, the following first load comment list getlist function

The first is to initialize the list, empty it, display the loaded GIF, hide the warning words without comments, and prepare to initiate the AJAX request.

The idea is to use PHP to all the comments in the comment area down, in front of the finishing, Ajax request for:

Fn.resetlist = function () {
    this.loading.css (' Display ', ' block ')
    this.noCmt.css (' Display ', ' none ');
    This.cmtList.html (");
Fn.getlist = function () {var self = this;

    This.resetlist ();
        $.ajax ({url:self.getCmtUrl, type: ' Get ', DataType: ' JSON ', data: {Id:self.belong},
                Success:function (data) {if (!data) {alert (' Get comment list failed ');
            Return! 1;
            };
            Organize comments list self.initlist (data);
            Self.loading.css (' Display ', ' none '); Show Comments List if (self.lists.length = 0) {//No comment self.noCmt.css (' Display ', ' block
            ');

                }else{//Set Page separator var total = Math.ceil (Self.lists.length/self.offset); Self.pager = new Pager ({index:1, total:total, parent:self.
                        Pagerbox[0], onchange:self.doChangePage.bind (self), label:{
  Prev: ' < ', Next: ' > '                  }
                });
        }, Error:function () {alert (' Get comment list failed ');
}
    }); };

Get form, and then the transfer ID passed, and the resulting data wanted to be an array of lists.

PHP content does not speak, the following post the SQL statement:

$id = $_get[' id '];
$query = "SELECT * from comments where belong= $id order by Time";
...
$str = ' [';
foreach ($result as $key => $value) { 
    $id = $value [' id '];   
    $username = $value [' username '];
    $time = $value [' time '];
    $content = $value [' content '];
    $parent = $value [' parent '];

    $str. = <<<end
        {
            "id": "{$id}",
            "parent": "{$parent}",            
            "username": "{$username. '",
            ' time ': ' {$time} ',
            ' content ': ' {$content} ',
            ' response ': []
        } end
;
}

    $str = substr ($str, 0,-1);
    $str. = '] ';
    Echo $str;

Get a JSON string, jquery Ajax can turn it into JSON data, and get the following data:

If the load succeeds, then we get a bunch of data, we are now in the success callback function, the data needs to be sorted in order to display, because now all comments are back to the same level. initlist function

Fn.initlist = function (data) {

    this.lists = [];   Save Comment List
    This.keys = {};   Save Comment ID and index corresponding table

    var index = 0;
    Traversal processing for
    (var i = 0, len = data.length i < len; i++) {

        var t = data[i],
            id = t[' id '];
        if (t[' parent '] = = 0) {
            This.keys[id] = index++;
            This.lists.push (t);
        } else{
            var parentid = t[' parent ',
                parentindex = This.keys[parentid];
            this.lists[parentindex][' response '].push (t);}};

My train of thought is: This.lists put are comments (parent 0 message), through the traversal of the data, if the parent is 0, push into this.lists; otherwise, the parent is not 0 means that this is a reply, find the corresponding comments, the reply to push into the comments of the RESP In Onse.

But there is a problem, because the ID is growing, there may be some comments are deleted, so ID and index does not necessarily match, so with This.keys save ID and index of the corresponding relationship.

Traversing all of the data can be done, and all of the this.lists, and then the rest of the thing is to turn the data into HTML and put it in the page.

Show Comments List
if (self.lists.length = 0) {
    //No comment
    self.noCmt.css (' Display ', ' block ');
} else{
    //Set page separator
    var total = Math.ceil (self.lists.length/self.offset);

    Self.pager = new Pager ({
        index:1,
        total:total,
        parent:self.pagerbox[0],
        onchange: Self.doChangePage.bind (self),
        label:{
            prev: ' < ',
            Next: ' > '
    }}

This is part of the callback function that was just ajax,success, which is when the data is sorted, and if the data is empty, then "no comment is displayed".

Otherwise, set the pager, the pager I used directly before the package, if interested can look at my previous blog:

Object-oriented: pager encapsulation

In short, it's going to go through the onchange function, the default number of pages is 1, stored in the parameter Obj.index

Fn.dochangepage = function (obj) {
    this.showlist (obj.index);
};
showlist function
Fn.showlist = (function () {/* generates a comment String */function Oneli (_obj) {var str1 = ';
            Processing reply for (var i = 0, len = _obj.response.length i < len; i++) {var t = _obj.response[i];
            T.content = T.content.replace (/\&lt\;/g, ' < ');
            T.content = T.content.replace (/\&gt\;/g, ' > '); str1 + = ' <li class= ' f-clear ' ><table><tbody><tr><td> ' + ' <span class= ' user Name ' > ' + t.username + ':</span></td><td> ' + ' <span class= ' child-content ' > ' + t
        . Content + ' </span></td></tr></tbody></table> ' + ' </li> '}
        Process comment var headimg = ';
        if (_obj.username = = "Kang") {headimg = ' kang_head.jpg ';
            }else{var index = Math.floor (Math.random () * 6) + 1; headimg = ' head ' + index + '. jpg '} _obj.content = _oBj.content.replace (/\&lt\;/g, ' < ');
        _obj.content = _obj.content.replace (/\&gt\;/g, ' > '); var str2 = ' <li class= ' f-clear ' > ' + ' <div class= ' head g-col-1 ' > ' + '  ' + ' </div> ' + ' <div class=" content g-col-19 ">  ' + ' <div class= ' f-clear ' > ' + ' <span class= ' username f-float-left ' > ' + _obj.username + ' </span> ' + ' <span class= ' time F-float-left ' > ' + _obj.time + ' </span> ' + ' </ Div> ' + ' <span class= "parent-content" > ' + _obj.content + ' </span> ' + ' <ul class = "Child-comment" > ' + str1 + ' </ul> ' + ' </div> ' + ' <div class= ' Respone-box g-col- 2 F-float-right "> ' + ' <a href=" javascript:void (0); "class=" f-show response "data-id=" ' + _obj.id + ' "" ;
        [Reply]</a> ' +    ' </div> ' + ' </li> ';

    return str2;


    };
            return function (page) {var len = this.lists.length, end = Len-(page-1) * This.offset, Start = End-this.offset < 0?
        0:end-this.offset, current = This.lists.slice (start, end);
        var cmtlist = '; for (var i = current.length-1 i >= 0; i--) {var t = current[i], index = this.keys[t[' id ']
            ];
            current[i][' index '] = index;
        Cmtlist + = Oneli (t);
    } this.cmtList.html (Cmtlist);
}; })();

The argument for this function is page, which is the number of pages, we intercept the this.lists data based on the number of pages, and then iterate through the generated HTML.

HTML templates I'm connected by strings, and I'm looking at people's preferences.

After the build this.cmtList.html (cmtlist), so that the list is displayed, the effect of the beginning of the picture.

The functionality that is needed now is commented back, and the Init function is left with only the last initevent initevent function

Fn.initevent = function () {
    //submit button click
    this.cmtBtn.on (' click ', This.addCmt.bind (this, this.cmtbtn, This.text, 0 ));
    Click Reply, click Cancel Reply, click the Submit Comment button in reply
    this.cmtList.on (' click ', This.doClickResponse.bind (this));

The screenshot above comes from my personal website, when we click Reply, we want to have a place to write the reply, can submit, can cancel, because these elements are added later, so we will host the behavior to the comment list this element.

The comment event function is submitted below. ADDCMT function

FN.ADDCMT = function (_btn, _text, _parent) {//Prevent multiple clicks if (_btn.attr (' data-disabled ') = = ' true ') {return!
    1;
    //Process Submit blank var value = _text.val (). Replace (/^\s+|\s+$/g, ');
    Value = Value.replace (/[\r\n]/g, ' <br > ');
        if (!value) {alert (' content cannot be empty ');
    Return! 1;
    //No click on _btn.attr (' data-disabled ', ' true ');
    _btn.html (' comments submitted ... ');

    Submit processing var self = this, email, username;
    Username = $.cookie (' user ');
    if (!username) {username = ' visitor ';
    email = $.cookie (' email ');
    if (!email) {email = ' default@163.com ';

    var now = new Date (); $.ajax ({type: ' Get ', DataType: ' json ', URL:THIS.SETCMTURL, data: {belong:s Elf.belong, Parent: _parent, Email:email, Username:username, Content:va Lue}, Success:function (_data) {//Unblock click _btn.attr (' Data-disabled ', ');
            _btn.html (' submit comments ');
                if (!_data) {alert (' comment failed, please comment again ');
            Return! 1;
                } if (_data[' result '] = = 1) {//Comment success alert (' comment success '); var id = _data[' id ', time = now.getfullyear () + '-' + (Now.getmonth () + 1) + '-' + now.getdate () + '

                ' + now.gethours () + ': ' + now.getminutes () + ': ' + now.getseconds ();

                    if (_parent = = 0) {var index = self.lists.length;
                        if (!self.pager) {//Set pager self.noCmt.css (' Display ', ' none ');

                        var total = Math.ceil (Self.lists.length/self.offset);
                            Self.pager = new Pager ({index:1, total:total, Paren

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.