PDA

View Full Version : [CLOSED] MVC Razor example of drag and drop?



ATLAS
Jul 16, 2013, 10:24 AM
I need to add drag and drop functionality liberally within my site. Is there a working example of of MVC Razor DnD using (presumably) DropZone and DropTarget?

I've tried porting the Hospital/Patient example to MVC (Razor) but hit an issue with the GetTargetFromEvent in the DropZone as the MVC component does not seem to have an equivalent method.

Daniil
Jul 16, 2013, 3:37 PM
Hi @ATLAS,

There is no a Razor builder for the DropZone class. It is a bug. Thank you for the report!

Fixed in the SVN trunk. Please update.

Also we implemented the example that you mentioned with Razor.

It will go to the MVC Examples Explorer of the upcoming v2.3 release.

Index.cshtml

@model Ext.Net.MVC.Examples.Areas.DragDrop_Advanced.Model s.Example3Model

@{
ViewBag.Title = "Drag&Drop - Ext.NET MVC Examples";
Layout = "~/Views/Shared/_BaseLayout.cshtml";
var X = Html.X();
}

@section headtag
{
<style>
.app-header .x-panel-body {
background-color: #ddd;
padding-left: 5px;
}

.app-header h1 {
font-family: verdana,arial,sans-serif;
font-size: 20px;
color: #15428B;
}

.hospital-target {
border: 1px solid red;
margin: 5px;
padding: 5px;
font-size: small;
cursor: default;
}

.hospital-target.hospital-target-hover {
background-color: #C0C0C0;
}

.patient-source {
cursor: pointer;
}

.patient-view table {
border-collapse: separate;
border-spacing: 2px;
}

.patient-view td {
font-family: verdana,arial,sans-serif;
font-size: 12px;
}

td.patient-label {
background-color: #ddd;
border: 1px solid #bbb;
font-weight: bold;
text-align: right;
width: 100px;
padding: 0px 3px 0px 0px;
}

.patient-over {
background-color: #EFEFEF;
cursor: pointer;
}

.patient-selected {
background-color: #DFE8F6;
cursor: pointer;
}
</style>

<script>
/*
* Here is where we "activate" the DataView.
* We have decided that each node with the class "patient-source" encapsulates a single draggable
* object.
*
* So we inject code into the DragZone which, when passed a mousedown event, interrogates
* the event to see if it was within an element with the class "patient-source". If so, we
* return non-null drag data.
*
* Returning non-null drag data indicates that the mousedown event has begun a dragging process.
* The data must contain a property called "ddel" which is a DOM element which provides an image
* of the data being dragged. The actual node clicked on is not dragged, a proxy element is dragged.
* We can insert any other data into the data object, and this will be used by a cooperating DropZone
* to perform the drop operation.
*/


// On receipt of a mousedown event, see if it is within a draggable element.
// Return a drag data object if so. The data object can contain arbitrary application
// data, but it should also contain a DOM element in the ddel property to provide
// a proxy to drag.
var getDragData = function (e) {
var view = App.PatientView,
sourceEl = e.getTarget(view.itemSelector, 10);

if (sourceEl) {
d = sourceEl.cloneNode(true);
d.id = Ext.id();

return (view.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d,
patientData: view.getRecord(sourceEl).data
});
}
};

// Provide coordinates for the proxy to slide back to on failed drag.
// This is the original XY coordinates of the draggable element.
var getRepairXY = function () {
return this.dragData.repairXY;
};




/*
* Here is where we "activate" the GridPanel.
* We have decided that the element with class "hospital-target" is the element which can receieve
* drop gestures. So we inject a method "getTargetFromEvent" into the DropZone. This is constantly called
* while the mouse is moving over the DropZone, and it returns the target DOM element if it detects that
* the mouse if over an element which can receieve drop gestures.
*
* Once the DropZone has been informed by getTargetFromEvent that it is over a target, it will then
* call several "onNodeXXXX" methods at various points. These include:
*
* onNodeEnter
* onNodeOut
* onNodeOver
* onNodeDrop
*
* We provide implementations of each of these to provide behaviour for these events.
*/


// If the mouse is over a target node, return that node. This is
// provided as the "target" parameter in all "onNodeXXXX" node event handling functions
var getTargetFromEvent = function (e) {
return e.getTarget(".hospital-target");
};


// On entry into a target node, highlight that node.
var onNodeEnter = function (target, dd, e, data) {
Ext.fly(target).addCls("hospital-target-hover");
};


// On exit from a target node, unhighlight that node.
var onNodeOut = function (target, dd, e, data) {
Ext.fly(target).removeCls("hospital-target-hover");
};


// While over a target node, return the default drop allowed class which
// places a "tick" icon into the drag proxy.
var onNodeOver = function (target, dd, e, data) {
return Ext.dd.DropZone.prototype.dropAllowed;
};


// On node drop, we can interrogate the target node to find the underlying
// application object that is the real target of the dragged data.
// In this case, it is a Record in the GridPanel's Store.
// We can use the data set up by the DragZone's getDragData method to read
// any data we decided to attach.
var onNodeDrop = function (target, dd, e, data) {
var rowBody = Ext.fly(target).findParent('.x-grid-rowbody-tr', null, false),
mainRow = rowBody.previousSibling,
h = App.HospitalGrid.getView().getRecord(mainRow),
targetEl = Ext.get(target),
html = targetEl.dom.innerHTML;

if (html == 'Drop Patient Here') {
html = data.patientData.Name;
} else {
html = data.patientData.Name + ', ' + targetEl.dom.innerHTML;
}

targetEl.update(html);
Ext.Msg.alert('Drop gesture', 'Dropped patient ' + data.patientData.Name +
' on hospital ' + h.data.Name);
return true;
};
</script>
}

