Bugzilla – Attachment 163598 Details for
Bug 35249
Use DataTables RowReorder extension instead of tableDND jQuery plugin
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 35249: Use DataTables RowReorder extension instead of tableDND jQuery plugin
Bug-35249-Use-DataTables-RowReorder-extension-inst.patch (text/plain), 44.87 KB, created by
Jonathan Druart
on 2024-03-21 11:27:32 UTC
(
hide
)
Description:
Bug 35249: Use DataTables RowReorder extension instead of tableDND jQuery plugin
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2024-03-21 11:27:32 UTC
Size:
44.87 KB
patch
obsolete
>From 1f49365ae52f21c77d5f6741fcb36496f789f8b4 Mon Sep 17 00:00:00 2001 >From: Owen Leonard <oleonard@myacpl.org> >Date: Mon, 30 Oct 2023 17:53:41 +0000 >Subject: [PATCH] Bug 35249: Use DataTables RowReorder extension instead of > tableDND jQuery plugin > >Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >--- > .../datatables/dataTables.rowReorder.min.js | 4 + > .../datatables/rowReorder.dataTables.min.css | 36 + > .../lib/jquery/plugins/jquery.tablednd.js | 672 ------------------ > .../prog/css/src/staff-global.scss | 20 +- > .../searchengine/elasticsearch/mappings.tt | 12 +- > .../prog/js/elasticsearch-mappings.js | 15 +- > 6 files changed, 70 insertions(+), 689 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/lib/datatables/dataTables.rowReorder.min.js > create mode 100644 koha-tmpl/intranet-tmpl/lib/datatables/rowReorder.dataTables.min.css > delete mode 100644 koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.tablednd.js > >diff --git a/koha-tmpl/intranet-tmpl/lib/datatables/dataTables.rowReorder.min.js b/koha-tmpl/intranet-tmpl/lib/datatables/dataTables.rowReorder.min.js >new file mode 100644 >index 00000000000..19c1e8a6563 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/lib/datatables/dataTables.rowReorder.min.js >@@ -0,0 +1,4 @@ >+/*! RowReorder 1.4.1 >+ * © SpryMedia Ltd - datatables.net/license >+ */ >+!function(o){var r,n;"function"==typeof define&&define.amd?define(["jquery","datatables.net"],function(t){return o(t,window,document)}):"object"==typeof exports?(r=require("jquery"),n=function(t,e){e.fn.dataTable||require("datatables.net")(t,e)},"undefined"==typeof window?module.exports=function(t,e){return t=t||window,e=e||r(t),n(t,e),o(e,t,t.document)}:(n(window,r),module.exports=o(r,window,window.document))):o(jQuery,window,document)}(function(v,d,a,s){"use strict";function i(t,e){if(!l.versionCheck||!l.versionCheck("1.10.8"))throw"DataTables RowReorder requires DataTables 1.10.8 or newer";if(this.c=v.extend(!0,{},l.defaults.rowReorder,i.defaults,e),this.s={bodyTop:null,dt:new l.Api(t),getDataFn:l.ext.oApi._fnGetObjectDataFn(this.c.dataSrc),middles:null,scroll:{},scrollInterval:null,setDataFn:l.ext.oApi._fnSetObjectDataFn(this.c.dataSrc),start:{top:0,left:0,offsetTop:0,offsetLeft:0,nodes:[],rowIndex:0},windowHeight:0,documentOuterHeight:0,domCloneOuterHeight:0,dropAllowed:!0},this.dom={clone:null,cloneParent:null,dtScroll:v("div.dataTables_scrollBody",this.s.dt.table().container())},e=this.s.dt.settings()[0],t=e.rowreorder)return t;this.dom.dtScroll.length||(this.dom.dtScroll=v(this.s.dt.table().container(),"tbody")),(e.rowreorder=this)._constructor()}var l=v.fn.dataTable,t=(v.extend(i.prototype,{_constructor:function(){var r=this,n=this.s.dt,t=v(n.table().node());"static"===t.css("position")&&t.css("position","relative"),v(n.table().container()).on("mousedown.rowReorder touchstart.rowReorder",this.c.selector,function(t){var e,o;if(r.c.enable)return!!v(t.target).is(r.c.excludedChildren)||(e=v(this).closest("tr"),(o=n.row(e)).any()?(r._emitEvent("pre-row-reorder",{node:o.node(),index:o.index()}),r._mouseDown(t,e),!1):void 0)}),n.on("destroy.rowReorder",function(){v(n.table().container()).off(".rowReorder"),n.off(".rowReorder")}),this._keyup=this._keyup.bind(this)},_cachePositions:function(){var t=this.s.dt,r=v(t.table().node()).find("thead").outerHeight(),e=v.unique(t.rows({page:"current"}).nodes().toArray()),e=v.map(e,function(t,e){var o=v(t).position().top-r;return(o+o+v(t).outerHeight())/2});this.s.middles=e,this.s.bodyTop=v(t.table().body()).offset().top,this.s.windowHeight=v(d).height(),this.s.documentOuterHeight=v(a).outerHeight(),this.s.bodyArea=this._calcBodyArea()},_clone:function(t){var e=this.s.dt,e=v(e.table().node().cloneNode(!1)).addClass("dt-rowReorder-float").append("<tbody/>").append(t.clone(!1)),o=t.outerWidth(),r=t.outerHeight(),n=v(v(this.s.dt.table().node()).parent()),s=n.width(),n=n.scrollLeft(),i=t.children().map(function(){return v(this).width()}),t=(e.width(o).height(r).find("tr").children().each(function(t){this.style.width=i[t]+"px"}),v("<div>").addClass("dt-rowReorder-float-parent").width(s).append(e).appendTo("body").scrollLeft(n));this.dom.clone=e,this.dom.cloneParent=t,this.s.domCloneOuterHeight=e.outerHeight()},_clonePosition:function(t){var e=this.s.start,o=this._eventToPage(t,"Y")-e.top,t=this._eventToPage(t,"X")-e.left,r=this.c.snapX,o=o+e.offsetTop,r=!0===r?e.offsetLeft:"number"==typeof r?e.offsetLeft+r:t+e.offsetLeft+this.dom.cloneParent.scrollLeft();o<0?o=0:o+this.s.domCloneOuterHeight>this.s.documentOuterHeight&&(o=this.s.documentOuterHeight-this.s.domCloneOuterHeight),this.dom.cloneParent.css({top:o,left:r})},_emitEvent:function(o,r){var n;return this.s.dt.iterator("table",function(t,e){t=v(t.nTable).triggerHandler(o+".dt",r);t!==s&&(n=t)}),n},_eventToPage:function(t,e){return(-1!==t.type.indexOf("touch")?t.originalEvent.touches[0]:t)["page"+e]},_mouseDown:function(t,e){var o=this,r=this.s.dt,n=this.s.start,s=this.c.cancelable,i=e.offset(),i=(n.top=this._eventToPage(t,"Y"),n.left=this._eventToPage(t,"X"),n.offsetTop=i.top,n.offsetLeft=i.left,n.nodes=v.unique(r.rows({page:"current"}).nodes().toArray()),this._cachePositions(),this._clone(e),this._clonePosition(t),this._eventToPage(t,"Y")-this.s.bodyTop),r=(n.rowIndex=this._calcRowIndexByPos(i),(this.dom.target=e).addClass("dt-rowReorder-moving"),v(a).on("mouseup.rowReorder touchend.rowReorder",function(t){o._mouseUp(t)}).on("mousemove.rowReorder touchmove.rowReorder",function(t){o._mouseMove(t)}),v(d).width()===v(a).width()&&v(a.body).addClass("dt-rowReorder-noOverflow"),this.dom.dtScroll);this.s.scroll={windowHeight:v(d).height(),windowWidth:v(d).width(),dtTop:r.length?r.offset().top:null,dtLeft:r.length?r.offset().left:null,dtHeight:r.length?r.outerHeight():null,dtWidth:r.length?r.outerWidth():null},s&&v(a).on("keyup",this._keyup)},_mouseMove:function(t){this._clonePosition(t);for(var e,o,r=this.s.start,n=this.c.cancelable,s=(n&&(e=this.s.bodyArea,o=this._calcCloneParentArea(),this.s.dropAllowed=this._rectanglesIntersect(e,o),this.s.dropAllowed?v(this.dom.cloneParent).removeClass("drop-not-allowed"):v(this.dom.cloneParent).addClass("drop-not-allowed")),this._eventToPage(t,"Y")-this.s.bodyTop),i=this.s.middles,d=null,a=0,l=i.length;a<l;a++)if(s<i[a]){d=a;break}null===d&&(d=i.length),n&&(this.s.dropAllowed||(d=r.rowIndex>this.s.lastInsert?r.rowIndex+1:r.rowIndex),this.dom.target.toggleClass("dt-rowReorder-moving",this.s.dropAllowed)),this._moveTargetIntoPosition(d),this._shiftScroll(t)},_mouseUp:function(t){var e=this,o=this.s.dt,r=this.c.dataSrc;if(this.s.dropAllowed){for(var n,s,i,d=this.s.start.nodes,a=v.unique(o.rows({page:"current"}).nodes().toArray()),l={},c=[],h=[],u=this.s.getDataFn,f=this.s.setDataFn,w=0,p=d.length;w<p;w++)d[w]!==a[w]&&(n=o.row(a[w]).id(),s=o.row(a[w]).data(),i=o.row(d[w]).data(),n&&(l[n]=u(i)),c.push({node:a[w],oldData:u(s),newData:u(i),newPosition:w,oldPosition:v.inArray(a[w],d)}),h.push(a[w]));var g,m=[c,{dataSrc:r,nodes:h,values:l,triggerRow:o.row(this.dom.target),originalEvent:t}];!1===this._emitEvent("row-reorder",m)?e._cancel():(this._cleanupDragging(),g=function(){if(e.c.update){for(w=0,p=c.length;w<p;w++){var t=o.row(c[w].node).data();f(t,c[w].newData),o.columns().every(function(){this.dataSrc()===r&&o.cell(c[w].node,this.index()).invalidate("data")})}e._emitEvent("row-reordered",m),o.draw(!1)}},this.c.editor?(this.c.enable=!1,this.c.editor.edit(h,!1,v.extend({submit:"changed"},this.c.formOptions)).multiSet(r,l).one("preSubmitCancelled.rowReorder",function(){e.c.enable=!0,e.c.editor.off(".rowReorder"),o.draw(!1)}).one("submitUnsuccessful.rowReorder",function(){o.draw(!1)}).one("submitSuccess.rowReorder",function(){g()}).one("submitComplete",function(){e.c.enable=!0,e.c.editor.off(".rowReorder")}).submit()):g())}else e._cancel()},_moveTargetIntoPosition:function(t){var e,o,r=this.s.dt;null!==this.s.lastInsert&&this.s.lastInsert===t||(e=v.unique(r.rows({page:"current"}).nodes().toArray()),o="",o=t>this.s.lastInsert?(this.dom.target.insertAfter(e[t-1]),"after"):(this.dom.target.insertBefore(e[t]),"before"),this._cachePositions(),this.s.lastInsert=t,this._emitEvent("row-reorder-changed",{insertPlacement:o,insertPoint:t,row:r.row(this.dom.target)}))},_cleanupDragging:function(){var t=this.c.cancelable;this.dom.clone.remove(),this.dom.cloneParent.remove(),this.dom.clone=null,this.dom.cloneParent=null,this.dom.target.removeClass("dt-rowReorder-moving"),v(a).off(".rowReorder"),v(a.body).removeClass("dt-rowReorder-noOverflow"),clearInterval(this.s.scrollInterval),this.s.scrollInterval=null,t&&v(a).off("keyup",this._keyup)},_shiftScroll:function(t){var e,o,r=this,n=(this.s.dt,this.s.scroll),s=!1,i=t.pageY-a.body.scrollTop;i<v(d).scrollTop()+65?e=-5:i>n.windowHeight+v(d).scrollTop()-65&&(e=5),null!==n.dtTop&&t.pageY<n.dtTop+65?o=-5:null!==n.dtTop&&t.pageY>n.dtTop+n.dtHeight-65&&(o=5),e||o?(n.windowVert=e,n.dtVert=o,s=!0):this.s.scrollInterval&&(clearInterval(this.s.scrollInterval),this.s.scrollInterval=null),!this.s.scrollInterval&&s&&(this.s.scrollInterval=setInterval(function(){var t;n.windowVert&&(t=v(a).scrollTop(),v(a).scrollTop(t+n.windowVert),t!==v(a).scrollTop())&&(t=parseFloat(r.dom.cloneParent.css("top")),r.dom.cloneParent.css("top",t+n.windowVert)),n.dtVert&&(t=r.dom.dtScroll[0],n.dtVert)&&(t.scrollTop+=n.dtVert)},20))},_calcBodyArea:function(t){var e=this.s.dt,o=v(e.table().body()).offset();return{left:o.left,top:o.top,right:o.left+v(e.table().body()).width(),bottom:o.top+v(e.table().body()).height()}},_calcCloneParentArea:function(t){this.s.dt;var e=v(this.dom.cloneParent).offset();return{left:e.left,top:e.top,right:e.left+v(this.dom.cloneParent).width(),bottom:e.top+v(this.dom.cloneParent).height()}},_rectanglesIntersect:function(t,e){return!(t.left>=e.right||e.left>=t.right||t.top>=e.bottom||e.top>=t.bottom)},_calcRowIndexByPos:function(r){var t=this.s.dt,e=v.unique(t.rows({page:"current"}).nodes().toArray()),n=-1,s=v(t.table().node()).find("thead").outerHeight();return v.each(e,function(t,e){var o=v(e).position().top-s,e=o+v(e).outerHeight();o<=r&&r<=e&&(n=t)}),n},_keyup:function(t){this.c.cancelable&&27===t.which&&(t.preventDefault(),this._cancel())},_cancel:function(){var t=this.s.start,t=t.rowIndex>this.s.lastInsert?t.rowIndex+1:t.rowIndex;this._moveTargetIntoPosition(t),this._cleanupDragging(),this._emitEvent("row-reorder-canceled",[this.s.start.rowIndex])}}),i.defaults={dataSrc:0,editor:null,enable:!0,formOptions:{},selector:"td:first-child",snapX:!1,update:!0,excludedChildren:"a",cancelable:!1},v.fn.dataTable.Api);return t.register("rowReorder()",function(){return this}),t.register("rowReorder.enable()",function(e){return e===s&&(e=!0),this.iterator("table",function(t){t.rowreorder&&(t.rowreorder.c.enable=e)})}),t.register("rowReorder.disable()",function(){return this.iterator("table",function(t){t.rowreorder&&(t.rowreorder.c.enable=!1)})}),i.version="1.4.1",v.fn.dataTable.RowReorder=i,v.fn.DataTable.RowReorder=i,v(a).on("init.dt.dtr",function(t,e,o){var r,n;"dt"===t.namespace&&(t=e.oInit.rowReorder,r=l.defaults.rowReorder,t||r)&&(n=v.extend({},t,r),!1!==t)&&new i(e,n)}),l}); >\ No newline at end of file >diff --git a/koha-tmpl/intranet-tmpl/lib/datatables/rowReorder.dataTables.min.css b/koha-tmpl/intranet-tmpl/lib/datatables/rowReorder.dataTables.min.css >new file mode 100644 >index 00000000000..ced1e62583f >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/lib/datatables/rowReorder.dataTables.min.css >@@ -0,0 +1,36 @@ >+div.dt-rowReorder-float-parent { >+ table-layout: fixed; >+ outline: 2px solid green; >+ z-index: 2001; >+ position: absolute !important; >+ overflow: hidden; >+ border-radius: 0; >+} >+div.dt-rowReorder-float-parent table.dt-rowReorder-float { >+ opacity: 0.9; >+ background-color: white; >+ margin: 0 !important; >+} >+div.dt-rowReorder-float-parent.drop-not-allowed { >+ cursor: not-allowed; >+} >+tr.dt-rowReorder-moving { >+ outline: 2px solid #888; >+ outline-offset: -2px; >+} >+body.dt-rowReorder-noOverflow { >+ overflow-x: hidden; >+} >+table.dataTable td.reorder { >+ text-align: center; >+ cursor: move; >+} >+html.dark div.dt-rowReorder-float-parent { >+ outline-color: #52ceff; >+} >+html.dark div.dt-rowReorder-float-parent table.dt-rowReorder-float { >+ background-color: var(--dt-html-background); >+} >+html.dark tr.dt-rowReorder-moving { >+ outline-color: #aaa; >+} >diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.tablednd.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.tablednd.js >deleted file mode 100644 >index f0bd3329cdc..00000000000 >--- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.tablednd.js >+++ /dev/null >@@ -1,672 +0,0 @@ >-/** >- * TableDnD plug-in for JQuery, allows you to drag and drop table rows >- * You can set up various options to control how the system will work >- * Copyright (c) Denis Howlett <denish@isocra.com> >- * Licensed like jQuery, see http://docs.jquery.com/License. >- * >- * Configuration options: >- * >- * onDragStyle >- * This is the style that is assigned to the row during drag. There are limitations to the styles that can be >- * associated with a row (such as you can't assign a border--well you can, but it won't be >- * displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as >- * a map (as used in the jQuery css(...) function). >- * onDropStyle >- * This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations >- * to what you can do. Also this replaces the original style, so again consider using onDragClass which >- * is simply added and then removed on drop. >- * onDragClass >- * This class is added for the duration of the drag and then removed when the row is dropped. It is more >- * flexible than using onDragStyle since it can be inherited by the row cells and other content. The default >- * is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your >- * stylesheet. >- * onDrop >- * Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table >- * and the row that was dropped. You can work out the new order of the rows by using >- * table.rows. >- * onDragStart >- * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the >- * table and the row which the user has started to drag. >- * onAllowDrop >- * Pass a function that will be called as a row is over another row. If the function returns true, allow >- * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under >- * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. >- * scrollAmount >- * This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the >- * window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2, >- * FF3 beta >- * dragHandle >- * This is a jQuery mach string for one or more cells in each row that is draggable. If you >- * specify this, then you are responsible for setting cursor: move in the CSS and only these cells >- * will have the drag behaviour. If you do not specify a dragHandle, then you get the old behaviour where >- * the whole row is draggable. >- * >- * Other ways to control behaviour: >- * >- * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows >- * that you don't want to be draggable. >- * >- * Inside the onDrop method you can also call $.tableDnD.serialize() this returns a string of the form >- * <tableID>[]=<rowID1>&<tableID>[]=<rowID2> so that you can send this back to the server. The table must have >- * an ID as must all the rows. >- * >- * Other methods: >- * >- * $("...").tableDnDUpdate() >- * Will update all the matching tables, that is it will reapply the mousedown method to the rows (or handle cells). >- * This is useful if you have updated the table rows using Ajax and you want to make the table draggable again. >- * The table maintains the original configuration (so you don't have to specify it again). >- * >- * $("...").tableDnDSerialize() >- * Will serialize and return the serialized string as above, but for each of the matching tables--so it can be >- * called from anywhere and isn't dependent on the currentTable being set up correctly before calling >- * >- * Known problems: >- * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 >- * >- * Version 0.2: 2008-02-20 First public version >- * Version 0.3: 2008-02-07 Added onDragStart option >- * Made the scroll amount configurable (default is 5 as before) >- * Version 0.4: 2008-03-15 Changed the noDrag/noDrop attributes to nodrag/nodrop classes >- * Added onAllowDrop to control dropping >- * Fixed a bug which meant that you couldn't set the scroll amount in both directions >- * Added serialize method >- * Version 0.5: 2008-05-16 Changed so that if you specify a dragHandle class it doesn't make the whole row >- * draggable >- * Improved the serialize method to use a default (and settable) regular expression. >- * Added tableDnDupate() and tableDnDSerialize() to be called when you are outside the table >- * Version 0.6: 2011-12-02 Added support for touch devices >- * Version 0.7 2012-04-09 Now works with jQuery 1.7 and supports touch, tidied up tabs and spaces >- */ >-!function ($, window, document, undefined) { >-// Determine if this is a touch device >-var hasTouch = 'ontouchstart' in document.documentElement, >- startEvent = 'touchstart mousedown', >- moveEvent = 'touchmove mousemove', >- endEvent = 'touchend mouseup'; >- >-// If we're on a touch device, then wire up the events >-// see http://stackoverflow.com/a/8456194/1316086 >-hasTouch >- && $.each("touchstart touchmove touchend".split(" "), function(i, name) { >- $.event.fixHooks[name] = $.event.mouseHooks; >- }); >- >- >-$(document).ready(function () { >- function parseStyle(css) { >- var objMap = {}, >- parts = css.match(/([^;:]+)/g) || []; >- while (parts.length) >- objMap[parts.shift()] = parts.shift().trim(); >- >- return objMap; >- } >- $('table').each(function () { >- if ($(this).data('table') == 'dnd') { >- >- $(this).tableDnD({ >- onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null, >- onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null, >- onDragClass: $(this).data('ondragclass') == undefined && "tDnD_whileDrag" || $(this).data('ondragclass'), >- onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null, >- onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null, >- scrollAmount: $(this).data('scrollamount') || 5, >- sensitivity: $(this).data('sensitivity') || 10, >- hierarchyLevel: $(this).data('hierarchylevel') || 0, >- indentArtifact: $(this).data('indentartifact') || '<div class="indent"> </div>', >- autoWidthAdjust: $(this).data('autowidthadjust') || true, >- autoCleanRelations: $(this).data('autocleanrelations') || true, >- jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t', >- serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/, >- serializeParamName: $(this).data('serializeparamname') || false, >- dragHandle: $(this).data('draghandle') || null >- }); >- } >- >- >- }); >-}); >- >-jQuery.tableDnD = { >- /** Keep hold of the current table being dragged */ >- currentTable: null, >- /** Keep hold of the current drag object if any */ >- dragObject: null, >- /** The current mouse offset */ >- mouseOffset: null, >- /** Remember the old value of X and Y so that we don't do too much processing */ >- oldX: 0, >- oldY: 0, >- >- /** Actually build the structure */ >- build: function(options) { >- // Set up the defaults if any >- >- this.each(function() { >- // This is bound to each matching table, set up the defaults and override with user options >- this.tableDnDConfig = $.extend({ >- onDragStyle: null, >- onDropStyle: null, >- // Add in the default class for whileDragging >- onDragClass: "tDnD_whileDrag", >- onDrop: null, >- onDragStart: null, >- scrollAmount: 5, >- /** Sensitivity setting will throttle the trigger rate for movement detection */ >- sensitivity: 10, >- /** Hierarchy level to support parent child. 0 switches this functionality off */ >- hierarchyLevel: 0, >- /** The html artifact to prepend the first cell with as indentation */ >- indentArtifact: '<div class="indent"> </div>', >- /** Automatically adjust width of first cell */ >- autoWidthAdjust: true, >- /** Automatic clean-up to ensure relationship integrity */ >- autoCleanRelations: true, >- /** Specify a number (4) as number of spaces or any indent string for JSON.stringify */ >- jsonPretifySeparator: '\t', >- /** The regular expression to use to trim row IDs */ >- serializeRegexp: /[^\-]*$/, >- /** If you want to specify another parameter name instead of the table ID */ >- serializeParamName: false, >- /** If you give the name of a class here, then only Cells with this class will be draggable */ >- dragHandle: null >- }, options || {}); >- >- // Now make the rows draggable >- $.tableDnD.makeDraggable(this); >- // Prepare hierarchy support >- this.tableDnDConfig.hierarchyLevel >- && $.tableDnD.makeIndented(this); >- }); >- >- // Don't break the chain >- return this; >- }, >- makeIndented: function (table) { >- var config = table.tableDnDConfig, >- rows = table.rows, >- firstCell = $(rows).first().find('td:first')[0], >- indentLevel = 0, >- cellWidth = 0, >- longestCell, >- tableStyle; >- >- if ($(table).hasClass('indtd')) >- return null; >- >- tableStyle = $(table).addClass('indtd').attr('style'); >- $(table).css({whiteSpace: "nowrap"}); >- >- for (var w = 0; w < rows.length; w++) { >- if (cellWidth < $(rows[w]).find('td:first').text().length) { >- cellWidth = $(rows[w]).find('td:first').text().length; >- longestCell = w; >- } >- } >- $(firstCell).css({width: 'auto'}); >- for (w = 0; w < config.hierarchyLevel; w++) >- $(rows[longestCell]).find('td:first').prepend(config.indentArtifact); >- firstCell && $(firstCell).css({width: firstCell.offsetWidth}); >- tableStyle && $(table).css(tableStyle); >- >- for (w = 0; w < config.hierarchyLevel; w++) >- $(rows[longestCell]).find('td:first').children(':first').remove(); >- >- config.hierarchyLevel >- && $(rows).each(function () { >- indentLevel = $(this).data('level') || 0; >- indentLevel <= config.hierarchyLevel >- && $(this).data('level', indentLevel) >- || $(this).data('level', 0); >- for (var i = 0; i < $(this).data('level'); i++) >- $(this).find('td:first').prepend(config.indentArtifact); >- }); >- >- return this; >- }, >- /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ >- makeDraggable: function(table) { >- var config = table.tableDnDConfig; >- >- config.dragHandle >- // We only need to add the event to the specified cells >- && $(config.dragHandle, table).each(function() { >- // The cell is bound to "this" >- $(this).bind(startEvent, function(e) { >- $.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config); >- return false; >- }); >- }) >- // For backwards compatibility, we add the event to the whole row >- // get all the rows as a wrapped set >- || $(table.rows).each(function() { >- // Iterate through each row, the row is bound to "this" >- if (! $(this).hasClass("nodrag")) { >- $(this).bind(startEvent, function(e) { >- if (e.target.tagName == "TD") { >- $.tableDnD.initialiseDrag(this, table, this, e, config); >- return false; >- } >- }).css("cursor", "move"); // Store the tableDnD object >- } else { >- $(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class >- } >- }); >- }, >- currentOrder: function() { >- var rows = this.currentTable.rows; >- return $.map(rows, function (val) { >- return ($(val).data('level') + val.id).replace(/\s/g, ''); >- }).join(''); >- }, >- initialiseDrag: function(dragObject, table, target, e, config) { >- this.dragObject = dragObject; >- this.currentTable = table; >- this.mouseOffset = this.getMouseOffset(target, e); >- this.originalOrder = this.currentOrder(); >- >- // Now we need to capture the mouse up and mouse move event >- // We can use bind so that we don't interfere with other event handlers >- $(document) >- .bind(moveEvent, this.mousemove) >- .bind(endEvent, this.mouseup); >- >- // Call the onDragStart method if there is one >- config.onDragStart >- && config.onDragStart(table, target); >- }, >- updateTables: function() { >- this.each(function() { >- // this is now bound to each matching table >- if (this.tableDnDConfig) >- $.tableDnD.makeDraggable(this); >- }); >- }, >- /** Get the mouse coordinates from the event (allowing for browser differences) */ >- mouseCoords: function(e) { >- if (e.originalEvent.changedTouches) >- return { >- x: e.originalEvent.changedTouches[0].clientX, >- y: e.originalEvent.changedTouches[0].clientY >- }; >- >- if(e.pageX || e.pageY) >- return { >- x: e.pageX, >- y: e.pageY >- }; >- >- return { >- x: e.clientX + document.body.scrollLeft - document.body.clientLeft, >- y: e.clientY + document.body.scrollTop - document.body.clientTop >- }; >- }, >- /** Given a target element and a mouse eent, get the mouse offset from that element. >- To do this we need the element's position and the mouse position */ >- getMouseOffset: function(target, e) { >- var mousePos, >- docPos; >- >- e = e || window.event; >- >- docPos = this.getPosition(target); >- mousePos = this.mouseCoords(e); >- >- return { >- x: mousePos.x - docPos.x, >- y: mousePos.y - docPos.y >- }; >- }, >- /** Get the position of an element by going up the DOM tree and adding up all the offsets */ >- getPosition: function(element) { >- var left = 0, >- top = 0; >- >- // Safari fix -- thanks to Luis Chato for this! >- // Safari 2 doesn't correctly grab the offsetTop of a table row >- // this is detailed here: >- // http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ >- // the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. >- // note that firefox will return a text node as a first child, so designing a more thorough >- // solution may need to take that into account, for now this seems to work in firefox, safari, ie >- if (element.offsetHeight == 0) >- element = element.firstChild; // a table cell >- >- while (element.offsetParent) { >- left += element.offsetLeft; >- top += element.offsetTop; >- element = element.offsetParent; >- } >- >- left += element.offsetLeft; >- top += element.offsetTop; >- >- return { >- x: left, >- y: top >- }; >- }, >- autoScroll: function (mousePos) { >- var config = this.currentTable.tableDnDConfig, >- yOffset = window.pageYOffset, >- windowHeight = window.innerHeight >- ? window.innerHeight >- : document.documentElement.clientHeight >- ? document.documentElement.clientHeight >- : document.body.clientHeight; >- >- // Windows version >- // yOffset=document.body.scrollTop; >- if (document.all) >- if (typeof document.compatMode != 'undefined' >- && document.compatMode != 'BackCompat') >- yOffset = document.documentElement.scrollTop; >- else if (typeof document.body != 'undefined') >- yOffset = document.body.scrollTop; >- >- mousePos.y - yOffset < config.scrollAmount >- && window.scrollBy(0, - config.scrollAmount) >- || windowHeight - (mousePos.y - yOffset) < config.scrollAmount >- && window.scrollBy(0, config.scrollAmount); >- >- }, >- moveVerticle: function (moving, currentRow) { >- >- if (0 != moving.vertical >- // If we're over a row then move the dragged row to there so that the user sees the >- // effect dynamically >- && currentRow >- && this.dragObject != currentRow >- && this.dragObject.parentNode == currentRow.parentNode) >- 0 > moving.vertical >- && this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling) >- || 0 < moving.vertical >- && this.dragObject.parentNode.insertBefore(this.dragObject, currentRow); >- >- }, >- moveHorizontal: function (moving, currentRow) { >- var config = this.currentTable.tableDnDConfig, >- currentLevel; >- >- if (!config.hierarchyLevel >- || 0 == moving.horizontal >- // We only care if moving left or right on the current row >- || !currentRow >- || this.dragObject != currentRow) >- return null; >- >- currentLevel = $(currentRow).data('level'); >- >- 0 < moving.horizontal >- && currentLevel > 0 >- && $(currentRow).find('td:first').children(':first').remove() >- && $(currentRow).data('level', --currentLevel); >- >- 0 > moving.horizontal >- && currentLevel < config.hierarchyLevel >- && $(currentRow).prev().data('level') >= currentLevel >- && $(currentRow).children(':first').prepend(config.indentArtifact) >- && $(currentRow).data('level', ++currentLevel); >- >- }, >- mousemove: function(e) { >- var dragObj = $($.tableDnD.dragObject), >- config = $.tableDnD.currentTable.tableDnDConfig, >- currentRow, >- mousePos, >- moving, >- x, >- y; >- >- e && e.preventDefault(); >- >- if (!$.tableDnD.dragObject) >- return false; >- >- // prevent touch device screen scrolling >- e.type == 'touchmove' >- && event.preventDefault(); // TODO verify this is event and not really e >- >- // update the style to show we're dragging >- config.onDragClass >- && dragObj.addClass(config.onDragClass) >- || dragObj.css(config.onDragStyle); >- >- mousePos = $.tableDnD.mouseCoords(e); >- x = mousePos.x - $.tableDnD.mouseOffset.x; >- y = mousePos.y - $.tableDnD.mouseOffset.y; >- >- // auto scroll the window >- $.tableDnD.autoScroll(mousePos); >- >- currentRow = $.tableDnD.findDropTargetRow(dragObj, y); >- moving = $.tableDnD.findDragDirection(x, y); >- >- $.tableDnD.moveVerticle(moving, currentRow); >- $.tableDnD.moveHorizontal(moving, currentRow); >- >- return false; >- }, >- findDragDirection: function (x,y) { >- var sensitivity = this.currentTable.tableDnDConfig.sensitivity, >- oldX = this.oldX, >- oldY = this.oldY, >- xMin = oldX - sensitivity, >- xMax = oldX + sensitivity, >- yMin = oldY - sensitivity, >- yMax = oldY + sensitivity, >- moving = { >- horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1, >- vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1 >- }; >- >- // update the old value >- if (moving.horizontal != 0) >- this.oldX = x; >- if (moving.vertical != 0) >- this.oldY = y; >- >- return moving; >- }, >- /** We're only worried about the y position really, because we can only move rows up and down */ >- findDropTargetRow: function(draggedRow, y) { >- var rowHeight = 0, >- rows = this.currentTable.rows, >- config = this.currentTable.tableDnDConfig, >- rowY = 0, >- row = null; >- >- for (var i = 0; i < rows.length; i++) { >- row = rows[i]; >- rowY = this.getPosition(row).y; >- rowHeight = parseInt(row.offsetHeight) / 2; >- if (row.offsetHeight == 0) { >- rowY = this.getPosition(row.firstChild).y; >- rowHeight = parseInt(row.firstChild.offsetHeight) / 2; >- } >- // Because we always have to insert before, we need to offset the height a bit >- if (y > (rowY - rowHeight) && y < (rowY + rowHeight)) >- // that's the row we're over >- // If it's the same as the current row, ignore it >- if (draggedRow.is(row) >- || (config.onAllowDrop >- && !config.onAllowDrop(draggedRow, row)) >- // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) >- || $(row).hasClass("nodrop")) >- return null; >- else >- return row; >- } >- return null; >- }, >- processMouseup: function() { >- if (!this.currentTable || !this.dragObject) >- return null; >- >- var config = this.currentTable.tableDnDConfig, >- droppedRow = this.dragObject, >- parentLevel = 0, >- myLevel = 0; >- >- // Unbind the event handlers >- $(document) >- .unbind(moveEvent, this.mousemove) >- .unbind(endEvent, this.mouseup); >- >- config.hierarchyLevel >- && config.autoCleanRelations >- && $(this.currentTable.rows).first().find('td:first').children().each(function () { >- myLevel = $(this).parents('tr:first').data('level'); >- myLevel >- && $(this).parents('tr:first').data('level', --myLevel) >- && $(this).remove(); >- }) >- && config.hierarchyLevel > 1 >- && $(this.currentTable.rows).each(function () { >- myLevel = $(this).data('level'); >- if (myLevel > 1) { >- parentLevel = $(this).prev().data('level'); >- while (myLevel > parentLevel + 1) { >- $(this).find('td:first').children(':first').remove(); >- $(this).data('level', --myLevel); >- } >- } >- }); >- >- // If we have a dragObject, then we need to release it, >- // The row will already have been moved to the right place so we just reset stuff >- config.onDragClass >- && $(droppedRow).removeClass(config.onDragClass) >- || $(droppedRow).css(config.onDropStyle); >- >- this.dragObject = null; >- // Call the onDrop method if there is one >- config.onDrop >- && this.originalOrder != this.currentOrder() >- && $(droppedRow).hide().fadeIn('fast') >- && config.onDrop(this.currentTable, droppedRow); >- >- this.currentTable = null; // let go of the table too >- }, >- mouseup: function(e) { >- e && e.preventDefault(); >- $.tableDnD.processMouseup(); >- return false; >- }, >- jsonize: function(pretify) { >- var table = this.currentTable; >- if (pretify) >- return JSON.stringify( >- this.tableData(table), >- null, >- table.tableDnDConfig.jsonPretifySeparator >- ); >- return JSON.stringify(this.tableData(table)); >- }, >- serialize: function() { >- return $.param(this.tableData(this.currentTable)); >- }, >- serializeTable: function(table) { >- var result = ""; >- var paramName = table.tableDnDConfig.serializeParamName || table.id; >- var rows = table.rows; >- for (var i=0; i<rows.length; i++) { >- if (result.length > 0) result += "&"; >- var rowId = rows[i].id; >- if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) { >- rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0]; >- result += paramName + '[]=' + rowId; >- } >- } >- return result; >- }, >- serializeTables: function() { >- var result = []; >- $('table').each(function() { >- this.id && result.push($.param(this.tableData(this))); >- }); >- return result.join('&'); >- }, >- tableData: function (table) { >- var config = table.tableDnDConfig, >- previousIDs = [], >- currentLevel = 0, >- indentLevel = 0, >- rowID = null, >- data = {}, >- getSerializeRegexp, >- paramName, >- currentID, >- rows; >- >- if (!table) >- table = this.currentTable; >- if (!table || !table.id || !table.rows || !table.rows.length) >- return {error: { code: 500, message: "Not a valid table, no serializable unique id provided."}}; >- >- rows = config.autoCleanRelations >- && table.rows >- || $.makeArray(table.rows); >- paramName = config.serializeParamName || table.id; >- currentID = paramName; >- >- getSerializeRegexp = function (rowId) { >- if (rowId && config && config.serializeRegexp) >- return rowId.match(config.serializeRegexp)[0]; >- return rowId; >- }; >- >- data[currentID] = []; >- !config.autoCleanRelations >- && $(rows[0]).data('level') >- && rows.unshift({id: 'undefined'}); >- >- >- >- for (var i=0; i < rows.length; i++) { >- if (config.hierarchyLevel) { >- indentLevel = $(rows[i]).data('level') || 0; >- if (indentLevel == 0) { >- currentID = paramName; >- previousIDs = []; >- } >- else if (indentLevel > currentLevel) { >- previousIDs.push([currentID, currentLevel]); >- currentID = getSerializeRegexp(rows[i-1].id); >- } >- else if (indentLevel < currentLevel) { >- for (var h = 0; h < previousIDs.length; h++) { >- if (previousIDs[h][1] == indentLevel) >- currentID = previousIDs[h][0]; >- if (previousIDs[h][1] >= currentLevel) >- previousIDs[h][1] = 0; >- } >- } >- currentLevel = indentLevel; >- >- if (!$.isArray(data[currentID])) >- data[currentID] = []; >- rowID = getSerializeRegexp(rows[i].id); >- rowID && data[currentID].push(rowID); >- } >- else { >- rowID = getSerializeRegexp(rows[i].id); >- rowID && data[currentID].push(rowID); >- } >- } >- return data; >- } >-}; >- >-jQuery.fn.extend( >- { >- tableDnD : $.tableDnD.build, >- tableDnDUpdate : $.tableDnD.updateTables, >- tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD), >- tableDnDSerializeAll : $.tableDnD.serializeTables, >- tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD) >- } >-); >- >-}(jQuery, window, window.document); >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index bde56089180..607388715f7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -4115,6 +4115,16 @@ input.renew { > } > } > >+.drag_handle { >+ cursor: move; >+ margin-right: 6px; >+} >+ >+.drag_placeholder { >+ border: 1px dotted #AAA; >+ height: 2em; >+} >+ > #manage_stages { > ul { > padding-left: 0; >@@ -4147,16 +4157,6 @@ input.renew { > background-color: #F3F3F3; > } > >- .drag_handle { >- cursor: move; >- margin-right: 6px; >- } >- >- .drag_placeholder { >- border: 1px dotted #AAA; >- height: 2em; >- } >- > h3 { > display: inline-block; > } >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >index 625afa49986..d68a5adaa2f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >@@ -9,6 +9,7 @@ > [% t("Koha") | html %] > [% END %]</title> > [% INCLUDE 'doc-head-close.inc' %] >+<link rel="stylesheet" href="/intranet-tmpl/lib/datatables/rowReorder.dataTables.min.css"> > <style> > a.add, a.delete { > cursor: pointer; >@@ -455,10 +456,12 @@ a.add, a.delete { > > [% IF index.index_name == 'biblios' %] > <h3>Facet order</h3> >- <div id="facet_[% index.index_name | html %]" class="ui-tabs-panel"> >- <table> >+ <div class="hint">Drag and drop rows to change the order</div> >+ <div id="facet_[% index.index_name | html %]"> >+ <table id="facetst"> > <thead> > <tr> >+ <th>Order</th> > <th>Search field</th> > <th>Label</th> > <th>Display</th> >@@ -467,7 +470,8 @@ a.add, a.delete { > <tbody> > [% FOREACH f IN facetable_fields %] > <tr> >- <td> >+ <td>[% loop.count | html %]</td> >+ <td class="drag_handle"> > [% f.name | html %] > </td> > <td> >@@ -526,7 +530,7 @@ a.add, a.delete { > > [% MACRO jsinclude BLOCK %] > [% INCLUDE 'datatables.inc' %] >- [% Asset.js("lib/jquery/plugins/jquery.tablednd.js") | $raw %] >+ [% Asset.js("lib/datatables/dataTables.rowReorder.min.js") | $raw %] > [% Asset.js("js/elasticsearch-mappings.js") | $raw %] > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js b/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js >index 696d8d5cf72..dd6526ce44f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js >@@ -78,9 +78,18 @@ $(document).ready(function () { > clean_line(line); > } > }); >- $("#facet_biblios > table").tableDnD({ >- onDragClass: "dragClass highlighted-row", >- }); >+ >+ $("#facetst").DataTable( >+ $.extend(true, {}, dataTablesDefaults, { >+ "columnDefs": [ >+ { "orderable": false, "searchable": false, 'targets': ['NoSort'] }, >+ { "searchable": false, "visible": false, "targets": 0 } >+ ], >+ "dom": "t", >+ "paging": false, >+ "autoWidth": false, >+ "rowReorder": true >+ })); > > $("#es_mappings").on("submit", function(e){ > let table_ids = ['search_fields_table', 'mapping_biblios_table', 'mapping_authorities_table']; >-- >2.34.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 35249
:
163598
|
163599
|
163600
|
163601
|
164795
|
164796
|
164797
|
164798