jquery-based list drag sort implementation code _jquery

Source: Internet
Author: User
Tags abs

Requirements

Drag sort, from the name is not difficult to imagine, is to hold down a row of data dragged to the desired sort position, save the new sort queue.

Ideas

First, establish an anchor point for the list row, bind the MouseDown and MouseUp events, move the object row to the target row when the mouse moves to the position you want to insert, and then sort all the rows that it passes through.

The idea is simple, but there are still a few issues to be aware of

1. Where to move can be considered as the location to insert into the target row.
2, move out of the top and bottom when judged as first and last.
3, move up and down the processing

Solve

About events

JavaScript in the mouse press and release event for Onmousedown,onmouseup,jquery is Mousedown,mouseup, so, here use MouseDown and MouseUp

First, you know how many rows the interface has, how high each row is, because to judge how far the mouse moves

Copy Code code as follows:

var tbodyheight=setting.frame.outerheight (); Setting.frame, Parent object
var linenum=$ ("."  +setting.dgline). length; Setting.dgline, every line of classname
var lineheight=math.ceil (Tbodyheight/linenum);

For all of the linenum (rows), in addition to the calculation of the row height, there is also the purpose is to use index (), through the sequence index values to move the row to the target location

When the MouseDown event is triggered, start counting the distance of the mouse movement to determine where the line is going to be moved.

Copy Code code as follows:

dgid=$ (This). attr (Setting.id); The id,setting.id of the moved row is the name used to mark the ID for each row
thisindex=$ ("#" +setting.linepre+dgid). index (); The index of the row, Setting.linepre, each row ID shutdown
thislinetop=$ ("#" +setting.linepre+dgid). Offset (). Top; The top value of the row
Topdistance=thisindex*lineheight; The distance of the line from the top of the first line
Downdistance= (linenum-thisindex-1) *lineheight; The distance of the line from the bottom of the last line


Dgid is mainly used to differentiate the identity of each row, the general list is the output of the program, if there is no such an ID, you can not tell which line is which line, so, in HTML, you need to define a store ID of the guy. Program through attr is to take this value to ensure that each row has its own unique value.

Thislinetop is mainly used to compute the height of the mouse movement and then determine which line to move according to the row height and index value. There is also a function to determine whether to press the moving anchor, if there is a value, that is, then the MouseUp is set up, if there is no value, the description is not pressed to the anchor point, MouseUp does not perform any action. Why do you do it? Because no matter where the mouse on the page, will trigger the MouseUp event, if not a judgment, will continue to execute, that will produce some problems.

Topdistance and Downdistance, used to determine whether the mouse has moved out of the list, if removed, that is, the distance of the mouse movement is greater than topdistance or downdistance, it can be judged to need to move to the first row or the last line.

MouseDown events Mainly do is these things, of course, in order to effect, but also can add some things

Copy Code code as follows:

$ ("#" +setting.linepre+dgid). CSS (' background ', setting.linehighlight); Highlight Move row
var left=e.pagex+20;
var Top=e.pagey;
Dg_tips (Left,top); Create a hint layer
$ (' body '). CSS (' cursor ', ' move '); Change the mouse gesture of a page
$ ("Body"). Disableselection (); Disable selecting page elements when moving the mouse after pressing the mouse
Setting.frame.mousemove (function (e) {//Let hint layer follow mouse movement
$ ("#dgf"). CSS ({"Left": e.pagex+setting.tipsoffsetleft+ ' px ', "top": e.pagey+ ' px '});
});

The purpose of these is only to make the operation more effective, such as Gaoliang, is to let users know, they operate which line. The tip layer also works the same.

About forbidden to select,. disableselection (); This is the jquery_ui method, if you have the use of jquery_ui, that can be used directly, if not used, you can do

Copy Code code as follows:

$ (' body '). each (function () {
$ (this). attr (' unselectable ', ' on '). CSS ({
'-moz-user-select ': ' None ',
'-webkit-user-select ': ' None ',
' User-select ': ' None '
}). each (function () {
This.onselectstart = function () {return false;};
});
});

Cancel Prohibit selection

Copy Code code as follows:

$ (' body '). each (function () {
$ (this). attr (' unselectable ', '). CSS ({
'-moz-user-select ': ',
'-webkit-user-select ': ',
' User-select ': '
});
});

Given the versatility, the following code does not use the. disableselection ();

Okay, here's the MouseUp event. Here the MouseUp event is bound to the body, because MouseUp if it is only bound to the anchor point, then when the mouse moves out of the anchor point, then release the mouse, you will find that the MouseUp event is not executed, because it will be considered as the MouseUp of other objects. Therefore, the safest method is to use $ (' body '). MouseUp. So basically there's no problem.

