Reputation: 1
I've created a nice little KendoUI grid with drag and drop. It works great... as long as I have the developer tools open. Any idea why this would work with the dev tools open, but doesn't work at all with just using the browser?
Edit to add the code:
my cshtml page:
<div id="DisplayOrderGridContainer">
<div class="validation-error-box" id="errorMessages" style="display:none">
<span>Error!</span>
<ul id="message">
<li>The Record you attempted to edit was modified by another user after you got the original value. The edit operation was canceled.</li>
</ul>
</div>
<div style="padding-bottom: 15px;">
@Html.ActionLink("Back", Model.BackActionName, Model.ControllerName, Model.BackRouteValues, new { id = Model.ControllerName + "_Back", @class = "k-button" })
@if (Model.AllowClearingDisplayOrder)
{
@Html.ActionLink("Clear Order", Model.ClearActionName, Model.ControllerName, Model.BackRouteValues, new { @id = "clear-button", @class = "k-button float-right" })
}
</div>
<div id="KendoGridContainer">
<div id="ChangeDisplayOrderGrid"
class="grid"
data-role="grid"
data-bind="source:data, events:{dataBound:onDataBound,columnHide:OnColumnHide,columnShow:OnColumnShow}"
data-filterable="false"
data-sortable="false"
data-column-menu="true"
data-row-template="rowTemplate"
@*data-toolbar='[{ "template": kendo.template($("#toolbarTemplate").html()) }]'*@
data-columns='[{title:"Short Name", field:"NameField", width: 80, headerAttributes:{id: "@Model.ControllerName" + "_ShortName"}},
{title:"Description", field:"DescriptionField", width:300, headerAttributes:{id: "@Model.ControllerName" + "_Description"}},
{title:"Display Order", field:"Display", width:140, headerAttributes:{id: "@Model.ControllerName" + "_Display"}},
{title:"Value", field:"Value", hidden: true, headerAttributes:{id: "@Model.ControllerName" + "_Value"}}]'>
</div>
<script id="rowTemplate" type="text/x-kendo-tmpl">
<tr class="k-master-row" data-uid="#:uid#">
<td class="text-right">#=NameField#</td>
<td class="text-right">#=DescriptionField#</td>
<td class="text-right">#=Display#</td>
<td class="text-right" style="display:none;">#=Value#</td>
</tr>
</script>
<div id="grid" data-grid-url="@(Url.Action(Model.ActionName, Model.ControllerName))" data-grid-viewdataid="@ViewData.ID()"></div>
</div>
<input type="hidden" id="displayOrderId" />
<input type="hidden" id="Id" />
my js page:
$(document).ready(function () {
UnsavedWarningsModule.ClearUnsavedChanges();
var newData = new kendo.data.DataSource({
transport: {
read: {
url: $('#grid').attr('data-grid-url'),
dataType: "json"
}
},
schema: {
model: {
id: "Id"
}
}
})
var viewModel = new kendo.observable({
data: newData,
onDataBound: function (e) {
pfsKendoGridEvents.SetSelectedRow_MVVMGrid("KendoGridContainer", e.sender, $('#grid').attr('data-grid-viewdataId'))
},
OnColumnHide: function (e) {
pfsKendoGridEvents.OnHideShowColumns(e);
},
OnColumnShow: function (e) {
pfsKendoGridEvents.OnHideShowColumns(e);
}
});
kendo.bind($("#DisplayOrderGridContainer"), viewModel);
kendo.addDragAndDropToGrid = function (gridId, rowClass, viewModel) {
if (!gridId) { throw "Parameter [gridId] is not set."; }
if (!rowClass) { throw "Parameter [rowClass] is not set."; }
$(rowClass).kendoDraggable({
hint: function (element) {
var shortName = element[0].cells[0].firstChild.data;
var desc = element[0].cells[1].firstChild.data;
var dispOrder = element[0].cells[2].firstChild.data;
element[0].innerHTML = "<td class=\"text-right dragOver\" style=\"width:95px\">" + shortName + "</td><td class=\"text-right dragOver\" style=\"width:382px\">" + desc + "</td><td class=\"text-right dragOver\" style=\"width:173px\">" + dispOrder + "</td>";
return element;
},
axis: "y",
container: $(gridId)
});
$(gridId).kendoDropTargetArea({
filter: rowClass,
drop: function (e) {
var srcUid = e.draggable.element.data("uid");
var tgtUid = e.dropTarget.data("uid");
var ds = $(gridId).data("kendoGrid").dataSource;
var srcItem = ds.getByUid(srcUid);
var tgtItem = ds.getByUid(tgtUid);
var dstIdx = ds.indexOf(tgtItem);
ds.remove(srcItem);
ds.insert(dstIdx, srcItem);
e.draggable.destroy();
UnsavedWarningsModule.SetUnsavedChanges();
kendo.addDragAndDropToGrid(gridId, rowClass, viewModel);
},
dragenter: function (e) {
e.draggable.hint.css("opacity", 0.3);
},
dragleave: function (e) {
e.draggable.hint.css("opacity", 1);
var srcUid = e.draggable.element.data("uid");
var tgtUid = e.dropTarget.data("uid");
var ds = $(gridId).data("kendoGrid").dataSource;
var srcItem = ds.getByUid(srcUid);
var srcDispOrd = srcItem.Display;
var tgtItem = ds.getByUid(tgtUid);
var tgtDispOrd = tgtItem.Display;
var dstIdx = ds.indexOf(tgtItem);
//--update display orders after dropping
ds._data.forEach(function (data) {
//if dragging it to a spot with higher dispOrder
if (tgtDispOrd > srcDispOrd) {
if (data.Display <= tgtDispOrd && data.Display > srcDispOrd) {
data.Display -= 1;
}
}
//if dragging it to a spot with lower dispOrder
if (srcDispOrd > tgtDispOrd) {
if (data.Display >= tgtDispOrd && data.Display < srcDispOrd) {
data.Display += 1;
}
}
});
srcItem.Display = tgtDispOrd;
//--end
ds.remove(srcItem);
ds.insert(dstIdx, srcItem);
}
});
};
var dataService = (function () {
"use strict";
var self = {};
self.getAddresses = function () {
var data = new kendo.data.ObservableArray([newData]);
// Manual create a promise, so this function mimicks an Ajax call.
var dfd = new $.Deferred();
dfd.resolve(data);
return dfd.promise();
};
return self;
})(kendo);
var controller = (function (dataService, viewModel) {
"use strict";
var _dataService = dataService;
var _vm = viewModel;
var self = {};
self.handleAddressesRefresh = function (data) {
_vm.set("addresses", new kendo.data.DataSource({ data: data }));
kendo.bind($("#KendoGridContainer"), _vm);
kendo.addDragAndDropToGrid("#ChangeDisplayOrderGrid", ".k-master-row", _vm);
};
self.show = function () {
$.when(_dataService.getAddresses())
.then(self.handleAddressesRefresh);
};
return self;
})(dataService, viewModel);
controller.show();});
I think it's something to do with the timing of the loading of the page, possibly with the promise I'm using?
Thanks!
Upvotes: 0
Views: 275