@section example
{
@(X.Viewport()
.Layout("border")
.Items(
X.Container()
.Cls("app-header")
.Height(30)
.Region(Region.North)
.Html("<h1>Patient Hospital Assignment</h1>")
.Margins("5"),

X.Panel()
.Title("Patients")
.Width(300)
.Region(Region.West)
.Margins("0 5 5 5")
.Items(
X.DataView()
.ID("PatientView")
.Cls("patient-view")
.OverItemCls("patient-over")
.SelectedItemCls("patient-selected")
.SimpleSelect(true)
.ItemSelector("div.patient-source")
.Store(X.Store()
.ID("PatientStore")
.Model(X.Model()
.IDProperty("InsuranceCode")
.Fields("Name", "Address", "Telephone")
)
.DataSource(Model.Patients)
)
.Tpl(X.XTemplate()
.Html(@<text>
<tpl for=".">
<div class="patient-source">
<table>
<tbody>
<tr>
<td class="patient-label">Name</td>
<td class="patient-name">{Name}</td>
</tr>
<tr>
<td class="patient-label">Address</td>
<td class="patient-name">{Address}</td>
</tr>
<tr>
<td class="patient-label">Telephone</td>
<td class="patient-name">{Telephone}</td>
</tr>
</tbody>
</table>
</div>
</tpl>
</text>)
)
),

X.GridPanel()
.ID("HospitalGrid")
.Title("Hospitals")
.Region(Region.Center)
.Margins("0 5 5 0")
.Store(X.Store()
.ID("HospitalStore")
.Model(X.Model()
.IDProperty("Code")
.Fields("Name", "Address", "Telephone")
)
.DataSource(Model.Hospitals)
)
.ColumnModel(
X.Column().DataIndex("Name").Text("NAME").Width(200),
X.Column().DataIndex("Address").Text("Address").Width(300),
X.Column().DataIndex("Telephone").Text("Telephone").Width(100)
)
.Features(
X.RowBody()
.CustomConfig(cc => cc.Add(new { rowBodyDivCls = "hospital-target"}))
.GetAdditionalData("return {rowBody: 'Drop Patient Here', rowBodyDivCls:'hospital-target'};")
)
)
)

@(X.DragZone()
.Target("={#{PatientView}.getEl()}")
.GetDragData(h => h.Fn = "getDragData")
.GetRepairXY(h => h.Fn = "getRepairXY")
)

@(X.DropZone()
.Target("={#{HospitalGrid}.getView().el}")
.GetTargetFromEvent(h => h.Fn = "getTargetFromEvent")
.OnNodeEnter(h => h.Fn = "onNodeEnter")
.OnNodeOut(h => h.Fn = "onNodeOut")
.OnNodeOver(h => h.Fn = "onNodeOver")
.OnNodeDrop(h => h.Fn = "onNodeDrop")
)
}

Example3Model.cs

using System.Collections.Generic;

namespace Ext.Net.MVC.Examples.Areas.DragDrop_Advanced.Model s
{
public class Example3Model
{
public IEnumerable<object> Patients
{
get
{
return new List<object>
{
new { InsuranceCode="11111", Name="Fred Bloggs", Address="Main Street", Telephone="555 1234 123" },
new { InsuranceCode="22222", Name="Fred West", Address="Cromwell Street", Telephone="666 666 666" },
new { InsuranceCode="33333", Name="Fred Mercury", Address="Over The Rainbow", Telephone="555 321 0987" },
new { InsuranceCode="44444", Name="Fred Forsyth", Address="Blimp Street", Telephone="555 111 2222" },
new { InsuranceCode="55555", Name="Fred Douglass", Address="Talbot County, Maryland", Telephone="N/A" }
};
}
}

public IEnumerable<object> Hospitals
{
get
{
return new List<object>
{
new { Code="AAAAA", Name="Saint Thomas", Address="Westminster Bridge Road, SE1 7EH", Telephone="020 7188 7188" },
new { Code="BBBBB", Name="Queen's Medical Centre", Address="Derby Road, NG7 2UH", Telephone="0115 924 9924" },
new { Code="CCCCC", Name="Saint Bartholomew", Address="West Smithfield, EC1A 7BE", Telephone="020 7377 7000" },
new { Code="DDDDD", Name="Royal London", Address="Whitechapel, E1 1BB", Telephone="020 7377 7000" }
};
}
}
}
}

Example3Controller.cs

using System.Web.Mvc;
using Ext.Net.MVC.Examples.Areas.DragDrop_Advanced.Model s;

namespace Ext.Net.MVC.Examples.Areas.DragDrop_Advanced.Contr ollers
{
public class Example3Controller : Controller
{
public ActionResult Index()
{
return View(new Example3Model());
}
}
}

ATLAS
Jul 16, 2013, 4:13 PM
Hi @ATLAS,

There is no a Razor builder for the DropZone class. It is a bug. Thank you for the report!

Fixed in the SVN trunk. Please update.

Also we implemented the example that you mentioned with Razor.

It will go to the MVC Examples Explorer of the upcoming v2.3 release.

[

Hi Daniil,
I have just updated from SVN and used the example ......... it works! Thank you and mark this as closed please.