From db64734193e468077aedf6e5089ac56f95cc6e31 Mon Sep 17 00:00:00 2001
From: Eric Rasmussen <ericrasmussen1@gmail.com>
Date: Tue, 2 Oct 2012 14:53:33 -0500
Subject: [PATCH] [gh-462] Add Draggable Views module to project

---
 sites/all/modules/draggableviews/LICENSE.txt  | 339 ++++++++++++
 sites/all/modules/draggableviews/README.txt   |  60 +++
 .../css/draggableviews_list.css               |  24 +
 .../draggableviews/draggableviews.api.php     |  24 +
 .../draggableviews/draggableviews.info        |  26 +
 .../draggableviews/draggableviews.install     | 111 ++++
 .../draggableviews/draggableviews.module      | 509 ++++++++++++++++++
 .../draggableviews/draggableviews.rules.inc   |  30 ++
 .../draggableviews_book.info                  |  13 +
 .../draggableviews_book.install               |  10 +
 .../draggableviews_book.module                | 110 ++++
 .../draggableviews_book.views.inc             |  32 ++
 .../draggableviews_book.views_default.inc     |  84 +++
 ...gableviews_book_views_handler_argument.inc |  31 ++
 .../handlers/draggableviews_handler_book.inc  |  47 ++
 .../draggableviews_hierarchy_handler_book.inc |  38 ++
 .../handlers/draggableviews_handler.inc       |  54 ++
 .../draggableviews_handler_fieldapi.inc       | 126 +++++
 .../draggableviews_handler_native.inc         |  71 +++
 .../draggableviews_hierarchy_handler.inc      |  72 +++
 ...raggableviews_hierarchy_handler_native.inc |  31 ++
 .../draggableviews/js/draggableviews_list.js  |  45 ++
 .../draggableviews/js/draggableviews_table.js |  37 ++
 .../draggableviews/test/draggableviews.test   | 425 +++++++++++++++
 .../draggableviews_test.info                  |  12 +
 .../draggableviews_test.module                |  11 +
 .../draggableviews_test.views_default.inc     | 248 +++++++++
 .../views/draggableviews.views.inc            |  56 ++
 ...draggableviews_handler_field_draggable.inc | 199 +++++++
 .../views/draggableviews_handler_sort.inc     | 112 ++++
 .../views/draggableviews_join_handler.inc     |  83 +++
 31 files changed, 3070 insertions(+)
 create mode 100644 sites/all/modules/draggableviews/LICENSE.txt
 create mode 100644 sites/all/modules/draggableviews/README.txt
 create mode 100644 sites/all/modules/draggableviews/css/draggableviews_list.css
 create mode 100644 sites/all/modules/draggableviews/draggableviews.api.php
 create mode 100644 sites/all/modules/draggableviews/draggableviews.info
 create mode 100644 sites/all/modules/draggableviews/draggableviews.install
 create mode 100644 sites/all/modules/draggableviews/draggableviews.module
 create mode 100644 sites/all/modules/draggableviews/draggableviews.rules.inc
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.info
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.install
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.module
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views.inc
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views_default.inc
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/draggableviews_book_views_handler_argument.inc
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_handler_book.inc
 create mode 100644 sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_hierarchy_handler_book.inc
 create mode 100644 sites/all/modules/draggableviews/handlers/draggableviews_handler.inc
 create mode 100644 sites/all/modules/draggableviews/handlers/draggableviews_handler_fieldapi.inc
 create mode 100644 sites/all/modules/draggableviews/handlers/draggableviews_handler_native.inc
 create mode 100644 sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler.inc
 create mode 100644 sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler_native.inc
 create mode 100644 sites/all/modules/draggableviews/js/draggableviews_list.js
 create mode 100644 sites/all/modules/draggableviews/js/draggableviews_table.js
 create mode 100644 sites/all/modules/draggableviews/test/draggableviews.test
 create mode 100644 sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.info
 create mode 100644 sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.module
 create mode 100644 sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.views_default.inc
 create mode 100644 sites/all/modules/draggableviews/views/draggableviews.views.inc
 create mode 100644 sites/all/modules/draggableviews/views/draggableviews_handler_field_draggable.inc
 create mode 100644 sites/all/modules/draggableviews/views/draggableviews_handler_sort.inc
 create mode 100644 sites/all/modules/draggableviews/views/draggableviews_join_handler.inc

