PDA

View Full Version : [CLOSED] Drag and drop design and issues



ATLAS
Oct 08, 2014, 3:09 PM
Hi Guys,
I'd like to implement a drag and drop scenario like this.

1) There can be 1 ... n source panels(fieldsets).
2) There are two destinations.
3) Items dragged from any source can be dropped on any of the two destinations.
4) An item in a destination can only be dragged back to it's original source.

Any assistance with a solution would be appreciated. I'm using MVC Razor.

I've looked at Drag and Drop Basic Example 2 as a starting point but I get an exception of "System.Exception: AddTo mode can be applied to only a AbstractComponent" at the following line.



sb.Append(dz.ToScript());


Any clues what the issue might be?

Daniil
Oct 08, 2014, 7:36 PM
Hi @ATLAS,

I don't think we have such an example. Though the first three items should not be a problem to implement.

As for #4, you should save the source of the dropped thing to check it on further drag&drop operations.


System.Exception: AddTo mode can be applied to only a AbstractComponent"

In other words, the Exception states that the AddTo mode is used for non-Ext.NET content. For example, for raw HTML.

ATLAS
Oct 08, 2014, 8:01 PM
Thanks Daniil, I have a go at it. On the last point (exception), I copied and pasted the example code into my own test cshtml so don't understand why it is throwing the exception at all. It looks like :-



@using System.Text
@using Ext.Net.Utilities

@using CAMS.NLS.Resources
@using CAMS.Web.UI.ViewModels
@using CAMS.Web.UI.ViewHelpers
@using Panel = Ext.Net.Panel


@{
GridMessageItem vm = Page.model;
}

<style type="text/css">
body {
font-size : 11px;
}

.dd-ct {
position :absolute;
border : 1px solid silver;
width : 180px;
height : 180px;
top : 40px;
background-color : #ffffc0;
}

#dd1-ct {
left : 64px;
}

#dd2-ct {
left : 256px;
}

.dd-item {
height : 18px;
border : 1px solid #a0a0a0;
background-color : #c4d0ff;
vertical-align : middle;
cursor : move;
padding : 2px;
z-index : 1000;
}

.dd-ct .dd-item {
margin : 2px;
}

.dd-proxy {
opacity : 0.4;
-moz-opacity : 0.4;
filter : alpha(opacity=40);
}

.dd-over {
background-color : #ffff60;
}
</style>

<script>
var startDrag = function (x, y) {
var dragEl = Ext.get(this.getDragEl());
var el = Ext.get(this.getEl());

dragEl.applyStyles({border:"","z-index":2000});
dragEl.update(el.dom.innerHTML);
dragEl.addCls(el.dom.className + " dd-proxy");
};

var onDragOver = function (e, targetId) {
if ("dd1-ct" === targetId || "dd2-ct" === targetId) {
var target = Ext.get(targetId);
this.lastTarget = target;
target.addCls("dd-over");
}
};

var onDragOut = function (e, targetId) {
if ("dd1-ct" === targetId || "dd2-ct" === targetId) {
var target = Ext.get(targetId);
this.lastTarget = null;
target.removeCls("dd-over");
}
};

var endDrag = function () {
var dragEl = Ext.get(this.getDragEl()),
el = Ext.get(this.getEl());

if (this.lastTarget) {
Ext.get(this.lastTarget).appendChild(el);
el.applyStyles({position:"", width:""});
} else {
el.applyStyles({position:"absolute"});
el.setXY(dragEl.getXY());
el.setWidth(dragEl.getWidth());
}

Ext.get("dd1-ct").removeCls("dd-over");
Ext.get("dd2-ct").removeCls("dd-over");
};
</script>


@functions
{
private string RenderDropZonesAndProxy()
{
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 2; i++)
{
DropZone dz = new DropZone{ Target = "dd{0}-ct".FormatWith(i), Group = "group"};
sb.Append(dz.ToScript());
}

for (int i = 1; i <= 2; i++)
{
for (int p = 1; p <= 3; p++)
{
DDProxy ddProxy = new DDProxy
{
Target = "dd{0}-item{1}".FormatWith(i,p),
Group = "group",
StartDrag = { Fn = "startDrag" },
OnDragOver = { Fn = "onDragOver" },
OnDragOut = { Fn = "onDragOut" },
EndDrag = { Fn = "endDrag" }
};

sb.Append(ddProxy.ToScript());
}
}
return sb.ToString();
}
}

<script>
@Html.Raw(RenderDropZonesAndProxy())
</script>

