Personal website Message page (front-end jquery writing, backstage PHP read and write MySQL) _javascript tips

Source: Internet
Author: User
Tags comments prev

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

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 that this does not speak CSS, everyone tailored to their needs, 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:

1. Show Comments List

2. Ability to submit comments

3, to reply

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 the same thing, it's just a different place to initialize.

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 4 jobs to do, from code comments can be seen, now one of the explanation

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-f ORM "> ' + ' <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 clas s= "NO-CMT" > temporarily no comment </div> ' + ' <ul class= ' cmt-list ' ></ul> ' + ' <div class= ' f-clear ' ; ' + ' <div class= ' pager-box ' ></div> ' + ' </div> ' + ' </div> ' + ' </d
  Iv> ';
 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 methods

Put content in a 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 process 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 article:

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 (/\<\;/g, ' < ');
   T.content = T.content.replace (/\>\;/g, ' > '); str1 + = ' <li class= ' f-clear ' ><table><tbody><tr><td> ' + ' <span class= ' username ' > ' + t.username + ':</span></td><td> ' + ' <span class= ' child-content ' > ' + t.content + ' &LT;/SPAN&G
  T;</td></tr></tbody></table> ' + ' </li> '}//processing comments 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 (/\<\;/g, ' < ');
  _obj.content = _obj.content.replace (/\>\;/g, ' > '); var str2 = ' <li class= ' f-clear ' > ' + ' <div class= ' head g-cOl-1 "> ' + '  ' + ' </div> ' + ' <div class= ' cont ent 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.of Fset < 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 you need now has a comment reply, 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:self.belong, Parent: _parent, Email:email, Username:username, Content:value}, Success:function (_data) {//Unblock click _btn.attr (' data-d
   Isabled ', ');
   _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.getminute

    S () + ': ' + 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, parent:self.pagerbox[0), onchange:self.doCh
     Angepage.bind (self), label:{prev: ' < ', Next: ' > '}};
     } Self.keys[id] = index; Self.lists.push ({"id": ID, "username": Username, "time": Time, "content": Value, "Response"
     : []
     });
     Self.showlist (1);

     Self.pager._$setindex (1);
     }else {var index = self.keys[_parent], page = Self.pager.__index; self.lists[index][' response '].push ({"id": ID, "username": Username, "Time": TiMe, "Content": value});
    Self.showlist (page);
   } self.text.val (");
   else {alert (' comment failed, please comment again ');
   }, Error:function () {alert (' comment failed, please comment again ');
   Unblock click _btn.attr (' data-disabled ', ');
  _btn.html (' submit comments ');
}
 });

 }

There are 3 parameters: _btn, _text, _parent to have these three parameters because of comments or replies so that you can use the same function, so do not write separately.

Click is common to prevent multiple submissions, check the cookie has no username, email and other user information, do not use the identity of tourists, and then deal with the content, to remove the blank Ah, \ n replaced <br> and so on, after the test to launch the AJAX request.

After successful, put the new comments into the this.lists, and then perform the this.showlist (1) Refresh display

The PHP section is still not speaking and the SQL statement is as follows:

$parent = $_get[' parent '];
$belong = $_get[' belong '];
$content = htmlentities ($_get[' content '));
$username = $_get[' username '];

$email = $_get[' email ']; $query = "INSERT into Comments (Parent,belong,content,time,username,email) value ($parent, $belong, ' $content ', now (), ' $

Username ', ' $email ');

 Doclickresponse Functions fn.doclickresponse = function (_event) {var target = $ (_event.target);

 var id = target.attr (' Data-id '); if (Target.hasclass (' response ') && target.attr (' data-disabled ')!= ' true ') {//click reply var odiv = Document.create
  Element (' div ');
  Odiv.classname = ' cmt-form '; odiv.innerhtml = ' <textarea class= ' Cmt-text "placeholder=" welcome suggestions, ask questions and learn together! "></textarea> ' + ' <button class=" U-button resbtn "data-id=" ' + ID + ' "> Submit comment </button> ' + ' <a
  href= "javascript:void (0);" class= "Cancel" >[cancel reply]</a> ';
  Target.parent (). Parent (). append (Odiv);
  Odiv = null;
 Target.attr (' data-disabled ', ' true '); else if (Target.hasclass (' Cancel ')) {//Click to fetchrecovery var ppnode = Target.parent (). Parent (), ores = Ppnode.find ('. Response '). EQ (0);
  Target.parent (). remove ();
 Ores.attr (' data-disabled ', '); else if (target.hasclass (' resbtn ')) {//click comment var otext = target.parent (). Find ('. Cmt-text '). EQ (0), parent = target
  . attr (' Data-id ');

 THIS.ADDCMT (Target, otext, parent);
 }else{//Other case return! 1;

 }

};

According to Target.class to determine which button is clicked.

If you click Reply, generate HTML, put it in the back of this comment

var odiv = document.createelement (' div ');
Odiv.classname = ' cmt-form ';
odiv.innerhtml = ' <textarea class= ' Cmt-text "placeholder=" welcome suggestions, ask questions and learn together! "></textarea> ' +
     ' <button class=" U-button resbtn "data-id=" ' + ID + ' "> Submit comments </button> ' +
     ' Lt;a href= "javascript:void (0);" class= "Cancel" >[cancel reply]</a> ';
Target.parent (). Parent (). append (odiv);
Odiv = null;
Target.attr (' data-disabled ', ' true '); Block repeat generation of HTML

Click Cancel, just remove the generated

var ppnode = Target.parent (). Parent (),
 ores = Ppnode.find ('. Response '). EQ (0);
Target.parent (). remove ();
Ores.attr (' data-disabled ', '); Allow the Reply button to be clicked again

Click Submit to get the element and call the ADDCMT function directly

var otext = target.parent (). Find ('. Cmt-text ')-eq (0),
 parent = target.attr (' Data-id ');
THIS.ADDCMT (Target, otext, parent);

Note: When parent just generated HTML I put it on the data-id of the Submit button.

All the functions have been realized, and I hope that we can learn some inspiration.

Related Article

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.