Hi FabrÃ*cio,
thank you for your prompt reply. Before I opened this thread, I went through available examples and spent many hours trying different scenarios. Here is one based on the example you mentioned:
@using Ext.Net;
@using Ext.Net.MVC;
@{
ViewBag.Title = "Desktop Drag & Drop Example";
Layout = null;
var X = Html.X();
List<MenuItem> startMenu = new List<Ext.Net.MenuItem>();
startMenu.Add(new Ext.Net.MenuItem() { ID = "EU", Icon = Icon.FlagEuropeanunion, Text = "European Union" });
startMenu.Add(new Ext.Net.MenuItem() { ID = "US", Icon = Icon.FlagUs, Text = "United States" });
}
<!DOCTYPE html>
<html>
<head>
<title>Ext.NET MVC Test Case</title>
<style>
.dropOK {
background-color: #99ff99 !important;
}
.dropNotOK {
border: 1px solid #FF0000 !important;
}
</style>
<script type="text/javascript">
Ext.onReady(function () {
console.log("onReady");
console.log("EU", Ext.getCmp("EU"));
console.log("dataview-1030", Ext.getCmp("dataview-1030"));
});
function desktopReady() {
console.log("desktopReady");
console.log("EU", Ext.getCmp("EU"));
console.log("dataview-1030", Ext.getCmp("dataview-1030"));
}
Ext.ns("App").ddOverrides = {
// Called the instant the element is dragged.
startDrag: function () {
console.log("startDrag");
// Cache the drag "phantom" element
if (!this.dEl) {
this.dEl = Ext.get(this.getDragEl());
}
// Cache the original element
if (!this.el) {
this.el = Ext.get(this.getEl());
}
// Make the original icon less visible to indicate it is really about to be moved
this.el.applyStyles({ opacity: 0.4 });
this.dEl.applyStyles({
border: "",
// Trim the sides to 8 pixels to have it match the icons
width: (this.el.getWidth() - 8) + "px",
height: (this.el.getHeight() - 8) + "px",
"z-index": 2000
});
// Create an exact copy of the element on the cursor
this.dEl.update(this.el.dom.innerHTML);
// adding this class is the trick to have drop areas to work
// If you just avoid this and then use this.el.dom.outerHTML above, the mouse will
// be always above the div and will never trigger an dropEnter event.
this.dEl.addCls(this.el.dom.className);
this.lastTarget = null;
},
// Called when the drag operation completes
endDrag: function () {
console.log("endDrag");
// Create the animation configuration object
var animCfgObj = {
easing: 'ease',
duration: 500,
opacity: 1,
scope: this,
};
// Invoke the animation according to the drop success/failure
if (this.lastTarget == null) {
// After dragging, remove transparency effect of moved element.
this.el.animate(animCfgObj);
} else {
// Remove the drop invitation
this.el.removeCls('dropOK');
// Get exact position where the drag-dropped item were released
var destXY = this.dEl.getXY();
animCfgObj.callback = function () {
// Remove the position attribute
this.el.dom.style.position = '';
// Finally, add the item to the target div
Ext.get(this.lastTarget).appendChild(this.el);
};
// animate icon to where the mouse dropped it
this.el.setXY([destXY[0], destXY[1]], animCfgObj);
}
},
// Only called when the drag element is dragged over the a drop target with the same ddgroup
onDragEnter: function (evtObj, targetElId) {
console.log("onDragEnter");
// Colorize the drag target if the drag node's parent is not the same as the drop target
// and is valid for the car type
if (targetElId != this.el.dom.parentNode.id) {
this.el.addCls('dropOK');
this.dEl.addCls('dropOK');
this.lastTarget = Ext.get(targetElId);
} else {
// Remove the invitation
this.onDragOut();
this.lastTarget = null;
}
},
// Only called when element is dragged out of a dropzone with the same ddgroup
onDragOut: function (evtObj, targetElId) {
console.log("onDragOut");
this.el.removeCls('dropOK');
this.dEl.removeCls('dropOK');
this.lastTarget = null;
},
onDrop: function (evtObj, targetElId) {
console.log("onDrop");
}
};
</script>
</head>
<body>
@Html.X().ResourceManager()
@(Html.X().Desktop()
.ID("_nelisDesktop").Listeners(l => l.Ready.Fn = "desktopReady")
.DesktopConfig(
Html.X().DesktopConfig()
.SortShortcuts(true)
.WallpaperStretch(true)
.ShortcutDragSelector(true)
)
.StartMenu(
Html.X().DesktopStartMenu()
.ID("_nelisDesktop_StartMenu")
.Title("Allegro Desktop")
.Icon(Icon.Application)
.MenuItems(startMenu)
.ToolConfig(
Html.X().Toolbar()
.Width(100)
.Items(
Html.X().Button()
.Icon(Icon.Calculator)
.Text("Calculator")
)
)
)
.TaskBar(
Html.X().DesktopTaskBar()
.TrayWidth(40)
.QuickStartWidth(75)
.QuickStart(
Html.X().Toolbar()
.Items(
Html.X().Button()
.Icon(Icon.ApplicationTileVertical)
.ToolTip("Tile windows")
.OverflowText("Tile windows"),
Html.X().Button()
.Icon(Icon.ApplicationCascade)
.ToolTip("Cascade windows")
.OverflowText("Cascade windows"),
Html.X().Button()
.Icon(Icon.ApplicationViewIcons)
.ToolTip("Default icons positions")
)
)
)
.Modules(
Html.X().DesktopModule().ModuleID("Notepad").Shortcut(new DesktopShortcut { Name = "Notepad", IconCls = "x-notepad-shortcut" })
)
)
@(X.DDProxy()
.Target("EU")
.Group("desktopDD")
.IsTarget(false)
.StartDrag(a => a.Fn = "App.ddOverrides.startDrag")
.EndDrag(a => a.Fn = "App.ddOverrides.endDrag")
.OnDragEnter(a => a.Fn = "App.ddOverrides.onDragEnter")
.OnDragOut(a => a.Fn = "App.ddOverrides.onDragOut")
)
@(X.DDProxy()
.Target("US")
.Group("desktopDD")
.IsTarget(false)
.StartDrag(a => a.Fn = "App.ddOverrides.startDrag")
.EndDrag(a => a.Fn = "App.ddOverrides.endDrag")
.OnDragEnter(a => a.Fn = "App.ddOverrides.onDragEnter")
.OnDragOut(a => a.Fn = "App.ddOverrides.onDragOut")
)
@(X.DropZone().Target("dataview-1030").Group("desktopDD").NotifyDrop(a => a.Fn = "App.ddOverrides.onDrop").OnDragDrop(a => a.Fn = "App.ddOverrides.onDrop"))
</body>
</html>
Unfortunately, it does not work, events are triggered differently than I would expect and dragged item cannot be dropped. I also have problem to specify target for drop zone, as pointing to '_nelisDesktop' does not work because no component with such ID is rendered.
But even your example does not work:
http://mvc4.ext.net/#/DragDrop_Basic/Dom/
I copied the code in my project and found out that the events did not work the same way as in my test case and a car cannot be dropped:
@using Ext.Net;
@using Ext.Net.MVC;
@{
ViewBag.Title = "Drag and Drop with DOM Elements - Ext.NET MVC Examples";
Layout = null;
var X = Html.X();}
<!DOCTYPE html>
<html>
<head>
<title>Ext.NET MVC Test Case</title>
<style>
body {
padding: 10px;
}
.availableLot {
width: 103px;
border: 1px solid #999999;
padding: 10px;
height: 310px;
margin: 10px;
-moz-border-radius: 17px;
-webkit-border-radius: 17px;
border-radius: 17px;
}
.rented, .repair {
width: 195px;
}
.vehicleIcon {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
width: 85px;
border: 1px solid #666666;
padding: 3px;
background-color: #FFFFFF;
margin: 5px;
cursor: move;
text-align: center;
}
#cars div, #trucks div {
margin: 5px;
width: 85px;
}
#repair div, #rented div {
float: left;
margin: 2px;
}
.imgThumb {
position: relative;
top: 2px;
height: 57px;
width: 77px;
border: 1px solid #777777;
}
.dropOK {
background-color: #99ff99 !important;
}
.dropNotOK {
border: 1px solid #FF0000 !important;
}
</style>
<script type="text/javascript">
Ext.ns("App").ddOverrides = {
// Called the instant the element is dragged.
startDrag: function () {
console.log("startDrag");
// Cache the drag "phantom" element
if (!this.dEl) {
this.dEl = Ext.get(this.getDragEl());
}
// Cache the original element
if (!this.el) {
this.el = Ext.get(this.getEl());
}
// Make the original icon less visible to indicate it is really about to be moved
this.el.applyStyles({ opacity: 0.4 });
this.dEl.applyStyles({
border: "",
// Trim the sides to 8 pixels to have it match the icons
width: (this.el.getWidth() - 8) + "px",
height: (this.el.getHeight() - 8) + "px",
"z-index": 2000
});
// Create an exact copy of the element on the cursor
this.dEl.update(this.el.dom.innerHTML);
// adding this class is the trick to have drop areas to work
// If you just avoid this and then use this.el.dom.outerHTML above, the mouse will
// be always above the div and will never trigger an dropEnter event.
this.dEl.addCls(this.el.dom.className);
this.lastTarget = null;
},
// Called when the drag operation completes
endDrag: function () {
console.log("endDrag");
// Create the animation configuration object
var animCfgObj = {
easing: 'ease',
duration: 500,
opacity: 1,
scope: this,
};
// Invoke the animation according to the drop success/failure
if (this.lastTarget == null) {
// After dragging, remove transparency effect of moved element.
this.el.animate(animCfgObj);
} else {
// Remove the drop invitation
this.el.removeCls('dropOK');
// Get exact position where the drag-dropped item were released
var destXY = this.dEl.getXY();
animCfgObj.callback = function () {
// Remove the position attribute
this.el.dom.style.position = '';
// Finally, add the item to the target div
Ext.get(this.lastTarget).appendChild(this.el);
};
// animate icon to where the mouse dropped it
this.el.setXY([destXY[0], destXY[1]], animCfgObj);
}
},
// Only called when the drag element is dragged over the a drop target with the same ddgroup
onDragEnter: function (evtObj, targetElId) {
console.log("onDragEnter");
var vehicleAllowed = true;
// Determine if currently selected car type is allowed in the drop area
if ((this.el.id.indexOf("truck") == 0 && targetElId == "cars") ||
(this.el.id.indexOf("car") == 0 && targetElId == "trucks")) {
vehicleAllowed = false;
};
// Colorize the drag target if the drag node's parent is not the same as the drop target
// and is valid for the car type
if (targetElId != this.el.dom.parentNode.id && vehicleAllowed) {
this.el.addCls('dropOK');
this.dEl.addCls('dropOK');
this.lastTarget = Ext.get(targetElId);
} else {
// Remove the invitation
this.onDragOut();
this.lastTarget = null;
}
},
// Only called when element is dragged out of a dropzone with the same ddgroup
onDragOut: function (evtObj, targetElId) {
console.log("onDragOut");
this.el.removeCls('dropOK');
this.dEl.removeCls('dropOK');
this.lastTarget = null;
}
};
</script>
</head>
<body>
<table class="x-unselectable">
<tr>
<td>
<table>
<tr>
<td align='center'>
Available Cars
</td>
<td align='center'>
Available Trucks
</td>
</tr>
<tr>
<td>
<div id="cars" class="availableLot">
<div id="carCamaro" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/camaro.jpg")" class="imgThumb" qtip="Camaro" /></div>
<div id="carMiata" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/miata.jpg")" class="imgThumb" qtip="Miata" /></div>
<div id="carMustang" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/mustang.jpg")" class="imgThumb" qtip="Mustang" /></div>
<div id="carCorvette" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/corvette.jpg")" class="imgThumb" qtip="Corvette" /></div>
</div>
</td>
<td>
<div id="trucks" class="availableLot trucksLot">
<div id="truckF150" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/f150.jpg")" class="imgThumb" qtip="F150" /></div>
<div id="truckTahoe" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/tahoe.jpg")" class="imgThumb" qtip="Tahoe" /></div>
<div id="truckTacoma" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/tacoma.jpg")" class="imgThumb" qtip="Tacoma" /></div>
<div id="truckS10" class="vehicleIcon"><img src="http://mvc4.ext.net/Areas/DragDrop_Basic/Content/images/s10.jpg")" class="imgThumb" qtip="S10" /></div>
</div>
</td>
</tr>
</table>
</td>
<td align='center' style="width: 200px;">
<table>
<tr>
<td align='center' style="width: 200px;">
Vehicles Rented
</td>
<td align='center' style="width: 200px;">
Vehicles In Repair
</td>
</tr>
<tr style="">
<td style="">
<div id="rented" class="availableLot rented"></div>
</td>
<td>
<div id="repair" class="availableLot repair"></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
@Html.X().ResourceManager()
@* Set as drag zones on every item inside both the cars and trucks divs *@
@(X.DDProxy()
.Target("${#cars div}")
.Group("carsDDGroup")
.IsTarget(false)
.StartDrag(a => a.Fn = "App.ddOverrides.startDrag")
.EndDrag(a => a.Fn = "App.ddOverrides.endDrag")
.OnDragEnter(a => a.Fn = "App.ddOverrides.onDragEnter")
.OnDragOut(a => a.Fn = "App.ddOverrides.onDragOut")
)
@(X.DDProxy()
.Target("${#trucks div}")
.Group("carsDDGroup")
.IsTarget(false)
.StartDrag(a => a.Fn = "App.ddOverrides.startDrag")
.EndDrag(a => a.Fn = "App.ddOverrides.endDrag")
.OnDragEnter(a => a.Fn = "App.ddOverrides.onDragEnter")
.OnDragOut(a => a.Fn = "App.ddOverrides.onDragOut")
)
@* Set as drop zones both 'rented' and 'repair' divs *@
@(X.DropZone().Target("rented").Group("carsDDGroup"))
@(X.DropZone().Target("repair").Group("carsDDGroup"))
@* Set drop zones on cars and trucks divs (they're specially treated to allow correct items back) *@
@(X.DropZone().Target("cars").Group("carsDDGroup"))
@(X.DropZone().Target("trucks").Group("carsDDGroup"))
</body>
</html>
Can you please help me with the right solution? Thank you.
Dan