Hi there,
I have below code:
dropsGrid.table.kendoSortable({<br> filter: ">tbody >tr",<br> placeholder: $('<tr class="placeholder"><td colspan="11">Drop Here!</td></tr>'),<br> hint: function (element) {<br> var width = $('#Drops').width();<br> var table = $('<table style="width: ' + width + 'px;" class="k-grid k-widget"></table>'),<br> hint;<br><br> table.append($('#Drops .k-state-selected').clone());<br> table.css("opacity", 0.7);<br><br> return table;<br> },<br> start: function (e) {<br> if ($('#Drops .k-state-selected').length == 0) {<br> e.preventDefault();<br> } else {<br> $('#Drops .k-state-selected').hide();<br> }<br> },<br> end: function (e) {<br> $('#Drops .k-state-selected').show();<br> },<br> change: function (e) {<br> try {<br> isDropInProgress = true;<br><br> var items = this.element.find('.k-state-selected').not(e.item);<br> for (var i = 0; i < items.length; i++) {<br> console.log(items[i]);<br> $(items[i]).insertBefore(e.item).show();<br> }<br><br> var selectedSequence = $(e.item[0]).find('.row-number').text();<br> for (var i = 0; i < items.length; i++) {<br> var sequence = $(items[i]).find('.row-number').text();<br> if (Number(sequence) > Number(selectedSequence)) { <br> $(e.item).insertBefore(items[i]);<br> break;<br> }<br> }<br><br> var rows = $(dropsGrid.tbody[0]).find('tr');<br> for (var i = 0; i < rows.length; i++) {<br> var uid = $(rows[i]).data('uid');<br> var drops = dropsGrid.dataSource.data();<br> var dataItem = null;<br> for (var j = 0; j < drops.length; j++) {<br> if (drops[j].uid == uid) {<br> dataItem = drops[j];<br> break;<br> }<br> }<br> if (dataItem != null) {<br> dropsGrid.dataSource.remove(dataItem);<br> dropsGrid.dataSource.insert(i, dataItem);<br> }<br> }<br><br> } finally {<br> isDropInProgress = false;<br> isDirty = true;<br> onDataBound();<br> refreshMap(dropsGrid.dataSource._data);<br> }<br> },<br> cancel: function (e) {<br> $('#Drops .k-state-selected').show();<br> }<br> }).data("kendoSortable");With this code the user can reorder rows on a grid using drag and drop. Also "refreshMap(dropsGrid.dataSource._data);" updates the pins on a google map when the user changes the order of the rows.
Everything works as expected, but if the grid contains, lets say 80 rows and you are trying to move 3 rows at a time the performance takes a significant hit. I.e It takes between 9 to 10 seconds for the rows to drop in place.
I did some debugging around it and found that the issue is with the chunk of code below:
var rows = $(dropsGrid.tbody[0]).find('tr');<br> for (var i = 0; i < rows.length; i++) {<br> var uid = $(rows[i]).data('uid');<br> var drops = dropsGrid.dataSource.data();<br> var dataItem = null;<br> for (var j = 0; j < drops.length; j++) {<br> if (drops[j].uid == uid) {<br> dataItem = drops[j];<br> break;<br> }<br> }<br> if (dataItem != null) {<br> dropsGrid.dataSource.remove(dataItem);<br> dropsGrid.dataSource.insert(i, dataItem);<br> }<br> }I tried for the past couple of days to replace the nested for loops but without a complete successful result.
I got as far as getting the single selection to work synchronously with the map by using below code:
<code style="color: #069;font-weight: bold;">var</code> <code style="color: #000;">skip = 0,<br> oldIndex = e.oldIndex + skip,<br> newIndex = e.newIndex + skip,<br> </code><code style="color: #008200;">data = dropsGrid.dataSource.data(),<br> dataItem = dropsGrid.dataSource.getByUid(e.item.data("uid"));<br><br> console.log("------" + e.newIndex + " " + newIndex + " " + skip + " - " + e.oldIndex + " " + oldIndex + " " + skip);<br><br> dropsGrid.dataSource.remove(dataItem);<br> dropsGrid.dataSource.insert(newIndex, dataItem);</code>but I am loosing the multiple selection functionality.
By using below code:
start: function (e) {<br> if ($('.k-state-selected').length === 0) {<br> e.preventDefault();<br> } else {<br> $('.k-state-selected').hide();<br> }<br> },<br> end: function (e) {<br> <br> $('.k-state-selected').show();<br> },<br> change: function (e) {<br> try {<br> isDropInProgress = true;<br><br> console.time("whole drop");<br><br> var items = this.element.find('.k-state-selected').not(e.item);<br> for (var i = 0; i < items.length; i++) {<br> console.log(items[i]);<br> $(items[i]).insertBefore(e.item).show();<br> }<br><br> var selectedSequence = $(e.item[0]).find('.row-number').text();<br> for (var i = 0; i < items.length; i++) {<br> var sequence = $(items[i]).find('.row-number').text();<br> if (Number(sequence) > Number(selectedSequence)) { <br> $(e.item).insertBefore(items[i]);<br> break;<br> }<br> }<br><br> $('.k-state-selected').removeClass("state-selected");<br><br> console.timeEnd("whole drop");<br> } finally {<br> isDropInProgress = false;<br> isDirty = true;<br> onDataBound();<br> refreshMap(dropsGrid.dataSource._data);<br> }<br> },<br> cancel: function (e) {<br> $('.k-state-selected').show();<br> } <br> }).data("kendoSortable");<br><br> testDrop.draggable.userEvents.bind("tap", function (e) {<br> if (e.event.ctrlKey) {<br> e.target.toggleClass("state-selected");<br> } else {<br> $('.k-state-selected').removeClass("state-selected");<br> e.target.addClass("state-selected");<br> }<br> });multiple and single selection works but the pins on the map are not updating anymore.
Another issue with the above approach is that when I move, lets say, two rows from position 1 and 2 under row 5 I am getting following behavior:
- the 2 rows that I moved are selected (expected behavior)
- the rows that replaced position 1 and 2 are also selected (unwanted behavior, as this creates confusion)
As I spent couple of days already on this issue I was wondering if you can, please, help with an example or some guidance in order to resolve the issue.
I am looking forward to hearing from you!
Thank you