diff --git a/sites/all/modules/draggableviews/LICENSE.txt b/sites/all/modules/draggableviews/LICENSE.txt
new file mode 100644
index 000000000..d159169d1
--- /dev/null
+++ b/sites/all/modules/draggableviews/LICENSE.txt
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/sites/all/modules/draggableviews/README.txt b/sites/all/modules/draggableviews/README.txt
new file mode 100644
index 000000000..c75fa1ed8
--- /dev/null
+++ b/sites/all/modules/draggableviews/README.txt
@@ -0,0 +1,60 @@
+DraggableViews
+==============
+
+This module provides dragging entities and saving their order.
+
+Quick install:
+ 1) Activate Draggableviews module at admin/modules
+ 2) Navigate to view edit-page, click on the first link at the Format section and then choose style "table".
+ 3) Click Add button at the "Fields" section and choose field "Content:title", add and apply.
+ 4) Click Add button at the "Fields" section and choose field "Draggableviews: Content", add apply.
+ 5) Click Add button at the "Sort criteria" section and choose field "Draggableviews: Weight", add and choose sort asc, then apply.
+ 6) Save the view and you're done.
+
+In the case of table standard drupal tabledrag.js javascript is used.
+
+We also support jQuery UI Sortable javascript. In order to use it please set display style HTML List.
+By default HTML list is displayed like grid. If you would like it to be displayed as list override
+CSS styles for example in following way:
+  .draggableviews-processed li.views-row { float: none; width: 100%; margin-left: 0; }
+
+One view/display to set order another to display
+================================================
+
+You can create one view to set the order and another view to display the order. Or even
+create one view with two separate displays. In a view that displays the order there
+should be no draggableviews field (that makes view sortable), then in the settings of
+the "draggableviews weight" sorting criteria there will be selectbox "Display sort as"
+where you can choose the source view of your weights. This is applicable when you use
+ Native handler.
+
+Permissions
+===========
+
+Please add "Access draggable views" permission to users who should be able to reorder views.
+
+Arguments handling
+==================
+
+Every time we save the order of a view, current set of arguments are saved with order.
+You can see this in draggableviews_structure table "args" column. By default when we display order we use all
+currently passed arguments to a view to "match" arguments in "args" column. This means that we can create
+a view with contextual filter or exposed filter criteria and save different orders for different sets of arguments.
+
+We can also completely ignore passed arguments using "Do not use any arguments (use empty arguments)" option
+in Arguments handling of Sort criteria Draggable views weight. Be aware that in this case empty arguments set
+will be used. So you can set order for a view when no arguments passed and then whatever arguments passed,
+empty set will be used.
+
+Prepare arguments with PHP code is an option when you would like to alter arguments before they passed to
+"matching" with "args" column. For us this means that we can create for example several exposed filters,
+but pass values of only one of values of exposed filters instead of all of them (like we create two exposed
+filters: author and node type, but take into account for ordering only node type).
+Please be aware that in PHP code arguments are passed as $arguments variable and you should return array.
+Contextual filters are number keyed and exposed filters are name keyed.
+
+Contextual link "Order view"
+============================
+
+If there is view with sort order draggableviews weight and the order is set by another view we show "Order view"
+contextual link for opening a view that sets the order.
diff --git a/sites/all/modules/draggableviews/css/draggableviews_list.css b/sites/all/modules/draggableviews/css/draggableviews_list.css
new file mode 100644
index 000000000..9ecf3ecfc
--- /dev/null
+++ b/sites/all/modules/draggableviews/css/draggableviews_list.css
@@ -0,0 +1,24 @@
+.draggableviews-processed {
+  float: left;
+}
+
+.draggableviews-processed li.views-row {
+  display: block;
+  float: left;
+  width: 180px;
+/*  height: 180px;  if required for fixed height displays */
+  margin: 10px;
+  padding: 5px;
+  cursor:move;
+}
+
+.draggableviews-processed li.views-row.ui-sortable-helper {
+  border: 1px dotted blue;
+}
+.draggableviews-processed li.views-row  {
+  border: 1px dotted grey;
+}
+
+.draggableviews-weight{
+  display:none;
+}
diff --git a/sites/all/modules/draggableviews/draggableviews.api.php b/sites/all/modules/draggableviews/draggableviews.api.php
new file mode 100644
index 000000000..25b52d444
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews.api.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Hooks provided by the Draggableviews module.
+ */
+
+/**
+ * If Native handler used, you can alter arguments set before saved to database.
+ *
+ * This can be used when you would like to exclude or add some of arguments
+ * to be recorded to database. Also you can add new records to be saved to
+ * database (for example for translated nodes, etc.)
+ *
+ * @see http://drupal.org/node/1463596#comment-5687620
+ *
+ * @param array $arguments
+ *   Array of arguments before saving.
+ * @param array $form_values
+ *   Array of submitted entity ids and weights.
+ * @param object $view
+ *   Views object.
+ */
+function hook_draggableviews_handler_native_arguments_alter(&$arguments, $view, &$form_values) {}
diff --git a/sites/all/modules/draggableviews/draggableviews.info b/sites/all/modules/draggableviews/draggableviews.info
new file mode 100644
index 000000000..7ca651faa
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews.info
@@ -0,0 +1,26 @@
+name = Draggableviews
+description = Makes Views draggable
+dependencies[] = views
+package = Views
+core = 7.x
+
+files[] = handlers/draggableviews_handler.inc
+files[] = handlers/draggableviews_hierarchy_handler.inc
+files[] = views/draggableviews_handler_field_draggable.inc
+files[] = views/draggableviews_handler_sort.inc
+files[] = views/draggableviews_join_handler.inc
+
+files[] = test/draggableviews.test
+
+files[] = handlers/draggableviews_handler_native.inc
+files[] = handlers/draggableviews_handler_fieldapi.inc
+files[] = handlers/draggableviews_hierarchy_handler_native.inc
+
+dependencies[] = entity
+
+; Information added by drupal.org packaging script on 2012-10-01
+version = "7.x-2.0+26-dev"
+core = "7.x"
+project = "draggableviews"
+datestamp = "1349093683"
+
diff --git a/sites/all/modules/draggableviews/draggableviews.install b/sites/all/modules/draggableviews/draggableviews.install
new file mode 100644
index 000000000..b1b3e9bc5
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews.install
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Draggableviews defines a new database schema
+ * for saving the order.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+function draggableviews_schema() {
+  $schema['draggableviews_structure'] = array(
+    'description' => 'The table saves the order settings of an draggableview.',
+    'fields' => array(
+      'dvid' => array(
+        'description' => 'The primary identifier.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'view_name' => array(
+        'description' => 'Makes the order unique for each view.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'view_display' => array(
+        'description' => 'Makes the order unique for each view display.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'args' => array(
+        'description' => 'Makes the order unique for a given set of arguments',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => FALSE,
+        'default' => '',
+      ),
+      'entity_id' => array(
+        'description' => 'Id of the entity that we are sorting (node, user, etc.).',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'weight' => array(
+        'description' => 'The order weight.',
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'parent' => array(
+        'description' => 'The order parent.',
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'dvid' => array('dvid'),
+    ),
+    'primary key' => array('dvid'),
+  );
+  return $schema;
+}
+
+/**
+ * Increase sizes of view_name and view_display fields of
+ * draggableviews_strucutre table.
+ */
+function draggableviews_update_7201() {
+  $new_field = array(
+    'description' => 'Makes the order unique for each view.',
+    'type' => 'varchar',
+    'length' => 128,
+    'not null' => TRUE,
+    'default' => '',
+  );
+  db_change_field('draggableviews_structure', 'view_name', 'view_name', $new_field);
+
+  $new_field = array(
+    'description' => 'Makes the order unique for each view display.',
+    'type' => 'varchar',
+    'length' => 64,
+    'not null' => TRUE,
+    'default' => '',
+  );
+  db_change_field('draggableviews_structure', 'view_display', 'view_display', $new_field);
+}
+
+/**
+ * Add "parent" field to draggableviews_strucutre table.
+ */
+function draggableviews_update_7202() {
+  // Commit 0fd7c9f create this as 7002().  This got rename to 7202().  Check if field exist.
+  if (!count(db_query("SHOW COLUMNS FROM `draggableviews_structure` WHERE Field = 'parent'")->fetchALL())) {
+    $spec = array(
+        'description' => 'The order parent.',
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 0,
+    );
+    db_add_field('draggableviews_structure', 'parent', $spec);
+  }
+}
diff --git a/sites/all/modules/draggableviews/draggableviews.module b/sites/all/modules/draggableviews/draggableviews.module
new file mode 100644
index 000000000..9194cdc31
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews.module
@@ -0,0 +1,509 @@
+<?php
+
+/**
+ * Implements hook_views_api().
+ */
+function draggableviews_views_api() {
+  return array(
+    'api' => 3,
+    'path' => drupal_get_path('module', 'draggableviews') . '/views',
+  );
+}
+
+/**
+ * Implements hook_form_alter().
+ *
+ * Alter views form to change button label.
+ */
+function draggableviews_form_alter(&$form, &$form_state, $form_id) {
+  if (isset($form['draggableviews']) && !empty($form['draggableviews'])) {
+    $view = $form_state['build_info']['args'][0];
+    // Check permissions and number of results.
+    if (!user_access('access draggableviews') || count($view->result) < 2) {
+      $form['actions']['submit']['#access'] = FALSE;
+      return;
+    }
+    $options = $view->field['draggableviews']->options['draggableviews'];
+    $form['actions']['submit']['#value'] = t($options['save_button_label']);
+    $form['actions']['submit']['#submit'] = array('draggableviews_views_submit');
+
+    if ($options['ajax']) {
+      $form['actions']['submit']['#ajax'] = array(
+        'callback' => 'draggableviews_view_draggabletable_form_ajax'
+      );
+    }
+    // Set action as current path.
+    $form['#action'] = url(current_path());
+    // Keep destination and other GET params.
+    if (count($_GET) > 1) {
+      $get = $_GET;
+      unset($get['q']);
+      if (!isset($_GET['destination'])) {
+        $get['destination'] = current_path() . '?' . drupal_http_build_query($get);
+      }
+      $form['#action'] .= '?' . drupal_http_build_query($get);
+    }
+  }
+}
+
+/**
+ * Save weight records after form submit.
+ */
+function draggableviews_views_submit($form, &$form_state) {
+  $view = $form_state['build_info']['args'][0];
+
+  // Use 'input' instead of mapped 'values' here. This is done because if in
+  // table display we sort by header then set weights and save, we got
+  // totally wrong results ($form_state['values']['draggableviews'] mapped
+  // wrong from $form_state['input']['draggableviews'])
+  $form_state['values']['draggableviews'] = $form_state['input']['draggableviews'];
+
+  // Set the weight.
+  $handler_object = draggableviews_get_handler_class($view->field['draggableviews']->options['draggableviews']['handler']);
+  $handler_object->set($form_state);
+
+  // Trigger the event "A view has been sorted"
+  if (module_exists('rules')) {
+    rules_invoke_event('draggableviews_rules_event_sorted', $view->name, $view->current_display);
+  }
+}
+
+/**
+ * Implementes hook_preprocess_views_view_table().
+ */
+function draggableviews_preprocess_views_view_table(&$vars) {
+  if ($order_view = _draggableviews_load_order_view($vars['view'])) {
+    // Add identation if hierarchy is available.
+    if (!empty($order_view->field['draggableviews']->options['draggableviews']['hierarchy_handler'])) {
+      $hierarchy_handler_object = draggableviews_get_handler_class($order_view->field['draggableviews']->options['draggableviews']['hierarchy_handler'], 'hierarchy_handler');
+      foreach ($vars['rows'] as $key => $row) {
+        $first_column = current(array_keys($row));
+        $field = (object) array('view' => $vars['view']);
+        $depth = $hierarchy_handler_object->get_depth($field, $key);
+        $vars['rows'][$key][$first_column] = theme('indentation', array('size' => $depth)) . $vars['rows'][$key][$first_column];
+      }
+    }
+  }
+
+  // Check whether this table view has draggableview field.
+  if (!isset($vars['view']->field['draggableviews'])) {
+    return;
+  }
+
+  // Check permissions.
+  if (!user_access('access draggableviews')) {
+    // Remove column "draggableviews" from results and header.
+    foreach ($vars['rows'] as &$row) {
+      unset($row['draggableviews']);
+    }
+    unset($vars['header']['draggableviews']);
+    return;
+  }
+
+  // Add table class.
+  $vars['classes_array'][] = 'draggable';
+
+  // Add row class.
+  foreach ($vars['row_classes'] as &$row_classes) {
+    $row_classes[] = 'draggable';
+  }
+
+  $vars['attributes_array']['id'] = drupal_html_id('draggableviews-table-' . $vars['view']->name . '-' . $vars['view']->current_display);
+  // Add javascript.
+  drupal_add_tabledrag($vars['attributes_array']['id'], 'order', 'sibling', 'draggableviews-weight');
+
+  // Add javascript for autosave functionality.
+  if ($vars['view']->field['draggableviews']->options['draggableviews']['ajax']) {
+    drupal_add_js(drupal_get_path('module', 'draggableviews') . '/js/draggableviews_table.js');
+  }
+  // Parent javascripts.
+  if (!empty($vars['view']->field['draggableviews']->options['draggableviews']['hierarchy_handler'])) {
+    drupal_add_tabledrag($vars['attributes_array']['id'], 'match', 'parent', 'draggableviews-parent', 'draggableviews-parent', 'draggableviews-id', FALSE);
+    drupal_add_tabledrag($vars['attributes_array']['id'], 'depth', 'group', 'draggableviews-depth', NULL, NULL, FALSE);
+  }
+}
+
+/**
+ * Implementes hook_preprocess_views_view_list().
+ */
+function draggableviews_preprocess_views_view_list(&$vars) {
+  // Check whether this table view has draggableview field.
+  if (!isset($vars['view']->field['draggableviews'])) {
+    return;
+  }
+
+  // Check permissions.
+  if (!user_access('access draggableviews')) {
+    return;
+  }
+
+  // Add class to ul item of the view.
+  $class = 'draggableviews-grid-' . $vars['view']->name . '-' . $vars['view']->current_display;
+  $vars['list_type_prefix'] = str_replace('>', ' class="' . $class . '">', $vars['list_type_prefix']);
+  // Add javascript.
+  drupal_add_library('system', 'ui.sortable');
+  // Add setting of the row class.
+  $js_setting = array('draggableviews_row_class' => $class);
+  // Add setting whether ajax enabled or not.
+  $js_setting['draggableviews_ajax'] = $vars['view']->field['draggableviews']->options['draggableviews']['ajax'];
+  drupal_add_js($js_setting, 'setting');
+  // Add custom js and css.
+  drupal_add_js(drupal_get_path('module', 'draggableviews') . '/js/draggableviews_list.js');
+  drupal_add_css(drupal_get_path('module', 'draggableviews') . '/css/draggableviews_list.css');
+}
+
+/**
+ * Implements hook_permission().
+ */
+function draggableviews_permission() {
+  return array(
+    'access draggableviews' => array(
+      'title' => t('Access draggable views'),
+      'description' => t('Give users the right to sort their views'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_ctools_plugin_type().
+ */
+function draggableviews_ctools_plugin_type() {
+  return array(
+    'handler' => array(
+      'use hooks' => FALSE,
+    ),
+    'hierarchy_handler' => array(
+      'use hooks' => FALSE,
+    ),
+  );
+}
+
+/**
+ * Implements hook_ctools_plugin_directory().
+ */
+function draggableviews_ctools_plugin_directory($module, $plugin) {
+  if (($module == 'draggableviews') && ($plugin == 'handler' || $plugin == 'hierarchy_handler')) {
+    return 'handlers';
+  }
+}
+
+/**
+ * Implements hook_contextual_links_view_alter().
+ *
+ * Adds "Order view" contextual link.
+ */
+function draggableviews_contextual_links_view_alter(&$element, $items) {
+  // Check permission to use draggable.
+  if (!user_access('access draggableviews')) {
+    return;
+  }
+  // Do not add contextual link on view preview.
+  if (module_exists('views_ui') && views_ui_contextual_links_suppress()) {
+    return;
+  }
+
+  // Add Draggableviews contextual link "Order view".
+  $views_ui_element = array();
+  if (isset($element['#element']['#views_contextual_links_info']['views_ui'])) {
+    $views_ui_element = $element['#element']['#views_contextual_links_info']['views_ui'];
+  }
+  // In case of block #views_contextual_links_info element is inside of
+  // 'content' and not '#element' directly.
+  // @see http://drupal.org/node/1413596#comment-5912688
+  if (empty($views_ui_element) && isset($element['#element']['content']['#views_contextual_links_info']['views_ui'])) {
+    $views_ui_element = $element['#element']['content']['#views_contextual_links_info']['views_ui'];
+  }
+
+  if ( !empty($views_ui_element['view_display_id']) && isset($views_ui_element['view'])) {
+    $display_id = $views_ui_element['view_display_id'];
+    $view = $views_ui_element['view'];
+    $view->build($display_id);
+
+    // Get the order view's path. Don't include itself.
+    if ($path = _draggableviews_get_order_path($view, FALSE)) {
+      $element['#links']['draggableviews-order'] = array(
+        'title' => t('Order view'),
+        'href' => $path,
+        'query' => array('destination' => current_path()),
+      );
+    }
+  }
+}
+
+/**
+ * Implements hook_views_post_execute().
+ */
+function draggableviews_views_post_execute(&$view) {
+  if (isset($view->field['draggableviews'])) {
+    // Move draggableviews field to last column
+    // otherwise tabledrag.js doesn't work.
+    $draggable_field = $view->field['draggableviews'];
+    unset($view->field['draggableviews']);
+    $view->field['draggableviews'] = $draggable_field;
+  }
+}
+
+/**
+ * Implements hook_post_render().
+ */
+function draggableviews_views_post_render(&$view, &$output, &$cache) {
+  // Hide "Save" button when there are no results available. We cannot do this
+  // in form_alter hook as view is not yet executed there.
+  if (empty($view->result)) {
+    $output = str_replace('<div class="form-actions form-wrapper" id="edit-actions">', '<div class="form-actions form-wrapper" id="edit-actions" style="display:none">', $output);
+  }
+}
+
+/**
+ * Get class of handler.
+ *
+ * @param object
+ *   Handler's class object.
+ */
+function draggableviews_get_handler_class($handler_name, $handler_type = 'handler') {
+  $objects = &drupal_static(__FUNCTION__);
+  if (!isset($objects[$handler_name])) {
+    ctools_include('plugins');
+    if ($class = ctools_plugin_load_class('draggableviews', $handler_type, $handler_name, 'handler')) {
+      $objects[$handler_name] = new $class();
+    }
+  }
+
+  return $objects[$handler_name];
+}
+
+/**
+ * Retrieve all sort plugins.
+ *
+ * Check whether handler class inherits draggablevies_handler.
+ *
+ * @return array
+ *   Array of proper draggableviews handlers.
+ */
+function draggableviews_get_handlers() {
+  ctools_include('plugins');
+  $handlers = ctools_get_plugins('draggableviews', 'handler');
+  $return = array();
+  foreach ($handlers as $handler_id => $handler) {
+    $handler_object = draggableviews_get_handler_class($handler_id);
+    if (in_array('draggableviews_handler', class_parents(get_class($handler_object)))) {
+      $return[$handler_id] = $handler_object;
+    }
+  }
+  return $return;
+}
+
+/**
+ * Retrieve all hierarchy plugins.
+ *
+ * Check whether handler class inherits draggablevies_hierarcy_handler.
+ *
+ * @return array
+ *   Array of proper draggableviews handlers.
+ */
+function draggableviews_get_hierarchy_handlers() {
+  ctools_include('plugins');
+  $handlers = ctools_get_plugins('draggableviews', 'hierarchy_handler');
+  $return = array();
+  foreach ($handlers as $handler_id => $handler) {
+    $handler_object = draggableviews_get_handler_class($handler_id);
+    if (in_array('draggableviews_hierarchy_handler', class_parents(get_class($handler_object)))) {
+      $return[$handler_id] = $handler_object;
+    }
+  }
+  return $return;
+}
+
+/**
+ * Ajax draggabletable submit handler.
+ */
+function draggableviews_view_draggabletable_form_ajax($form, $form_state) {
+  // Find the form element
+  $form_element = "form:has(input[name=form_build_id][value='{$form['form_build_id']['#value']}'])";
+
+  // Remove warning and asterisk.
+  return array('#type' => 'ajax', '#commands' => array(
+    ajax_command_remove("$form_element div.tabledrag-changed-warning"),
+    ajax_command_remove("$form_element span.tabledrag-changed"),
+    ajax_command_remove("$form_element div.draggableviews-changed-warning"),
+    ajax_command_invoke("$form_element ul.draggableviews-changed", 'removeClass', array('draggableviews-changed')),
+  ));
+}
+
+/**
+ * Get the draggable views weight sort of a view if there is one and return its
+ * ID. If there are multiple of these sorts the first is returned.
+ *
+ * @param $view
+ *   The view object.
+ *
+ * @return
+ *   The ID of the sort or FALSE if there isn't one.
+ */
+function _draggableviews_get_draggable_sort($view) {
+  foreach ($view->sort as $id => $sort) {
+    if ($sort->definition['handler'] == 'draggableviews_handler_sort') {
+      return $id;
+    }
+  }
+  return FALSE;
+}
+
+/**
+ * Evalutes the given PHP code, with the given variables defined.
+ *
+ * @param $code
+ *   The PHP code to run, without <?php ?>
+ * @param $arguments
+ *   Views arguments including values of exposed filters.
+ * @param $view
+ *   The view being sorted.
+ *
+ * @return
+ *   The return value of the evaled code.
+ */
+function _draggableviews_eval_return($code, $arguments, $view) {
+  return eval($code);
+}
+
+/**
+ * Load built order view.
+ */
+function _draggableviews_load_order_view($view, $include_self = TRUE) {
+  if ($order_view_name_display = _draggableviews_get_order_view_display($view, $include_self)) {
+    if ($order_view_name_display == 'self' && $include_self) {
+      $order_view = $view;
+    }
+    else {
+      list($order_view_name, $order_view_display) = explode(':', $order_view_name_display);
+      if ($order_view_name == $view->name)  {
+        $order_view = $view;
+      }
+      else {
+        // Need to get the order view, as order is not part of this one.
+        $order_view = views_get_view($order_view_name);
+        $order_view->build($order_view_display);
+      }
+    }
+
+    return $order_view;
+  }
+}
+
+/**
+ * Get the view display identifier.
+ *
+ * @param $view
+ *   The view object
+ *
+ * @return
+ *   A string with the view name and display id separated by ':'.
+ */
+function _draggableviews_get_order_view_display($view, $include_self = TRUE) {
+  // Proceed only if weight sort criteria is available.
+  if (!$sort_key = _draggableviews_get_draggable_sort($view)) {
+    return FALSE;
+  }
+  $order_view_display = $view->sort[$sort_key]->options['draggableviews_setting_view'];
+  if (empty($order_view_display)) {
+    return FALSE;
+  }
+  if (!$include_self) {
+    if ($order_view_display == 'self' || $order_view_display == $view->name . ':' . $view->current_display) {
+      return FALSE;
+    }
+  }
+  return $order_view_display;
+}
+
+/**
+ * Get the path to the order view.
+ *
+ * @param $view
+ *   The view object.
+ *
+ * @return
+ *   The path of the page or FALSE if there isn't one.
+ */
+function _draggableviews_get_order_path($view, $include_self = TRUE) {
+  $path = FALSE;
+  if ($order_view = _draggableviews_load_order_view($view, $include_self)) {
+    if (isset($order_view->display[$order_view->current_display]->display_options['path'])) {
+      $path = $order_view->display[$order_view->current_display]->display_options['path'];
+    }
+  }
+  elseif ($include_self) {
+    if (isset($view->display[$view->current_display]->display_options['path'])) {
+      $path = $view->display[$view->current_display]->display_options['path'];
+    }
+  }
+  else {
+    return FALSE;
+  }
+
+  // If page expects arguments, we provide arguments set to current view.
+  $args = $view->args;
+  if (strpos($path, '%') !== FALSE && !empty($args)) {
+    $new_path_array = array();
+    foreach (explode('/', $path) as $path_part) {
+      if (strpos($path_part, '%') !== FALSE) {
+        $new_path_array[] = (!empty($args)) ? array_shift($args) : '';
+      }
+      else {
+        $new_path_array[] = $path_part;
+      }
+    }
+    $path = implode('/', $new_path_array);
+  }
+  // If page path doesn't have % in the path or we still have some argument
+  // remain, simply append them to the end of the path.
+  if (!empty($args)) {
+    $path .= '/' . implode('/', $args);
+  }
+  return $path;
+}
+
+/**
+ * Helper function that returns an option list of all draggable views or let
+ * you inspect a specific view to see if it's a draggable view itself and
+ * returns the appropriate option for that.
+ *
+ * @param $view
+ *   The view object to incpect. Optional.
+ *
+ * @return
+ *   An option array of draggable views.
+ */
+function _draggableviews_get_views_options($view = NULL) {
+  if (!empty($view)) {
+    $view_clone = clone $view;
+    $view_clone->set_display($view_clone->current_display);
+    $view_clone->init_handlers();
+    if (isset($view_clone->field['draggableviews'])) {
+      return 'self';
+    }
+  }
+  // Check whether field exists for all enabled views. We only want the
+  // 'setting' views.
+  $views = views_get_enabled_views();
+  $options = array();
+
+  // Convert list of objects to options for the form.
+  foreach ($views as $view_name => $view) {
+    foreach ($view->display as $display_name => $display) {
+      if ($display_name == 'default') {
+        continue;
+      }
+      // Clone view and build it so we can see all the fields.
+      $view_clone = clone $view;
+      $view_clone->set_display($display_name);
+      $view_clone->init_handlers();
+
+      // If draggableviews field attached, show this view in options.
+      if (isset($view_clone->field['draggableviews'])) {
+        $options[$view_name . ':' . $display_name] = $view->human_name . ' (' . $display->display_title . ')';
+      }
+    }
+  }
+  return $options;
+}
diff --git a/sites/all/modules/draggableviews/draggableviews.rules.inc b/sites/all/modules/draggableviews/draggableviews.rules.inc
new file mode 100644
index 000000000..2719f7438
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews.rules.inc
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Rules hooks implementation.
+ */
+
+/**
+ * Implements hook_rules_event_info().
+ */
+function draggableviews_rules_event_info() {
+  $events = array();
+
+  $events['draggableviews_rules_event_sorted'] = array(
+    'label' => t('A view has been sorted'),
+    'group' => t('DraggableViews'),
+    'variables' => array(
+      'view_name' => array(
+        'type' => 'text',
+        'label' => t('view name'),
+      ),
+      'display_name' => array(
+        'type' => 'text',
+        'label' => t('view current display name'),
+      ),
+    ),
+  );
+
+  return $events;
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.info b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.info
new file mode 100644
index 000000000..131f0eccb
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.info
@@ -0,0 +1,13 @@
+name = Draggableviews Book
+description = Reorder books
+dependencies[] = draggableviews
+package = Views
+core = 7.x
+
+files[] = draggableviews_book_views_handler_argument.inc
+; Information added by drupal.org packaging script on 2012-10-01
+version = "7.x-2.0+26-dev"
+core = "7.x"
+project = "draggableviews"
+datestamp = "1349093683"
+
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.install b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.install
new file mode 100644
index 000000000..60fdf880c
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.install
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * Implements hook_install().
+ *
+ * Set the weight more than views.
+ */
+function draggableviews_book_install() {
+  db_query("UPDATE {system} SET weight = 11 WHERE name = 'draggableviews_book'");
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.module b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.module
new file mode 100644
index 000000000..1895a11be
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.module
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * Implements hook_views_api().
+ */
+function draggableviews_book_views_api() {
+  return array(
+    'api' => 3,
+    'path' => drupal_get_path('module', 'draggableviews_book'),
+  );
+}
+
+/**
+ * Implements hook_ctools_plugin_directory().
+ */
+function draggableviews_book_ctools_plugin_directory($module, $plugin) {
+  if (($module == 'draggableviews') && ($plugin == 'handler' || $plugin == 'hierarchy_handler')) {
+    return 'handlers';
+  }
+}
+
+/**
+ * Implements hook_menu_alter().
+ *
+ * Set custom access callback to "Order Outline" view.
+ */
+function draggableviews_book_menu_alter(&$items) {
+  $items['node/%/book']['access callback'] = '_draggableviews_book_access';
+  $items['node/%/book']['access arguments'] = array(1);
+}
+
+/**
+ * Check whether item has children.
+ */
+function _draggableviews_book_access($nid) {
+  return db_query('SELECT has_children FROM {menu_links} WHERE module = :module AND link_path = :link_path', array(':module' => 'book', ':link_path' => 'node/' . $nid))->fetchField();
+}
+
+/**
+ * Implements hook_views_post_execute().
+ *
+ * We manually sort results array according to the weights of depth levels.
+ */
+function draggableviews_book_views_post_execute($view) {
+  if (!isset($view->result[0]->draggableviews_book_mlid)) {
+    return;
+  }
+
+  // First prepare array of mlid keyed items.
+  $keyed_result = array();
+  foreach ($view->result as $result_item) {
+    $result_item->weight = array();
+    $keyed_result[$result_item->draggableviews_book_mlid] = $result_item;
+  }
+
+  // Set the weights arrays for every item. This collects weights of all parents
+  // plus its own weght. Weights are saved according to depth levels.
+  foreach ($keyed_result as &$item) {
+    _draggableviews_book_result_set_weight($item, $keyed_result);
+  }
+
+  // Sort items with custom sort callback.
+  usort($keyed_result, '_draggableviews_book_uasort');
+
+  $view->result = $keyed_result;
+}
+
+/**
+ * Set the weight array of item.
+ */
+function _draggableviews_book_result_set_weight(&$item, $result) {
+  // If weight is already calculated we simply return it.
+  if (!empty($item->weight)) {
+    return $item->weight;
+  }
+
+  // Load weights array of parent (if parent item is available).
+  $parent_weight = array();
+  if (isset($result[$item->draggableviews_book_plid])) {
+    $parent_weight = _draggableviews_book_result_set_weight($result[$item->draggableviews_book_plid], $result);
+  }
+
+  // Set the weight as sum of parents weights and
+  // its own weight according to depth.
+  $item->weight = $parent_weight + array($item->draggableviews_book_depth => $item->draggableviews_book_weight);
+
+  return $item->weight;
+}
+
+/**
+ * Custom sort callback based on weights arrays.
+ */
+function _draggableviews_book_uasort($item1, $item2) {
+  for ($i = 0; $i < 10; $i++) {
+    // Item 1 is less than item 2.
+    if (isset($item1->weight[$i]) && !isset($item2->weight[$i])) {
+      return 1;
+    }
+
+    // Item 2 is less than item 1.
+    if (!isset($item1->weight[$i]) && isset($item2->weight[$i])) {
+      return -1;
+    }
+
+    // If weights on the same depth level are not the same compare them.
+    if (isset($item1->weight[$i]) && isset($item2->weight[$i]) && $item1->weight[$i] != $item2->weight[$i]) {
+      return ($item1->weight[$i] < $item2->weight[$i]) ? -1 : 1;
+    }
+  }
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views.inc b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views.inc
new file mode 100644
index 000000000..2fed2c55f
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views.inc
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Provide special views data and handlers for draggableviews_book module
+ */
+
+/**
+ * Implements hook_views_data().
+ */
+function draggableviews_book_views_data() {
+  // Book hierarchy and weight data are now in {menu_links}.
+  $data['draggableviews_book_structure']['table']['group'] = t('Book');
+  $data['draggableviews_book_structure']['table']['join'] = array(
+    'node' => array(
+      'table' => 'menu_links',
+      'left_table' => 'book',
+      'left_field' => 'mlid',
+      'field' => 'mlid',
+    ),
+  );
+
+  $data['draggableviews_book_structure']['book'] = array(
+    'title' => t('All sub nodes of this book page.'),
+    'help' => t('All sub nodes of this book page.'),
+    'argument' => array(
+      'handler' => 'views_handler_argument_draggableviews_book',
+    ),
+  );
+
+  return $data;
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views_default.inc b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views_default.inc
new file mode 100644
index 000000000..6c394d3be
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book.views_default.inc
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * Implements hook_views_default_views().
+ */
+function draggableviews_book_views_default_views() {
+  $view = new view();
+  $view->name = 'book';
+  $view->description = '';
+  $view->tag = 'default';
+  $view->base_table = 'node';
+  $view->human_name = 'Book';
+  $view->core = 7;
+  $view->api_version = '3.0';
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+  /* Display: Master */
+  $handler = $view->new_display('default', 'Master', 'default');
+  $handler->display->display_options['title'] = 'Reorder Book';
+  $handler->display->display_options['access']['type'] = 'perm';
+  $handler->display->display_options['cache']['type'] = 'none';
+  $handler->display->display_options['query']['type'] = 'views_query';
+  $handler->display->display_options['exposed_form']['type'] = 'basic';
+  $handler->display->display_options['pager']['type'] = 'none';
+  $handler->display->display_options['pager']['options']['offset'] = '0';
+  $handler->display->display_options['style_plugin'] = 'table';
+  /* Field: Content: Title */
+  $handler->display->display_options['fields']['title']['id'] = 'title';
+  $handler->display->display_options['fields']['title']['table'] = 'node';
+  $handler->display->display_options['fields']['title']['field'] = 'title';
+  $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
+  $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
+  /* Field: Draggableviews: Content */
+  $handler->display->display_options['fields']['draggableviews']['id'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['table'] = 'node';
+  $handler->display->display_options['fields']['draggableviews']['field'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['element_default_classes'] = FALSE;
+  $handler->display->display_options['fields']['draggableviews']['hide_alter_empty'] = FALSE;
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['handler'] = 'draggableviews_handler_book';
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['hierarchy_handler'] = 'draggableviews_hierarchy_handler_book';
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['ajax'] = 0;
+  /* Contextual filter: Book: All sub nodes of this book page. */
+  $handler->display->display_options['arguments']['book']['id'] = 'book';
+  $handler->display->display_options['arguments']['book']['table'] = 'draggableviews_book_structure';
+  $handler->display->display_options['arguments']['book']['field'] = 'book';
+  $handler->display->display_options['arguments']['book']['default_action'] = 'empty';
+  $handler->display->display_options['arguments']['book']['default_argument_type'] = 'fixed';
+  $handler->display->display_options['arguments']['book']['summary']['number_of_records'] = '0';
+  $handler->display->display_options['arguments']['book']['summary']['format'] = 'default_summary';
+  $handler->display->display_options['arguments']['book']['summary_options']['items_per_page'] = '25';
+  /* Filter criterion: Content: Published */
+  $handler->display->display_options['filters']['status']['id'] = 'status';
+  $handler->display->display_options['filters']['status']['table'] = 'node';
+  $handler->display->display_options['filters']['status']['field'] = 'status';
+  $handler->display->display_options['filters']['status']['value'] = 1;
+  $handler->display->display_options['filters']['status']['group'] = 1;
+  $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
+
+  /* Display: Page */
+  $handler = $view->new_display('page', 'Page', 'page');
+  $handler->display->display_options['path'] = 'node/%/book';
+  $handler->display->display_options['menu']['type'] = 'tab';
+  $handler->display->display_options['menu']['title'] = 'Order Outline';
+  $handler->display->display_options['menu']['weight'] = '5';
+  $handler->display->display_options['menu']['context'] = 0;
+  $translatables['book'] = array(
+    t('Master'),
+    t('Reorder Book'),
+    t('more'),
+    t('Apply'),
+    t('Reset'),
+    t('Sort by'),
+    t('Asc'),
+    t('Desc'),
+    t('Title'),
+    t('Content'),
+    t('All'),
+    t('Page'),
+  );
+
+  $views[$view->name] = $view;
+
+  return $views;
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book_views_handler_argument.inc b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book_views_handler_argument.inc
new file mode 100644
index 000000000..737abf0bc
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/draggableviews_book_views_handler_argument.inc
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * Argument that refers to a certain book page.
+ */
+class views_handler_argument_draggableviews_book extends views_handler_argument {
+  /**
+   * Add condition to select only part of the tree that is under argument's id.
+   */
+  function query() {
+    $this->ensure_my_table();
+    $mlid = db_query("SELECT mlid FROM {book} WHERE nid = :nid", array(':nid' => $this->argument))->fetchField();
+    // Do not show argument menu item.
+    $this->query->add_where(0, $this->table . '.mlid', $mlid, '<>');
+
+    // Select all items that have argument in one of parents.
+    $group = $this->query->set_where_group('OR');
+    for ($i = 1; $i < 10; $i++) {
+      $this->query->add_where($group, $this->table . '.p' . $i, $mlid);
+    }
+
+    // We sort items in hook_views_post_execute().
+    $tbl = $this->table;
+
+    // Add weight, depth and parent fields.
+    $this->query->add_field($tbl, 'weight', 'draggableviews_book_weight');
+    $this->query->add_field($tbl, 'depth', 'draggableviews_book_depth');
+    $this->query->add_field($tbl, 'plid', 'draggableviews_book_plid');
+    $this->query->add_field($tbl, 'mlid', 'draggableviews_book_mlid');
+  }
+}
diff --git a/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_handler_book.inc b/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_handler_book.inc
new file mode 100644
index 000000000..9b4fd40d9
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_handler_book.inc
@@ -0,0 +1,47 @@
+<?php
+
+$plugin = array(
+  'label' => 'Book',
+  'handler' => array(
+    'class' => 'draggableviews_handler_book',
+  ),
+);
+
+class draggableviews_handler_book extends draggableviews_handler {
+
+  /**
+   * Retrieve the weight.
+   */
+  function get($field, $index) {
+    $row = $field->view->result[$index];
+    return isset($row->draggableviews_book_weight) ? $row->draggableviews_book_weight : 0;
+  }
+
+  /**
+   *  Set both parent and weight values.
+   */
+  function set($form_state) {
+    $fv = $form_state['values'];
+
+    foreach ($fv['draggableviews'] as $item) {
+      $node = node_load($item['id']);
+
+      $keys = array('menu_name', 'mlid', 'router_path', 'has_children', 'options', 'module',
+//          'original_bid', 'parent_depth_limit',
+          'bid');
+      $book = array();
+      foreach ($keys as $key) {
+        $book[$key] = $node->book[$key];
+      }
+
+      $book['weight'] = $item['weight'];
+      $book['plid'] = db_query('SELECT mlid FROM {menu_links} WHERE link_path = :link_path AND menu_name = :menu_name', array(':link_path' => 'node/' . $item['parent'], ':menu_name' => $book['menu_name']))->fetchField();
+
+      $node->book = $book;
+      _book_update_outline($node);
+
+      drupal_static_reset('book_get_books');
+    }
+  }
+}
+
diff --git a/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_hierarchy_handler_book.inc b/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_hierarchy_handler_book.inc
new file mode 100644
index 000000000..00e53abee
--- /dev/null
+++ b/sites/all/modules/draggableviews/draggableviews_book/handlers/draggableviews_hierarchy_handler_book.inc
@@ -0,0 +1,38 @@
+<?php
+
+$plugin = array(
+  'label' => 'Book',
+  'handler' => array(
+    'class' => 'draggableviews_hierarchy_handler_book',
+  ),
+);
+
+class draggableviews_hierarchy_handler_book extends draggableviews_hierarchy_handler {
+  public function get($field, $index) {
+    $row = $field->view->result[$index];
+    $parent_mlid = $row->draggableviews_book_plid;
+    
+    $parent_link_path = db_query('SELECT link_path FROM {menu_links} WHERE mlid = :mlid', array(':mlid' => $parent_mlid))->fetchField();
+
+    return !empty($parent_link_path) ? substr($parent_link_path, 5) : 0;
+  }
+
+  public function get_depth($field, $index) {
+    $row = $field->view->result[$index];
+
+    // Cache depth of the top parent so we do not recalculate it.
+    static $parent_depth;
+    if (is_null($parent_depth)) {
+      $parent_mlid = $row->draggableviews_book_plid;
+      $parent_depth = db_query('SELECT depth FROM {menu_links} WHERE mlid = :mlid', array(':mlid' => $parent_mlid))->fetchField() + 1;
+    }
+
+    return isset($row->draggableviews_book_depth) ? $row->draggableviews_book_depth - $parent_depth : 0;
+  }
+
+  // Don't need to set value here as it is done in "weight" handler
+  // draggableviews_handler in order to avoid doing multiple identical queries
+  // to draggableviews_structure table.
+  function set($form_state) {}
+}
+
diff --git a/sites/all/modules/draggableviews/handlers/draggableviews_handler.inc b/sites/all/modules/draggableviews/handlers/draggableviews_handler.inc
new file mode 100644
index 000000000..1fbef1636
--- /dev/null
+++ b/sites/all/modules/draggableviews/handlers/draggableviews_handler.inc
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Base plugin implementation.
+ */
+
+/**
+ * Parent class for all sort handlers.
+ */
+class draggableviews_handler {
+
+  /**
+   * Get the weight value.
+   *
+   * @param object $field
+   *   Draggableviews field handler. View is $field->view,
+   *   to get a row $field->view->result[$index].
+   * @param int $index
+   *   Index of the row.
+   *
+   * @return int
+   *   Weight value.
+   */
+  public function get($field, $index) {}
+
+  /**
+   * Save weight value.
+   *
+   * @param $form_state
+   *   Attay of form state of the form.
+   *   View object $form_state['values']['view'].
+   */
+  public function set($form_state) {}
+
+  /**
+   * Form with settings of the handler.
+   *
+   * @param object $field
+   *  Draggableviews field handler.
+   *
+   * @return array
+   *  Form array.
+   */
+  public function options_form($field) {}
+
+  /**
+   * Settings form default values.
+   *
+   * @return array
+   *   Array with default values.
+   */
+  public function option_definition() {}
+}
\ No newline at end of file
diff --git a/sites/all/modules/draggableviews/handlers/draggableviews_handler_fieldapi.inc b/sites/all/modules/draggableviews/handlers/draggableviews_handler_fieldapi.inc
new file mode 100644
index 000000000..814d50947
--- /dev/null
+++ b/sites/all/modules/draggableviews/handlers/draggableviews_handler_fieldapi.inc
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * @file
+ * Field API handler plugin.
+ */
+
+$plugin = array(
+  'label' => 'FieldAPI',
+  'handler' => array(
+    'class' => 'draggableviews_handler_fieldapi',
+  ),
+);
+
+class draggableviews_handler_fieldapi extends draggableviews_handler {
+  /**
+  * Set default value of field option.
+  */
+  public function option_definition() {
+    return array('field' => '');
+  }
+
+  /**
+  * Add field options for handler.
+  */
+  function options_form($field) {
+    $form = array();
+    $options = array('' => t('- Select -'));
+
+    // Check all the sortings added to a view. Hope there is
+    // better way to determine them. Need to research.
+    $sorts = $field->view->display_handler->display->display_options['sorts'];
+    // If no sorts avaialble for current display, use sorts from default display.
+    if (empty($sorts)) {
+      $sorts = $field->view->display['default']->display_options['sorts'];
+    }
+    foreach ($sorts as $sort_option) {
+      $field_name = $sort_option['field'];
+      // Field should be like "field_name_value".
+      if (strpos($field_name, 'field_') === FALSE || strpos($field_name, '_value') === FALSE) {
+        continue;
+      }
+
+      // Remove "_value" from field name and try to load the field.
+      $field_name = drupal_substr($field_name, 0, drupal_strlen($field_name) - 6);
+      if ($field_info = field_info_field($field_name)) {
+        if ($field_info['type'] == 'number_integer') {
+          $views_field_data = field_views_field_default_views_data($field_info);
+          $options[$sort_option['table'] . ':' . $sort_option['field']] = filter_xss($views_field_data[$sort_option['table']][$sort_option['field']]['title']);
+        }
+      }
+    }
+
+    // If options are emtpy, show warning message.
+    if (count($options) == 1) {
+      $form['field_warning'] = array(
+        '#markup' => '<div class="messages warning">' . t('Add weight integer field to sorts so it can be selected.') . '</div>',
+      );
+    }
+
+    $form['field'] = array(
+      '#type' => 'select',
+      '#title' => t('Field'),
+      '#options' => $options,
+      '#default_value' => $field->options['draggableviews']['draggableviews_handler_fieldapi']['field'],
+      '#description' => t('Please select field that contains weight. It should be integer type and already added to sorts of the view.'),
+    );
+    return $form;
+  }
+
+  function get($field, $index) {
+    // Get the name of selected field.
+    $field_option = $field->options['draggableviews']['draggableviews_handler_fieldapi']['field'];
+    list($field_table, $field_name) = explode(':', $field_option);
+    // Current row.
+    $row = $field->view->result[$index];
+    // Check whether key has table name and field name in it.
+    foreach ($row as $key => $value) {
+      if (strpos($key, $field_table) !== FALSE && strpos($key, $field_name) !== FALSE) {
+        return $value;
+      }
+    }
+  }
+
+  function set($form_state) {
+    $fv = $form_state['values'];
+    $view = $form_state['build_info']['args'][0];
+    $view_name = $view->name;
+    $view_display = $view->current_display;
+    // View arguments.
+    $arguments = $view->args;
+    if (isset($view->exposed_raw_input)) {
+      $arguments += $view->exposed_raw_input;
+      ksort($arguments);
+      // Redirect view to the same page with exposed filters set.
+      $form_state['redirect'] = array(current_path(), array('query' => $view->exposed_raw_input));
+    }
+
+    $base_table = $view->base_table;
+    $entity_info_all = entity_get_info();
+    $entity_type = '';
+    foreach ($entity_info_all as $entity_name_key => $entity_info) {
+      if ($entity_info['base table'] == $view->base_table) {
+        $entity_type = $entity_name_key;
+        break;
+      }
+    }
+
+    $options_field = $view->field['draggableviews']->options['draggableviews']['draggableviews_handler_fieldapi']['field'];
+    list($field_tabe, $field_column) = explode(':', $options_field);
+    // Remove '_value' from column name to get field name.
+    $field_name = drupal_substr($field_column, 0, drupal_strlen($field_column) - 6);
+
+    // Give other modules a chance to alter saved arguments.
+    drupal_alter('draggableviews_handler_fieldapi_arguments', $fv['draggableviews'], $view);
+
+    // Save the values of the field.
+    foreach ($fv['draggableviews'] as $item) {
+      if (isset($item['id']) && isset($item['weight'])) {
+        $entity = reset(entity_load($entity_type, array($item['id'])));
+        $entity->{$field_name}[LANGUAGE_NONE][0]['value'] = $item['weight'];
+        entity_save($entity_type, $entity);
+      }
+    }
+  }
+}
diff --git a/sites/all/modules/draggableviews/handlers/draggableviews_handler_native.inc b/sites/all/modules/draggableviews/handlers/draggableviews_handler_native.inc
new file mode 100644
index 000000000..b39853091
--- /dev/null
+++ b/sites/all/modules/draggableviews/handlers/draggableviews_handler_native.inc
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Native handler plugin.
+ */
+
+$plugin = array(
+  'label' => 'Native',
+  'handler' => array(
+    'class' => 'draggableviews_handler_native',
+  ),
+);
+
+class draggableviews_handler_native extends draggableviews_handler {
+  public function get($field, $index) {
+    $row = $field->view->result[$index];
+    return (isset($row->draggableviews_structure_weight)) ? $row->draggableviews_structure_weight : 0;
+  }
+
+  function set($form_state) {
+    $fv = $form_state['values'];
+    $view = $form_state['build_info']['args'][0];
+    $view_name = $view->name;
+    $view_display = $view->current_display;
+    // View arguments.
+    $arguments = $view->args;
+    if (isset($view->exposed_raw_input)) {
+      $arguments += $view->exposed_raw_input;
+      ksort($arguments);
+      // Redirect view to the same page with exposed filters set.
+      $form_state['redirect'] = array(current_path(), array('query' => $view->exposed_raw_input));
+    }
+
+    // Give other modules a chance to alter saved arguments.
+    drupal_alter('draggableviews_handler_native_arguments', $arguments, $view, $fv['draggableviews']);
+
+    $args_string = json_encode($arguments);
+
+    // Save records to our custom table.
+    $weight = 0;
+    foreach ($fv['draggableviews'] as $item) {
+      // Make sure id is available.
+      if (!isset($item['id'])) {
+        continue;
+      }
+      // Delete previous order record.
+      db_delete('draggableviews_structure')
+        ->condition('view_name', $view_name)
+        ->condition('view_display', $view_display)
+        ->condition('args', $args_string)
+        ->condition('entity_id', $item['id'])
+        ->execute();
+
+      // Create new order record.
+      $record = array(
+        'view_name' => $view_name,
+        'view_display' => $view_display,
+        'args' => $args_string,
+        'entity_id' => $item['id'],
+        'weight' => $weight,
+      );
+      // If parent element exists, save it.
+      if (isset($item['parent'])) {
+        $record['parent'] = $item['parent'];
+      }
+      drupal_write_record('draggableviews_structure', $record);
+      $weight++;
+    }
+  }
+}
diff --git a/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler.inc b/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler.inc
new file mode 100644
index 000000000..915bdb583
--- /dev/null
+++ b/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler.inc
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Base plugin implementation.
+ */
+
+/**
+ * Parent class for all hierarchy handlers.
+ */
+class draggableviews_hierarchy_handler {
+
+  /**
+   * Get the parent value.
+   *
+   * @param object $field
+   *   Draggableviews field handler. View is $field->view,
+   *   to get a row $field->view->result[$index].
+   * @param int $index
+   *   Index of the row.
+   *
+   * @return int
+   *   Weight value.
+   */
+  public function get($field, $index) {}
+
+  /**
+   * Save parent value.
+   *
+   * @param $form_state
+   *   Attay of form state of the form.
+   *   View object $form_state['values']['view'].
+   */
+  public function set($form_state) {}
+
+  /**
+   * Form with settings of the handler.
+   *
+   * @param object $field
+   *  Draggableviews field handler.
+   *
+   * @return array
+   *  Form array.
+   */
+  public function options_form($field) {}
+
+  /**
+   * Settings form default values.
+   *
+   * @return array
+   *   Array with default values.
+   */
+  public function option_definition() {}
+
+  /**
+   * Get "results" array index of and item with specific base field id.
+   *
+   * @param object $view
+   *   Views object
+   * @param type $id
+   *   Base field id.
+   *
+   * @return int
+   */
+  public function get_index($view, $id) {
+    foreach ($view->result as $key => $item) {
+      if ($item->{$view->base_field} == $id) {
+        return $key;
+      }
+    }
+  }
+}
diff --git a/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler_native.inc b/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler_native.inc
new file mode 100644
index 000000000..c3a4eccba
--- /dev/null
+++ b/sites/all/modules/draggableviews/handlers/draggableviews_hierarchy_handler_native.inc
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Native handler plugin.
+ */
+
+$plugin = array(
+  'label' => 'Native',
+  'handler' => array(
+    'class' => 'draggableviews_hierarchy_handler_native',
+  ),
+);
+
+class draggableviews_hierarchy_handler_native extends draggableviews_hierarchy_handler {
+  public function get($field, $index) {
+    $row = $field->view->result[$index];
+    return (isset($row->draggableviews_structure_parent)) ? $row->draggableviews_structure_parent : 0;
+  }
+
+  public function get_depth($field, $index) {
+    $row = $field->view->result[$index];
+    // If parent is available, set parent's depth +1.
+    return (!empty($row->draggableviews_structure_parent)) ? $this->get_depth($field, $this->get_index($field->view, $row->draggableviews_structure_parent)) + 1 : 0;
+  }
+
+  // Don't need to set value here as it is done in "weight" handler
+  // draggableviews_handler in order to avoid doing multiple identical queries
+  // to draggableviews_structure table.
+  function set($form_state) {}
+}
diff --git a/sites/all/modules/draggableviews/js/draggableviews_list.js b/sites/all/modules/draggableviews/js/draggableviews_list.js
new file mode 100644
index 000000000..822994860
--- /dev/null
+++ b/sites/all/modules/draggableviews/js/draggableviews_list.js
@@ -0,0 +1,45 @@
+/**
+ * @file
+ * Adds draggable functionality to the html list display of the view.
+ */
+
+(function ($) {
+ Drupal.behaviors.draggableViews = {
+  attach: function (context, settings) {
+    $('.views-form .' + Drupal.settings.draggableviews_row_class + ':not(.draggableviews-processed)', context)
+    // Add class for theming.
+    .addClass('draggableviews-processed')
+    // Add sortable effect.
+    .sortable({
+      update: function(event, ui) {
+        $( ".draggableviews-weight" ).each(function (i, Val) {
+          $(this).val(i);
+        });
+        if (!$(this).hasClass('draggableviews-changed')) {
+          // If view is not ajaxified.
+          if (!Drupal.settings.draggableviews_ajax) {
+            $('<div class="draggableviews-changed-warning messages warning">' + Drupal.t('Changes made in this list will not be saved until the form is submitted.') + '</div>')
+              .insertBefore($(this).parents('form div.item-list')).hide().fadeIn('slow');
+            $(this).addClass('draggableviews-changed');
+          }
+          else {
+            // If view ajaxified.
+            $('<div class="draggableviews-changed-notice messages warning">' + Drupal.t('Order of this view has been changed.') + '</div>')
+              .insertBefore($(this).parents('form div.item-list')).hide().fadeIn('slow').delay(3000).fadeOut('slow');
+            $(this).addClass('draggableviews-changed');
+          }
+        }
+        // If Ajax enabled, we should submit the form.
+        if (Drupal.settings.draggableviews_ajax) {
+          $(this).parent().parent().find('#edit-submit').trigger('mousedown');
+        }
+      },
+      containment: 'parent',
+      cursor: 'move'
+    });
+    if (Drupal.settings.draggableviews_ajax) {
+      $('.views-form .' + Drupal.settings.draggableviews_row_class).parent().parent().find('#edit-submit').hide();
+    }
+  }
+ }
+})(jQuery);
diff --git a/sites/all/modules/draggableviews/js/draggableviews_table.js b/sites/all/modules/draggableviews/js/draggableviews_table.js
new file mode 100644
index 000000000..2ad0de6ea
--- /dev/null
+++ b/sites/all/modules/draggableviews/js/draggableviews_table.js
@@ -0,0 +1,37 @@
+/**
+ * @file
+ * Adds draggable functionality to the table display of the view.
+ */
+
+(function ($) {
+  Drupal.behaviors.draggableviewsAutosave = {
+    attach: function(){
+      if (typeof Drupal.tableDrag == 'undefined') {
+        return;
+      }
+      for (var prop in Drupal.tableDrag){
+        if (prop.substring(0, 14) == 'draggableviews'){
+          var table = Drupal.tableDrag[prop];
+          table.onDrop = function() {
+            // Hide change messages that are not relevant when saving form
+            // through AJAX.
+            $('.tabledrag-changed').hide();
+            $('.tabledrag-changed-warning').hide();
+            $table = $(this.table);
+            // Submit form with AJAX.
+            $table.parent().find('#edit-actions input').triggerHandler('mousedown');
+            // The previously dragged row is left with class styling the row
+            // yellow style, indicating unsaved state. To increate UX we remove
+            // this class with some delay to indicate that progress was made in
+            // the background.
+            $('.drag-previous').removeClass('drag-previous');
+            $('<div class="draggableviews-changed-notice messages warning">' + Drupal.t('Order of this view has been changed.') + '</div>')
+              .insertBefore($table).hide().fadeIn('slow').delay(3000).fadeOut('slow');
+          }
+          // Hide Save button.
+          $('#' + prop).parent().find('#edit-actions input').hide();
+        }
+      }
+    }
+  }
+})(jQuery);
diff --git a/sites/all/modules/draggableviews/test/draggableviews.test b/sites/all/modules/draggableviews/test/draggableviews.test
new file mode 100644
index 000000000..1ca36ea7f
--- /dev/null
+++ b/sites/all/modules/draggableviews/test/draggableviews.test
@@ -0,0 +1,425 @@
+<?php
+
+/**
+ * @file
+ * Test cases file.
+ */
+
+/**
+ * Class for testing Draggableviews module.
+ */
+class DraggableviewsTestCase extends DrupalWebTestCase {
+
+  function setUp() {
+    parent::setUp(array('ctools', 'views', 'views_ui', 'entity', 'draggableviews', 'draggableviews_test'));
+  }
+
+  /**
+   * Fork from drupalPost().
+   *
+   * When action of the form determined we don't care about exposed filter
+   * arguments passed to the view. In this fork we use
+   * $this->getUrl() unconditionally.
+   */
+  protected function drupalDraggableviewsPost($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL, $extra_post = NULL) {
+    $submit_matches = FALSE;
+    $ajax = is_array($submit);
+    if (isset($path)) {
+      $this->drupalGet($path, $options);
+    }
+    if ($this->parse()) {
+      $edit_save = $edit;
+      // Let's iterate over all the forms.
+      $xpath = "//form";
+      if (!empty($form_html_id)) {
+        $xpath .= "[@id='" . $form_html_id . "']";
+      }
+      $forms = $this->xpath($xpath);
+      foreach ($forms as $form) {
+        // We try to set the fields of this form as specified in $edit.
+        $edit = $edit_save;
+        $post = array();
+        $upload = array();
+        $submit_matches = $this->handleForm($post, $edit, $upload, $ajax ? NULL : $submit, $form);
+//        $action = isset($form['action']) ? $this->getAbsoluteUrl((string) $form['action']) : $this->getUrl();
+        $action = $this->getUrl();
+        if ($ajax) {
+          $action = $this->getAbsoluteUrl(!empty($submit['path']) ? $submit['path'] : 'system/ajax');
+          // Ajax callbacks verify the triggering element if necessary, so while
+          // we may eventually want extra code that verifies it in the
+          // handleForm() function, it's not currently a requirement.
+          $submit_matches = TRUE;
+        }
+
+        // We post only if we managed to handle every field in edit and the
+        // submit button matches.
+        if (!$edit && ($submit_matches || !isset($submit))) {
+          $post_array = $post;
+          if ($upload) {
+            // TODO: cURL handles file uploads for us, but the implementation
+            // is broken. This is a less than elegant workaround. Alternatives
+            // are being explored at #253506.
+            foreach ($upload as $key => $file) {
+              $file = drupal_realpath($file);
+              if ($file && is_file($file)) {
+                $post[$key] = '@' . $file;
+              }
+            }
+          }
+          else {
+            foreach ($post as $key => $value) {
+              // Encode according to application/x-www-form-urlencoded
+              // Both names and values needs to be urlencoded, according to
+              // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
+              $post[$key] = urlencode($key) . '=' . urlencode($value);
+            }
+            $post = implode('&', $post) . $extra_post;
+          }
+          $out = $this->curlExec(array(CURLOPT_URL => $action, CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $post, CURLOPT_HTTPHEADER => $headers));
+          // Ensure that any changes to variables in the other thread are picked up.
+          $this->refreshVariables();
+
+          // Replace original page output with new output from redirected page(s).
+          if ($new = $this->checkForMetaRefresh()) {
+            $out = $new;
+          }
+          $this->verbose('POST request to: ' . $path .
+                         '<hr />Ending URL: ' . $this->getUrl() .
+                         '<hr />Fields: ' . highlight_string('<?php ' . var_export($post_array, TRUE), TRUE) .
+                         '<hr />' . $out);
+          return $out;
+        }
+      }
+      // We have not found a form which contained all fields of $edit.
+      foreach ($edit as $name => $value) {
+        $this->fail(t('Failed to set field @name to @value', array('@name' => $name, '@value' => $value)));
+      }
+      if (!$ajax && isset($submit)) {
+        $this->assertTrue($submit_matches, t('Found the @submit button', array('@submit' => $submit)));
+      }
+      $this->fail(t('Found the requested form fields at @path', array('@path' => $path)));
+    }
+  }
+}
+
+/**
+ * Testing Native Handler.
+ */
+class DraggableviewsNativeHandlerTestCase extends DraggableviewsTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Native handler',
+      'description' => 'Test the native handler.',
+      'group' => 'Draggableviews',
+    );
+  }
+
+  function testSort() {
+    $permissions = array('access content');
+    $rid = $this->drupalCreateRole($permissions);
+
+    // Create five test users.
+    $accounts = array();
+    for ($i = 0; $i < 5; $i++) {
+      $edit = array();
+      $edit['name']   = $this->randomName();
+      // First three users should be prefixed 'test_'.
+      if ($i < 3) {
+        $edit['name'] = 'test_' . $edit['name'];
+      }
+      $edit['mail']   = $edit['name'] . '@example.com';
+      $edit['roles']  = array($rid => $rid);
+      $edit['pass']   = user_password();
+      $edit['status'] = 1;
+
+      $account = user_save(drupal_anonymous_user(), $edit);
+      $account->pass_raw = $edit['pass'];
+
+      $accounts[$account->uid] = $account;
+    }
+
+    $account = $this->drupalCreateUser(array('access content', 'access draggableviews', 'access user profiles', 'access contextual links'));
+    $this->drupalLogin($account);
+
+    // Now lets sort and save a view.
+    $edit = array(
+      'draggableviews[0][weight]' => 0,
+      'draggableviews[0][id]' => 1,
+      'draggableviews[1][weight]' => 1,
+      'draggableviews[1][id]' => 2,
+      'draggableviews[2][weight]' => 2,
+      'draggableviews[2][id]' => 3,
+      'draggableviews[3][weight]' => 3,
+      'draggableviews[3][id]' => 4,
+      'draggableviews[4][weight]' => 4,
+      'draggableviews[4][id]' => 5,
+      'draggableviews[5][weight]' => 5,
+      'draggableviews[5][id]' => 6,
+      'draggableviews[6][weight]' => 6,
+      'draggableviews[6][id]' => 7,
+    );
+    $this->drupalPost('users-set', $edit, t('Save'));
+
+    // Assert that first user is on first place, and second is on second.
+    $first_row = $this->xpath('//tr[@class="odd views-row-first draggable"]/td/a[@class="username"]');
+    $second_row = $this->xpath('//tr[@class="even draggable"]/td/a[@class="username"]');
+    $this->assertEqual((string) $first_row[0], 'placeholder-for...', t('First row user uid 1.'));
+    $this->assertEqual((string) $second_row[0], $accounts[2]->name, t('Second row user uid 2.'));
+
+    // Now save a different sort (first and second rows changed places).
+    $edit = array(
+      'draggableviews[0][weight]' => 0,
+      'draggableviews[0][id]' => 2,
+      'draggableviews[1][weight]' => 1,
+      'draggableviews[1][id]' => 1,
+      'draggableviews[2][weight]' => 2,
+      'draggableviews[2][id]' => 3,
+      'draggableviews[3][weight]' => 3,
+      'draggableviews[3][id]' => 4,
+      'draggableviews[4][weight]' => 4,
+      'draggableviews[4][id]' => 5,
+      'draggableviews[5][weight]' => 5,
+      'draggableviews[5][id]' => 6,
+      'draggableviews[6][weight]' => 6,
+      'draggableviews[6][id]' => 7,
+    );
+    $this->drupalPost('users-set', $edit, t('Save'));
+    // Assert that first user is on second place, and second user is on first.
+    $first_row = $this->xpath('//tr[@class="odd views-row-first draggable"]/td/a[@class="username"]');
+    $second_row = $this->xpath('//tr[@class="even draggable"]/td/a[@class="username"]');
+    $this->assertEqual((string) $first_row[0], $accounts[2]->name, t('First row user uid 2.'));
+    $this->assertEqual((string) $second_row[0], 'placeholder-for...', t('Second row user uid 1.'));
+
+    // Apply exposed filter and set weights.
+    $edit = array(
+      'draggableviews[0][weight]' => 0,
+      'draggableviews[0][id]' => 4,
+      'draggableviews[1][weight]' => 1,
+      'draggableviews[1][id]' => 3,
+      'draggableviews[2][weight]' => 2,
+      'draggableviews[2][id]' => 2,
+    );
+    $this->drupalDraggableviewsPost('users-set', $edit, t('Save'), array('query' => array('mail' => 'test')));
+
+    // Now lets check display view page.
+    $this->drupalGet('users-display');
+    $first_row = $this->xpath('//tr[@class="odd views-row-first"]/td/a[@class="username"]');
+    $second_row = $this->xpath('//tr[@class="even"]/td/a[@class="username"]');
+    $this->assertEqual((string) $first_row[0], $accounts[2]->name, t('Display view. First row user uid 2.'));
+    $this->assertEqual((string) $second_row[0], 'placeholder-for...', t('Display view. Second row user uid 1.'));
+
+    // Check display view with applied exposed filter.
+    $this->drupalGet('users-display', array('query' => array('mail' => 'test')));
+    $first_row = $this->xpath('//tr[@class="odd views-row-first"]/td/a[@class="username"]');
+    $second_row = $this->xpath('//tr[@class="even"]/td/a[@class="username"]');
+    $this->assertEqual((string) $first_row[0], $accounts[4]->name, t('Display view. Exposed filter applied. First row user uid 4.'));
+    $this->assertEqual((string) $second_row[0], $accounts[3]->name, t('Display view. Exposed filter applied. Second row user uid 3.'));
+
+    // Check contextual link existense.
+    $contextual_links = $this->xpath('//ul[@class="contextual-links views-contextual-links-page"]/li/a');
+    $href = (string) $contextual_links[0]['href'];
+    $this->assertTrue(strpos($href, 'users-set?destination=users-display') !== FALSE, t('Contextual link exists.'));
+  }
+}
+
+/**
+ * Testing Fielad API Handler.
+ */
+class DraggableviewsFieldAPIHandlerTestCase extends DraggableviewsTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field API handler',
+      'description' => 'Test the Field API handler.',
+      'group' => 'Draggableviews',
+    );
+  }
+
+  public function testSort() {
+    $this->createField();
+
+    $account = $this->drupalCreateUser(array('access content', 'access draggableviews', 'access user profiles', 'access contextual links'));
+    $this->drupalLogin($account);
+
+    // Create five nodes.
+    $nodes = array();
+    for ($i = 0; $i < 5; $i++) {
+      $node = $this->drupalCreateNode(array('type' => 'article',));
+      $nodes[$node->nid] = $node;
+    }
+
+    // Now lets sort and save a view.
+    $edit = array(
+      'draggableviews[0][weight]' => 0,
+      'draggableviews[0][id]' => 1,
+      'draggableviews[1][weight]' => 1,
+      'draggableviews[1][id]' => 2,
+      'draggableviews[2][weight]' => 2,
+      'draggableviews[2][id]' => 3,
+      'draggableviews[3][weight]' => 3,
+      'draggableviews[3][id]' => 4,
+      'draggableviews[4][weight]' => 4,
+      'draggableviews[4][id]' => 5,
+    );
+    $this->drupalPost('nodes-set', $edit, t('Save'));
+    // Assert that first node is on first place, and second is on second.
+    $first_row = $this->xpath('//tr[@class="odd views-row-first draggable"]/td/a');
+    $second_row = $this->xpath('//tr[@class="even draggable"]/td/a');
+    $this->assertEqual((string) $first_row[0], $nodes[1]->title, t('First row node nid 1.'));
+    $this->assertEqual((string) $second_row[0], $nodes[2]->title, t('Second row node nid 2.'));
+
+    // Now save a different sort (first and second rows changed places).
+    $edit = array(
+      'draggableviews[0][weight]' => 0,
+      'draggableviews[0][id]' => 2,
+      'draggableviews[1][weight]' => 1,
+      'draggableviews[1][id]' => 1,
+      'draggableviews[2][weight]' => 2,
+      'draggableviews[2][id]' => 3,
+      'draggableviews[3][weight]' => 3,
+      'draggableviews[3][id]' => 4,
+      'draggableviews[4][weight]' => 4,
+      'draggableviews[4][id]' => 5,
+    );
+    $this->drupalPost('nodes-set', $edit, t('Save'));
+    // Assert that first node is on second place, and second is on first.
+    $first_row = $this->xpath('//tr[@class="odd views-row-first draggable"]/td/a');
+    $second_row = $this->xpath('//tr[@class="even draggable"]/td/a');
+    $this->assertEqual((string) $first_row[0], $nodes[2]->title, t('First row node nid 2.'));
+    $this->assertEqual((string) $second_row[0], $nodes[1]->title, t('Second row node nid 1.'));
+
+    // Check display view order.
+    $this->drupalGet('nodes-display');
+    $first_row = $this->xpath('//tr[@class="odd views-row-first"]/td/a');
+    $second_row = $this->xpath('//tr[@class="even"]/td/a');
+    $this->assertEqual((string) $first_row[0], $nodes[2]->title, t('First row node nid 2.'));
+    $this->assertEqual((string) $second_row[0], $nodes[1]->title, t('Second row node nid 1.'));
+
+    // Check values of nodes.
+    $node1 = node_load(1);
+    $node2 = node_load(2);
+    $this->assertTrue($node1->field_weight[LANGUAGE_NONE][0]['value'] > $node2->field_weight[LANGUAGE_NONE][0]['value'], t('Weight of node 1 is more than weight of node 2.'));
+  }
+
+  // Create a integer field for Article nodes.
+  function createField() {
+    $field = array (
+      'translatable' => '0',
+      'entity_types' =>
+      array (
+      ),
+      'settings' =>
+      array (
+      ),
+      'storage' =>
+      array (
+        'type' => 'field_sql_storage',
+        'settings' =>
+        array (
+        ),
+        'module' => 'field_sql_storage',
+        'active' => '1',
+        'details' =>
+        array (
+          'sql' =>
+          array (
+            'FIELD_LOAD_CURRENT' =>
+            array (
+              'field_data_field_weight' =>
+              array (
+                'value' => 'field_weight_value',
+              ),
+            ),
+            'FIELD_LOAD_REVISION' =>
+            array (
+              'field_revision_field_weight' =>
+              array (
+                'value' => 'field_weight_value',
+              ),
+            ),
+          ),
+        ),
+      ),
+      'foreign keys' =>
+      array (
+      ),
+      'indexes' =>
+      array (
+      ),
+      'id' => '5',
+      'field_name' => 'field_weight',
+      'type' => 'number_integer',
+      'module' => 'number',
+      'active' => '1',
+      'locked' => '0',
+      'cardinality' => '1',
+      'deleted' => '0',
+      'columns' =>
+      array (
+        'value' =>
+        array (
+          'type' => 'int',
+          'not null' => false,
+        ),
+      ),
+      'bundles' =>
+      array (
+        'node' =>
+        array (
+          0 => 'article',
+        ),
+      ),
+    );
+    field_create_field($field);
+
+    $instance = array (
+      'label' => 'Weight',
+      'widget' =>
+      array (
+        'weight' => 0,
+        'type' => 'number',
+        'module' => 'number',
+        'active' => 0,
+        'settings' =>
+        array (
+        ),
+      ),
+      'settings' =>
+      array (
+        'min' => '',
+        'max' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'user_register_form' => false,
+      ),
+      'display' =>
+      array (
+        'default' =>
+        array (
+          'label' => 'above',
+          'type' => 'number_integer',
+          'settings' =>
+          array (
+            'thousand_separator' => ' ',
+            'decimal_separator' => '.',
+            'scale' => 0,
+            'prefix_suffix' => true,
+          ),
+          'module' => 'number',
+          'weight' => 11,
+        ),
+      ),
+      'required' => 0,
+      'description' => '',
+      'default_value' => NULL,
+      'id' => '7',
+      'field_id' => '5',
+      'field_name' => 'field_weight',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+      'deleted' => '0',
+    );
+    field_create_instance($instance);
+  }
+}
diff --git a/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.info b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.info
new file mode 100644
index 000000000..f38e1b0e6
--- /dev/null
+++ b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.info
@@ -0,0 +1,12 @@
+name = Draggableviews Test
+description = Provides views for testing.
+dependencies[] = draggableviews
+package = Views
+core = 7.x
+hidden = TRUE
+; Information added by drupal.org packaging script on 2012-10-01
+version = "7.x-2.0+26-dev"
+core = "7.x"
+project = "draggableviews"
+datestamp = "1349093683"
+
diff --git a/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.module b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.module
new file mode 100644
index 000000000..58229c311
--- /dev/null
+++ b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.module
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * Implements hook_views_api().
+ */
+function draggableviews_test_views_api() {
+  return array(
+    'api' => 3,
+    'path' => drupal_get_path('module', 'draggableviews_test'),
+  );
+}
diff --git a/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.views_default.inc b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.views_default.inc
new file mode 100644
index 000000000..b6e7ad87f
--- /dev/null
+++ b/sites/all/modules/draggableviews/test/draggableviews_test/draggableviews_test.views_default.inc
@@ -0,0 +1,248 @@
+<?php
+
+/**
+ * @file
+ * Views to import for testing.
+ */
+
+/**
+ * Implements hook_views_default_views().
+ */
+function draggableviews_test_views_default_views() {
+  $view = new view;
+  $view->name = 'users';
+  $view->description = '';
+  $view->tag = 'default';
+  $view->base_table = 'users';
+  $view->human_name = 'Users';
+  $view->core = 7;
+  $view->api_version = '3.0';
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+  /* Display: Master */
+  $handler = $view->new_display('default', 'Master', 'default');
+  $handler->display->display_options['title'] = 'Users';
+  $handler->display->display_options['access']['type'] = 'perm';
+  $handler->display->display_options['access']['perm'] = 'access user profiles';
+  $handler->display->display_options['cache']['type'] = 'none';
+  $handler->display->display_options['query']['type'] = 'views_query';
+  $handler->display->display_options['query']['options']['query_comment'] = FALSE;
+  $handler->display->display_options['query']['options']['query_tags'] = FALSE;
+  $handler->display->display_options['exposed_form']['type'] = 'basic';
+  $handler->display->display_options['pager']['type'] = 'full';
+  $handler->display->display_options['pager']['options']['items_per_page'] = '10';
+  $handler->display->display_options['style_plugin'] = 'table';
+  /* Field: User: Name */
+  $handler->display->display_options['fields']['name']['id'] = 'name';
+  $handler->display->display_options['fields']['name']['table'] = 'users';
+  $handler->display->display_options['fields']['name']['field'] = 'name';
+  $handler->display->display_options['fields']['name']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['word_boundary'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['ellipsis'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['name']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['name']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['name']['link_to_user'] = 1;
+  $handler->display->display_options['fields']['name']['overwrite_anonymous'] = 0;
+  /* Field: Draggableviews: User */
+  $handler->display->display_options['fields']['draggableviews']['id'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['table'] = 'users';
+  $handler->display->display_options['fields']['draggableviews']['field'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['element_label_colon'] = 1;
+  $handler->display->display_options['fields']['draggableviews']['element_default_classes'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['hide_alter_empty'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['ajax'] = 0;
+  /* Field: User: E-mail */
+  $handler->display->display_options['fields']['mail']['id'] = 'mail';
+  $handler->display->display_options['fields']['mail']['table'] = 'users';
+  $handler->display->display_options['fields']['mail']['field'] = 'mail';
+  $handler->display->display_options['fields']['mail']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['external'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['replace_spaces'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['trim_whitespace'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['nl2br'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['word_boundary'] = 1;
+  $handler->display->display_options['fields']['mail']['alter']['ellipsis'] = 1;
+  $handler->display->display_options['fields']['mail']['alter']['more_link'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['mail']['element_label_colon'] = 1;
+  $handler->display->display_options['fields']['mail']['element_default_classes'] = 1;
+  $handler->display->display_options['fields']['mail']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['mail']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['mail']['hide_alter_empty'] = 1;
+  /* Sort criterion: Draggableviews: Weight */
+  $handler->display->display_options['sorts']['weight']['id'] = 'weight';
+  $handler->display->display_options['sorts']['weight']['table'] = 'draggableviews_structure';
+  $handler->display->display_options['sorts']['weight']['field'] = 'weight';
+  $handler->display->display_options['sorts']['weight']['draggableviews_setting_view'] = 'users:page';
+  $handler->display->display_options['sorts']['weight']['draggableviews_setting_new_items_bottom_list'] = 1;
+  /* Filter criterion: User: Active */
+  $handler->display->display_options['filters']['status']['id'] = 'status';
+  $handler->display->display_options['filters']['status']['table'] = 'users';
+  $handler->display->display_options['filters']['status']['field'] = 'status';
+  $handler->display->display_options['filters']['status']['value'] = '1';
+  $handler->display->display_options['filters']['status']['group'] = 1;
+  $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
+  /* Filter criterion: User: E-mail */
+  $handler->display->display_options['filters']['mail']['id'] = 'mail';
+  $handler->display->display_options['filters']['mail']['table'] = 'users';
+  $handler->display->display_options['filters']['mail']['field'] = 'mail';
+  $handler->display->display_options['filters']['mail']['operator'] = 'starts';
+  $handler->display->display_options['filters']['mail']['exposed'] = TRUE;
+  $handler->display->display_options['filters']['mail']['expose']['operator_id'] = 'mail_op';
+  $handler->display->display_options['filters']['mail']['expose']['label'] = 'E-mail';
+  $handler->display->display_options['filters']['mail']['expose']['operator'] = 'mail_op';
+  $handler->display->display_options['filters']['mail']['expose']['identifier'] = 'mail';
+  $handler->display->display_options['filters']['mail']['expose']['required'] = 0;
+  $handler->display->display_options['filters']['mail']['expose']['multiple'] = FALSE;
+
+  /* Display: Page */
+  $handler = $view->new_display('page', 'Page', 'page_1');
+  $handler->display->display_options['defaults']['fields'] = FALSE;
+  /* Field: User: Name */
+  $handler->display->display_options['fields']['name']['id'] = 'name';
+  $handler->display->display_options['fields']['name']['table'] = 'users';
+  $handler->display->display_options['fields']['name']['field'] = 'name';
+  $handler->display->display_options['fields']['name']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['word_boundary'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['ellipsis'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['name']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['name']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['name']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['name']['link_to_user'] = 1;
+  $handler->display->display_options['fields']['name']['overwrite_anonymous'] = 0;
+  /* Field: User: E-mail */
+  $handler->display->display_options['fields']['mail']['id'] = 'mail';
+  $handler->display->display_options['fields']['mail']['table'] = 'users';
+  $handler->display->display_options['fields']['mail']['field'] = 'mail';
+  $handler->display->display_options['fields']['mail']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['external'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['replace_spaces'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['trim_whitespace'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['nl2br'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['word_boundary'] = 1;
+  $handler->display->display_options['fields']['mail']['alter']['ellipsis'] = 1;
+  $handler->display->display_options['fields']['mail']['alter']['more_link'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['mail']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['mail']['element_label_colon'] = 1;
+  $handler->display->display_options['fields']['mail']['element_default_classes'] = 1;
+  $handler->display->display_options['fields']['mail']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['mail']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['mail']['hide_alter_empty'] = 1;
+  $handler->display->display_options['path'] = 'users-display';
+
+  /* Display: Set Page */
+  $handler = $view->new_display('page', 'Set Page', 'page');
+  $handler->display->display_options['path'] = 'users-set';
+
+  $views[$view->name] = $view;
+
+  $view = new view;
+  $view->name = 'nodes';
+  $view->description = '';
+  $view->tag = 'default';
+  $view->base_table = 'node';
+  $view->human_name = 'nodes';
+  $view->core = 7;
+  $view->api_version = '3.0';
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+  /* Display: Master */
+  $handler = $view->new_display('default', 'Master', 'default');
+  $handler->display->display_options['title'] = 'nodes';
+  $handler->display->display_options['access']['type'] = 'perm';
+  $handler->display->display_options['cache']['type'] = 'none';
+  $handler->display->display_options['query']['type'] = 'views_query';
+  $handler->display->display_options['query']['options']['query_comment'] = FALSE;
+  $handler->display->display_options['query']['options']['query_tags'] = FALSE;
+  $handler->display->display_options['exposed_form']['type'] = 'basic';
+  $handler->display->display_options['pager']['type'] = 'full';
+  $handler->display->display_options['pager']['options']['items_per_page'] = '10';
+  $handler->display->display_options['style_plugin'] = 'table';
+  /* Field: Content: Title */
+  $handler->display->display_options['fields']['title']['id'] = 'title';
+  $handler->display->display_options['fields']['title']['table'] = 'node';
+  $handler->display->display_options['fields']['title']['field'] = 'title';
+  $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['title']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['title']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['title']['link_to_node'] = 1;
+  /* Field: Draggableviews: Content */
+  $handler->display->display_options['fields']['draggableviews']['id'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['table'] = 'node';
+  $handler->display->display_options['fields']['draggableviews']['field'] = 'draggableviews';
+  $handler->display->display_options['fields']['draggableviews']['element_label_colon'] = 1;
+  $handler->display->display_options['fields']['draggableviews']['element_default_classes'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['hide_alter_empty'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['handler'] = 'draggableviews_handler_fieldapi';
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['ajax'] = 0;
+  $handler->display->display_options['fields']['draggableviews']['draggableviews']['draggableviews_handler_fieldapi'] = array(
+    'field' => 'field_data_field_weight:field_weight_value',
+  );
+  /* Sort criterion: Content: Weight (field_weight) */
+  $handler->display->display_options['sorts']['field_weight_value']['id'] = 'field_weight_value';
+  $handler->display->display_options['sorts']['field_weight_value']['table'] = 'field_data_field_weight';
+  $handler->display->display_options['sorts']['field_weight_value']['field'] = 'field_weight_value';
+  /* Filter criterion: Content: Published */
+  $handler->display->display_options['filters']['status']['id'] = 'status';
+  $handler->display->display_options['filters']['status']['table'] = 'node';
+  $handler->display->display_options['filters']['status']['field'] = 'status';
+  $handler->display->display_options['filters']['status']['value'] = 1;
+  $handler->display->display_options['filters']['status']['group'] = 1;
+  $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
+
+  /* Display: Set Page */
+  $handler = $view->new_display('page', 'Set Page', 'page');
+  $handler->display->display_options['path'] = 'nodes-set';
+
+  /* Display: Display Page */
+  $handler = $view->new_display('page', 'Display Page', 'page_1');
+  $handler->display->display_options['defaults']['fields'] = FALSE;
+  /* Field: Content: Title */
+  $handler->display->display_options['fields']['title']['id'] = 'title';
+  $handler->display->display_options['fields']['title']['table'] = 'node';
+  $handler->display->display_options['fields']['title']['field'] = 'title';
+  $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['make_link'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['absolute'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['trim'] = 0;
+  $handler->display->display_options['fields']['title']['alter']['html'] = 0;
+  $handler->display->display_options['fields']['title']['hide_empty'] = 0;
+  $handler->display->display_options['fields']['title']['empty_zero'] = 0;
+  $handler->display->display_options['fields']['title']['link_to_node'] = 1;
+  $handler->display->display_options['path'] = 'nodes-display';
+
+  $views[$view->name] = $view;
+  
+  return $views;
+}
diff --git a/sites/all/modules/draggableviews/views/draggableviews.views.inc b/sites/all/modules/draggableviews/views/draggableviews.views.inc
new file mode 100644
index 000000000..4a347278f
--- /dev/null
+++ b/sites/all/modules/draggableviews/views/draggableviews.views.inc
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Views hooks implementations.
+ */
+
+/**
+ * Implements hook_views_data_alter().
+ */
+function draggableviews_views_data_alter(&$data) {
+
+  $data['draggableviews_structure']['weight'] = array(
+    'title' => t('Weight'),
+    'group' => t('Draggableviews'),
+    'field' => array(
+      'help' => t('Display the weight value.'),
+      'handler' => 'views_handler_field_numeric',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'help' => t('Sort entities by the draggableviews weight table field.'),
+      'handler' => 'draggableviews_handler_sort',
+    ),
+  );
+  $data['draggableviews_structure']['parent'] = array(
+    'title' => t('Parent'),
+    'help' => t('The parent entity id.'),
+    'group' => t('Draggableviews'),
+    'field' => array(
+      'handler' => 'views_handler_field_numeric',
+    ),
+  );
+
+  foreach (entity_get_info() as $entity_type => $info) {
+    if (isset($info['base table']) && isset($data[$info['base table']]['table'])) {
+      $data[$info['base table']]['draggableviews'] = array(
+        'title' => $data[$info['base table']]['table']['group'],
+        'group' => t('Draggableviews'),
+        'help' => t('Provide a draggable functionality.'),
+        'real field' => $info['entity keys']['id'],
+        'field' => array(
+          'handler' => 'draggableviews_handler_field_draggable',
+          'click sortable' => FALSE,
+        ),
+      );
+      // Explain to every entity how to join with draggableviews structure table.
+      $data['draggableviews_structure']['table']['join'][$info['base table']] = array(
+        'handler' => 'draggableviews_join_handler',
+        'left_table' => $info['base table'], // Because this is a direct link it could be left out.
+        'left_field' => $info['entity keys']['id'],
+        'field' => 'entity_id',
+      );
+    }
+  }
+}
diff --git a/sites/all/modules/draggableviews/views/draggableviews_handler_field_draggable.inc b/sites/all/modules/draggableviews/views/draggableviews_handler_field_draggable.inc
new file mode 100644
index 000000000..9f4b130f1
--- /dev/null
+++ b/sites/all/modules/draggableviews/views/draggableviews_handler_field_draggable.inc
@@ -0,0 +1,199 @@
+<?php
+
+/**
+ * @file
+ * Views field handler. Contains all relevant Draggableviews
+ * options and related logic.
+ * Implements the Views Form API.
+ */
+
+class draggableviews_handler_field_draggable extends views_handler_field {
+
+  function construct() {
+    parent::construct();
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['draggableviews'] = array(
+      'contains' => array(
+        'handler' => array('default' => 'draggableviews_handler_native'),
+        'hierarchy_handler' => array('default' => ''),
+        'save_button_label' => array('default' => 'Save'),
+        'ajax' => array('default' => FALSE),
+      ),
+    );
+
+    // Populate default values of form elements provided by handlers.
+    foreach (draggableviews_get_handlers() as $handler_id => $handler_object) {
+      $options['draggableviews']['contains'][$handler_id] = array('default' => $handler_object->option_definition());
+    }
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // Remove not needed settings options.
+    $form['alter']['#access'] = FALSE;
+    $form['style_settings']['#access'] = FALSE;
+    $form['empty_field_behavior']['#access'] = FALSE;
+
+    $form['draggableviews'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Draggable Views'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+
+    $handler_options = array();
+    $handler_forms = array();
+    foreach (draggableviews_get_handlers() as $handler_id => $handler_object) {
+      $handler = ctools_get_plugins('draggableviews', 'handler', $handler_id);
+      $handler_options[$handler_id] = filter_xss($handler['label']);
+      $handler_forms[$handler_id] = $handler_object->options_form($this);
+    }
+
+    $form['draggableviews']['handler'] = array(
+      '#type' => 'select',
+      '#title' => t('Sort handler'),
+      '#options' => $handler_options,
+      '#default_value' => $this->options['draggableviews']['handler'],
+    );
+
+    // Add handler's form element as fielset that
+    // is active only if handler selected.
+    foreach ($handler_forms as $handler_id => $handler_form_element) {
+      // Skip empty handler's form elements.
+      if (empty($handler_form_element)) {
+        continue;
+      }
+      $form['draggableviews'][$handler_id] = array(
+        '#type' => 'fieldset',
+        '#title' => check_plain($form['draggableviews']['handler']['#options'][$handler_id]),
+        '#collapsible' => FALSE,
+        '#states' => array(
+          'visible' => array(
+            'select[name="options[draggableviews][handler]"]' => array('value' => $handler_id),
+          ),
+        ),
+      );
+      foreach ($handler_form_element as $key => $form_element) {
+        $form['draggableviews'][$handler_id][$key] = $form_element;
+      }
+    }
+
+    $hierarchy_handler_options = array('' => t('- None -'));
+    $hierarchy_handler_forms = array();
+    foreach (draggableviews_get_hierarchy_handlers() as $handler_id => $handler_object) {
+      $handler = ctools_get_plugins('draggableviews', 'hierarchy_handler', $handler_id);
+      $hierarchy_handler_options[$handler_id] = filter_xss($handler['label']);
+      $hierarchy_handler_forms[$handler_id] = $handler_object->options_form($this);
+    }
+
+    $form['draggableviews']['hierarchy_handler'] = array(
+      '#type' => 'select',
+      '#title' => t('Hierarchy handler'),
+      '#options' => $hierarchy_handler_options,
+      '#default_value' => $this->options['draggableviews']['hierarchy_handler'],
+    );
+
+    // Add handler's form element as fielset that
+    // is active only if handler selected.
+    foreach ($hierarchy_handler_forms as $handler_id => $hierarchy_handler_form_element) {
+      // Skip empty handler's form elements.
+      if (empty($hierarchy_handler_form_element)) {
+        continue;
+      }
+      $form['draggableviews'][$handler_id] = array(
+        '#type' => 'fieldset',
+        '#title' => check_plain($form['draggableviews']['handler']['#options'][$handler_id]),
+        '#collapsible' => FALSE,
+        '#states' => array(
+          'visible' => array(
+            'select[name="options[draggableviews][hierarchy_handler]"]' => array('value' => $handler_id),
+          ),
+        ),
+      );
+      foreach ($hierarchy_handler_form_element as $key => $form_element) {
+        $form['draggableviews'][$handler_id][$key] = $form_element;
+      }
+    }
+
+    $form['draggableviews']['save_button_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom Save button label'),
+      '#size' => 20,
+      '#description' => t("Allow to change Save button Label."),
+      '#default_value' => $this->options['draggableviews']['save_button_label'],
+    );
+
+    $form['draggableviews']['ajax'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Ajax'),
+      '#description' => t('Use ajax in draggable form.'),
+      '#default_value' => $this->options['draggableviews']['ajax'],
+    );
+  }
+
+  function render($values) {
+    if (user_access('access draggableviews')) {
+      return '<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->';
+    }
+  }
+
+  /**
+   * The form which replaces the placeholder from render().
+   */
+  function views_form(&$form, &$form_state) {
+    // The view is empty, abort.
+    if (empty($this->view->result)) {
+      return;
+    }
+
+    $form[$this->options['id']] = array(
+      '#tree' => TRUE,
+    );
+    $range = count($this->view->result);
+    // At this point, the query has already been run, so we can access the results
+    // in order to get the base key value (for example, nid for nodes).
+    foreach ($this->view->result as $row_index => $row) {
+      $entity_id = $this->get_value($row);
+
+      $form[$this->options['id']][$row_index] = array(
+        '#tree' => TRUE,
+      );
+
+      $handler_object = draggableviews_get_handler_class($this->options['draggableviews']['handler']);
+
+      // Weight field selectbox.
+      $form[$this->options['id']][$row_index]['weight'] = array(
+        '#type' => 'select',
+        '#options' => range(-$range, $range),
+        '#attributes' => array('class' => array('draggableviews-weight')),
+        '#default_value' => $handler_object->get($this, $row_index),
+      );
+      // Item to keep id of the entity.
+      $form[$this->options['id']][$row_index]['id'] = array(
+        '#type' => 'hidden',
+        '#value' => $this->view->result[$row_index]->{$this->field_alias},
+        '#attributes' => array('class' => 'draggableviews-id'),
+      );
+      // Add parent and depth field.
+      if (!empty($this->options['draggableviews']['hierarchy_handler'])) {
+        $hierarchy_handler_object = draggableviews_get_handler_class($this->options['draggableviews']['hierarchy_handler'], 'hierarchy_handler');
+        $form[$this->options['id']][$row_index]['parent'] = array(
+          '#type' => 'hidden',
+          '#default_value' => $hierarchy_handler_object->get($this, $row_index),
+          '#attributes' => array('class' => 'draggableviews-parent'),
+        );
+        $form[$this->options['id']][$row_index]['depth'] = array(
+          '#type' => 'hidden',
+          '#default_value' => $hierarchy_handler_object->get_depth($this, $row_index),
+          '#attributes' => array('class' => 'draggableviews-depth'),
+        );
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/sites/all/modules/draggableviews/views/draggableviews_handler_sort.inc b/sites/all/modules/draggableviews/views/draggableviews_handler_sort.inc
new file mode 100644
index 000000000..1931473a3
--- /dev/null
+++ b/sites/all/modules/draggableviews/views/draggableviews_handler_sort.inc
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Native handler sort.
+ */
+
+/**
+ * Sort handler for ordering by weight.
+ */
+class draggableviews_handler_sort extends views_handler_sort {
+  function query() {
+    $this->ensure_my_table();
+    // If new items should be placed in the bottom.
+    if ($this->options['draggableviews_setting_new_items_bottom_list']) {
+      // New items will get big default instead of NULL
+      $alias = $this->table_alias . '_' . $this->field . '_coalesce';
+      $this->query->add_field(NULL, "COALESCE($this->table_alias.$this->field, 10000)", $alias);
+      $this->query->orderby[] = array(
+        'field' => $alias,
+        'direction' => drupal_strtoupper($this->options['order'])
+      );
+    }
+    else {
+      // New items will be placed at the top as have NULL value.
+      $this->query->add_orderby($this->table_alias, $this->real_field);
+    }
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    // This handler invokes few times for one view,
+    // in the first time the $this->view->name is empty,
+    // so we need this check.
+    if (is_object($this->view)) {
+      $options['draggableviews_setting_view'] = array('default' => $this->view->name);
+    }
+    else {
+      $options['draggableviews_setting_view'] = array('default' => 'self');
+    }
+
+    $options['draggableviews_setting_arguments'] = array('default' => 'all');
+    $options['draggableviews_setting_arguments_php'] = array('default' => '');
+    $options['draggableviews_setting_new_items_bottom_list'] = array('default' => TRUE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['expose_button']['#access'] = FALSE;
+    $form['order']['#description'] = t('Please remember to override settings of the sort criterion if you have display that sets weights and you choose descendling order.');
+
+    // Check whether current views display doesn't have draggableviews field.
+    // If it has, it means that this is setting view so we should set
+    // option draggableviews_setting_view to 'self'
+    $options = _draggableviews_get_views_options($this->view);
+
+    // If it is setting view.
+    if (!is_array($options)) {
+      $form['order']['#access'] = FALSE;
+      $options = isset($this->options['draggableviews_setting_view']) ? $this->options['draggableviews_setting_view'] : 'self';
+      $form['draggableviews_setting_view'] = array(
+        '#type' => 'value',
+        '#value' => $options,
+      );
+    }
+    else {
+      $form['draggableviews_setting_view'] = array(
+        '#type' => 'select',
+        '#title' => t('Display sort as'),
+        '#default_value' => $this->options['draggableviews_setting_view'],
+        '#options' => $options,
+        '#description' => t('Please choose the view and display that sets the order.')
+      );
+      // If there is no setting views available, show error message.
+      if (empty($options)) {
+        drupal_set_message(t('First you should create a view that sets sorting order.'), 'error');
+      }
+    }
+
+    $form['draggableviews_setting_arguments'] = array(
+      '#title' => t('Arguments handling'),
+      '#type' => 'radios',
+      '#options' => array(
+        'all' => t('Use all arguments'),
+        'none' => t('Do not use any arguments (use empty arguments)'),
+        'php' => t('Prepare arguments with PHP code'),
+      ),
+      '#default_value' => $this->options['draggableviews_setting_arguments'],
+      '#description' => t('When sorting order is saved all arguments passed are saved with order. In display view we can choose how to use these arguments.')
+    );
+    $form['draggableviews_setting_arguments_php'] = array(
+      '#title' => t('PHP code to prepare arguments'),
+      '#type' => 'textarea',
+      '#default_value' => $this->options['draggableviews_setting_arguments_php'],
+      '#description' => t('Enter the php code to prepare the arguments. Do not enter <?php ?>. The following variables are available - $view (the view), $arguments (existing arguments - manipulate these to alter the arguments used to sort).'),
+      '#states' => array(
+        'visible' => array(
+          'input[name="options[draggableviews_setting_arguments]"]' => array('value' => 'php'),
+        ),
+      ),
+    );
+    $form['draggableviews_setting_new_items_bottom_list'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('New items appear bottom of the list'),
+      '#description' => t('New items means elements (for example nodes) that do not have saved weight (newly created).'),
+      '#default_value' => $this->options['draggableviews_setting_new_items_bottom_list'],
+    );
+  }
+}
diff --git a/sites/all/modules/draggableviews/views/draggableviews_join_handler.inc b/sites/all/modules/draggableviews/views/draggableviews_join_handler.inc
new file mode 100644
index 000000000..9a5451539
--- /dev/null
+++ b/sites/all/modules/draggableviews/views/draggableviews_join_handler.inc
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Native handler join handler.
+ */
+
+/**
+ * Join handler for extra join conditions.
+ */
+class draggableviews_join_handler extends views_join {
+  /**
+   * Build the SQL for the join this object represents.
+   */
+  function build_join($select_query, $table, $view_query) {
+    $view = $view_query->view;
+
+    if (empty($this->definition['table formula'])) {
+      $right_table = $this->table;
+    }
+    else {
+      $right_table = $this->definition['table formula'];
+    }
+
+    if ($this->left_table) {
+      $left = $view_query->get_table_info($this->left_table);
+      $left_field = "$left[alias].$this->left_field";
+    }
+    else {
+      // This can be used if left_field is a formula or something. It should be used only *very* rarely.
+      $left_field = $this->left_field;
+    }
+
+    $condition = "$left_field = $table[alias].$this->field";
+
+    // Check whether setting view is set.
+    $arguments = array();
+    $weight_key = _draggableviews_get_draggable_sort($view);
+    if (!empty($view->sort[$weight_key]->options['draggableviews_setting_view'])) {
+      $condition .= " AND $table[alias].view_name = :view_name";
+      $condition .= " AND $table[alias].view_display = :view_display";
+
+      // If it is setting view, set current view name and display name.
+      if ($view->sort[$weight_key]->options['draggableviews_setting_view'] == 'self') {
+        $arguments[':view_name'] = $view->name;
+        $arguments[':view_display'] = $view->current_display;
+      }
+      else {
+        list($setting_view_name, $setting_view_display) = explode(':', $view->sort[$weight_key]->options['draggableviews_setting_view']);
+        $arguments[':view_name'] = $setting_view_name;
+        $arguments[':view_display'] = $setting_view_display;
+      }
+
+      // Arguments passed to view (including exposed filters).
+      $view_arguments = $view->args;
+      if (isset($view->exposed_raw_input)) {
+        $view_arguments += $view->exposed_raw_input;
+        ksort($view_arguments);
+      }
+      // Alter arguments according to sort criteria settings.
+      if ($view->sort[$weight_key]->options['draggableviews_setting_arguments'] == 'none') {
+        $view_arguments = array();
+      }
+      // If PHP arguments processing is set.
+      if ($view->sort[$weight_key]->options['draggableviews_setting_arguments'] == 'php') {
+        $clone_view = clone $view;
+        $view_arguments = _draggableviews_eval_return($view->sort[$weight_key]->options['draggableviews_setting_arguments_php'], $view_arguments, $clone_view);
+      }
+      $condition .= " AND $table[alias].args = :view_arguments";
+      $arguments[':view_arguments'] = json_encode($view_arguments);
+    }
+
+    $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments);
+
+    // Add also parent field.
+    if ($order_view = _draggableviews_load_order_view($view)) {
+      if (isset($order_view->field['draggableviews']->options['draggableviews']['hierarchy_handler'])
+        && $order_view->field['draggableviews']->options['draggableviews']['hierarchy_handler'] == 'draggableviews_hierarchy_handler_native') {
+        $select_query->addField($table['alias'], 'parent', 'draggableviews_structure_parent');
+      }
+    }
+  }
+}
\ No newline at end of file
-- 
GitLab