<div class="dd-ct" id="dd1-ct">
<div class="dd-item" id="dd1-item1">Item 1.1</div>
<div class="dd-item" id="dd1-item2">Item 1.2</div>
<div class="dd-item" id="dd1-item3">Item 1.3</div>
</div>

<div class="dd-ct" id="dd2-ct">
<div class="dd-item" id="dd2-item1">Item 2.1</div>
<div class="dd-item" id="dd2-item2">Item 2.2</div>
<div class="dd-item" id="dd2-item3">Item 2.3</div>
</div>

Daniil
Oct 09, 2014, 7:44 PM
I guess it is a partial view, isn't? It is probably rendered to the main view using the RenderMode.AddTo mode? If so, as already mentioned such the partial view cannot be rendered with such the mode.

Please try to remove RenderMode.AddTo.

ATLAS
Oct 10, 2014, 9:11 AM
Ah! The whole site is built around a main layout that adds any number of partials as described by the viewmodel passed in. I'm assuming that the default RenderMode is AddTo? If it can be removed, how? Will it break the whole site if removed or changed?

Is there another way of creating the equivalent of the output of the function :-



<script>
@Html.Raw(RenderDropZonesAndProxy())
</script>


At the moment I'm trying to progress by using a copy and paste of the output obtained by a "view source" of the example :-



<script>
new Ext.net.ProxyDDCreator({ target: "dd1-ct", config: { ddGroup: "group" }, type: Ext.dd.DropZone });
new Ext.net.ProxyDDCreator({ target: "dd2-ct", config: { ddGroup: "group" }, type: Ext.dd.DropZone });

new Ext.net.ProxyDDCreator({ target: "dd1-item1", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd1-item2", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd1-item3", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd1-item4", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd1-item5", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });

new Ext.net.ProxyDDCreator({ target: "dd2-item1", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item2", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item3", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item4", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item5", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item6", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item7", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item8", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
new Ext.net.ProxyDDCreator({ target: "dd2-item9", group: "group", config: { endDrag: endDrag, onDragOut: onDragOut, onDragOver: onDragOver, startDrag: startDrag }, type: Ext.dd.DDProxy });
</script>



I need to create this dynamically as the number of ddGroups and contained items will be dictated by the viewmodel data.

Daniil
Oct 10, 2014, 9:25 AM
I'm assuming that the default RenderMode is AddTo?

It is RenderTo by default.

Please demonstrate how you render the partial views.


Is there another way of creating the equivalent of the output of the function...

Yes, creating it directly via JavaScript is a good way to go.

ATLAS
Oct 10, 2014, 10:15 AM
Thanks Daniil, I think I'll just use JavaScript as it looks as though that will work without risking anything untoward happening with the whole site at this stage.

But FYI, my _Layout.cshtml looks like this :-



@(Html.X().Viewport()
.ID("EXT_PAGE_VIEWPORT")
.Layout(LayoutType.Fit)
.Cls("page-main")
.Listeners(l =>
{
l.AfterLayout.Fn = "fnOnPageLayout";
})

.Items(
Html.X().Panel()
.ID("EXT_PAGE_PANEL")
.Layout(LayoutType.VBox)
.LayoutConfig(new VBoxLayoutConfig { Align = VBoxAlign.Stretch, Pack = BoxPack.Start })
.AutoScroll(true)
.TopBar(
Html.X().Toolbar()
.Layout(LayoutType.Fit)
.Border(false)
.PaddingSpec("0 0 0 0")
.ItemsFromPartial("_ToolBar", Model.ToolBar)
)
.Items(layoutItems =>
{
for (var item = 0; item < @Model.PageItems.Count; item++)
{
var pi = @Model.PageItems.ElementAt(item);
layoutItems.Add(
Html.X().Container()
.BaseCls("x-plain")
.Border(false)
.ItemsFromPage(this, pi.PartialViewName + ".cshtml", new { model = pi.ViewModel }));
}
}
)
.BottomBar(
Html.X().StatusBar()
.Layout(LayoutType.Fit)
.Border(false)
.PaddingSpec("0 0 0 0")
.ItemsFromPage(this, "_Footer.cshtml", new { model = Model.Navigation})
.ToolTips(tt => tt.Add(
Html.X().ToolTip()
.Title("Application Version")
.Items(Html.X().Label(String.Format("CAMS Version {0}", applicationVersion)))
))
)
)


Needless to say, the partials used at this level can themselves use many partials to complete the implementation.

Daniil
Oct 10, 2014, 3:17 PM
I think .ItemsFromPartial() throws the Exception.

For your partial view you should use .ContentFromPartial() instead.