MouseUp trigger, the first thing to determine whether Thislinetop is a value to prevent meaningless event execution. Then determine whether the mouse is moving the distance is positive or negative, that is, move up or down.

var movedistance=e.pagey-thislinetop;

To handle differently in different directions.

Copy Code code as follows:

if (movedistance<0) {
if (thisindex!=0) {
Movedistance=math.abs (movedistance); When it's negative, take the absolute value.
if (MOVEDISTANCE&GT;LINEHEIGHT/2) {//To determine whether the moving distance exceeds 1/2 of the row height
if (movedistance>topdistance) {//If the move distance is greater than the distance to the top edge of the line
focusindex=0;
}else{
Focusindex=thisindex-math.ceil (Movedistance/lineheight);
}
$("." +setting.dgline). EQ (Focusindex). Before ($ ("#" +setting.linepre+dgid);//Insert the row into the target location
}
}
}else{
if (thisindex!=linenum-1) {
if (movedistance>lineheight/2+lineheight) {
if (movedistance>downdistance) {
Focusindex=linenum-1;
}else{
Focusindex=thisindex+math.ceil (Movedistance/lineheight)-1;
}
$("." +setting.dgline). EQ (Focusindex), after ($ ("#" +setting.linepre+dgid));
}
}
}

The reason to determine whether the moving distance exceeds 1/2 of the row height is because if only one small point is moved, it can be viewed as not moving. When the target index value is computed, the Math.ceil is used, the maximum is taken, and when the moving distance is greater than 0, the rounding is 1, because it is downward.

Moving up and down using different insertion methods, before and after, you can try to think about why to use before and after.

When you're done, you have to get rid of the effect of pressing the mouse.

Copy Code code as follows:

$ ("#dgf"). Remove ()//removing hint layer
$ ("#" +setting.linepre+dgid). CSS (' background ', ');//make highlighted rows normal
Dgid= ';//the ID value of the row will be moved empty
thislinetop=0;//will move the top value of the row to 0
$ (' body '). CSS (' cursor ', ' default ');//change mouse gesture to default

Basically, the main problem is dealing with moving and deciding where to insert. The others are very simple.

The complete encapsulation program is given below, including updating the data section

Copy Code code as follows:

/*
*
* Draglist.js
* @author Fuweiyi <fuwy@foxmail.com>
*
*/
(function ($) {
$.fn. Draglist=function (setting) {
var _setting = {
Frame: $ (this),
Dgline: ' DLL ',
Dgbutton: ' DLB ',
ID: ' Action-id ',
Linepre: ' List_ ',
Linehighlight: ' #ffffcc ',
TIPSOPACITY:80,
TIPSOFFSETLEFT:20,
tipsoffsettop:0,
Jsonurl: ',
Jsondata: {},
Maskloaddingicon: ',
Maskbackgroundcolor: ' #999 ',
Maskopacity:30,
MaskColor: ' #000 ',
Maskloadicon: ',
};
var setting = $.extend (_setting,setting);

var dgid= ', thisindex,thislinetop=0,topdistance,downdistance;
var tbodyheight=setting.frame.outerheight ();
var linenum=$ ("." +setting.dgline). length;
var lineheight=math.ceil (Tbodyheight/linenum);

$("." +setting.dgbutton). MouseDown (function (e) {
dgid=$ (This). attr (Setting.id);
thisindex=$ ("#" +setting.linepre+dgid). index ();
var left=e.pagex+20;
var Top=e.pagey;
thislinetop=$ ("#" +setting.linepre+dgid). Offset (). Top;
Topdistance=thisindex*lineheight;
Downdistance= (linenum-thisindex-1) *lineheight;
$ ("#" +setting.linepre+dgid). CSS (' background ', setting.linehighlight);

Dg_tips (Left,top);
$ (' body '). CSS (' cursor ', ' move ');
Unselect ();
Setting.frame.mousemove (function (e) {
$ ("#dgf"). CSS ({"Left": e.pagex+setting.tipsoffsetleft+ ' px ', "top": e.pagey+ ' px '});
});
});

$ (' body '). MouseUp (function (e) {
if (thislinetop>0) {
var movedistance=e.pagey-thislinetop;
if (movedistance<0) {
if (thisindex!=0) {
Movedistance=math.abs (movedistance);
if (MOVEDISTANCE&GT;LINEHEIGHT/2) {
if (movedistance>topdistance) {
focusindex=0;
}else{
Focusindex=thisindex-math.ceil (Movedistance/lineheight);
}
$("." +setting.dgline). EQ (Focusindex). Before ($ ("#" +setting.linepre+dgid));
Dg_update (Thisindex,focusindex);
}
}
}else{
if (thisindex!=linenum-1) {
if (movedistance>lineheight/2+lineheight) {
if (movedistance>downdistance) {
Focusindex=linenum-1;
}else{
Focusindex=thisindex+math.ceil (Movedistance/lineheight)-1;
}
$("." +setting.dgline). EQ (Focusindex), after ($ ("#" +setting.linepre+dgid));
Dg_update (Thisindex,focusindex);
}
}
}
$ ("#dgf"). Remove ();
$ ("#" +setting.linepre+dgid). CSS (' background ', ');
Dgid= ';
Thislinetop=0;
$ (' body '). CSS (' cursor ', ' default ');
Onselect ();
}
});

function Dg_update (thisindex,focusindex) {
Dg_mask ();
var start=thisindex<focusindex?thisindex:focusindex;
var end=thisindex<focusindex?focusindex:thisindex;
var ids= ', vals= ';
for (Var i=start;i<=end;i++) {
ids+=i==start?$ (".") +setting.dgline). EQ (i). attr (setting.id): ', ' +$ ("." +setting.dgline). EQ (i). attr (Setting.id);
Vals+=i==start?i: ', ' +i;
}
$.getjson (setting. jsonurl,{' do ': ' changeorders ', ' IDs ': IDs, ' Vals ': vals},function (d) {
$ ("#dg_mask"). Remove ();
});
}

function Dg_mask () {
var w=setting.frame.outerwidth ();
var h=setting.frame.outerheight ();
var top=setting.frame.offset (). Top;
var left=setting.frame.offset (). Left;
var mask= "<div id= ' dg_mask ' > is struggling to save ...</div>";
$ (' body '). Append (mask);
$ ("#dg_mask"). CSS ({"Background": "#999", "position": ' absolute ', ' width ': w+ ' px ', ' height ': h+ ' px ', ' line-height ': h+ ' Px ', ' top ': top+ ' px ', ' Left ': left+ ' px ', ' filter ': ' Alpha (opacity= ' +setting.maskopacity+ ') ', ' moz-opacity ': setting.maskopacity/100, ' opacity ': setting.maskopacity/100, ' text-align ': ' Center ', ' Color ': ' #000 '};
}

function Dg_tips (left,top) {
var floatdiv= "<div id= ' dgf ' style= ' padding:5px 10px;border:1px #444 solid: #fff; Background-color ( Opacity= "+setting.tipsopacity+"); Moz-opacity: "+setting.tipsopacity/100+"; Opacity: "+setting.tipsopacity/100+"; Position:absolute;left: "+left+" Px;top: "+top+" PX; ' > Move a record </div> ";
$ (' body '). Append (Floatdiv);
}

function Unselect () {
$ (' body '). each (function () {
$ (this). attr (' unselectable ', ' on '). CSS ({
'-moz-user-select ': ' None ',
'-webkit-user-select ': ' None ',
' User-select ': ' None '
}). each (function () {
This.onselectstart = function () {return false;};
});
});
}

function Onselect () {
$ (' body '). each (function () {
$ (this). attr (' unselectable ', '). CSS ({
'-moz-user-select ': ',
'-webkit-user-select ': ',
' User-select ': '
});
});
}
}
}) (JQuery);

Use

Copy Code code as follows:

<table cellpadding= "5" cellspacing= "0" class= "listtable" id= "listtable" >
<thead>
<tr>
&LT;TD class= "TD50" > Drag </td>
&LT;TD class= "td220" > Name </td>
</tr>
</thead>
<tbody id= "Drag_table" >
<!--{loop $lists $k $list}-->
<tr id= "list_{$list [' id ']} ' action-id= ' {$list [' id ']} ' class= ' Drag_line ' >
<td><div class= "Drag_orders" action-id= {$list [' id ']} ' ></div></div></td>
<td> here is a line </td>
</tr>
<!--{/loop}-->
</tbody>
</table>
<script type= "Text/javascript" >
$ ("#drag_table"). Draglist ({
Dgline: ' Drag_line ',
Dgbutton: ' Drag_orders ',
ID: ' Action-id ',
Linepre: ' List_ ',
Jsonurl: ' {_admin}?controller=contents&method=focus_form ',
Maskloadicon: ' {sys_url}views/admin/images/loading.gif '
});
</script>

The main parameters are Dgline,dgbutton,id,linepre and jsonurl, which should not be difficult to understand by looking at the HTML code.

About drag sort is so much, of course, can also make the effect more beautiful, hint more clearly, to help the user experience

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.