Hi there,
What I'm trying to achieve here is I think pretty simple and is nearly working. I have a RadGrid with drag and drop set to true, an extender so I can design my own helper when dragging and a RadDock drop zone.
I followed this example to load Custom WebControls dynamically in my docks, this one for virtual scrolling in my grid, and been sent this project sample to drag and drop nodes from TreeView to a dockzone few weeks ago by the Telerik team (Thanks again ;)).
It works fine if I'm not using the ASP UpdatePanel for AsyncPostback except that when I add a new dock to my zone or re-order them, all the pre-existing docks become empty. I first thought that this was due to the fact that I'm not posting my data properly using this UpdatePanel and thus implemented it.
I'm now getting an error saying that it couldn't find my UpdatePanel1 :
Here's my code, hopefully someone will be able to help. I'm suspecting the RadAjaxPanel embedding the UpdatePanel to screw this up, but I kinda need it to pass some parameters my method in code behind:
ASPX
C#
When, I refresh the page, the dock appears but is not docked to the zone.
Help anyone ?
Cheers
What I'm trying to achieve here is I think pretty simple and is nearly working. I have a RadGrid with drag and drop set to true, an extender so I can design my own helper when dragging and a RadDock drop zone.
I followed this example to load Custom WebControls dynamically in my docks, this one for virtual scrolling in my grid, and been sent this project sample to drag and drop nodes from TreeView to a dockzone few weeks ago by the Telerik team (Thanks again ;)).
It works fine if I'm not using the ASP UpdatePanel for AsyncPostback except that when I add a new dock to my zone or re-order them, all the pre-existing docks become empty. I first thought that this was due to the fact that I'm not posting my data properly using this UpdatePanel and thus implemented it.
I'm now getting an error saying that it couldn't find my UpdatePanel1 :
PRM_MissingPanel : Could not find UpdatePanel with ID UpdatePanel1.
Here's my code, hopefully someone will be able to help. I'm suspecting the RadAjaxPanel embedding the UpdatePanel to screw this up, but I kinda need it to pass some parameters my method in code behind:
ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="StopsMgr.aspx.cs" Inherits="Test.StopsMgr" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
>Stop Manager</
title
>
<
link
href
=
"css/StopsMgr.css"
rel
=
"stylesheet"
type
=
"text/css"
/>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
<
Scripts
>
<%--Needed for JavaScript IntelliSense in VS2010--%>
<%--For VS2008 replace RadScriptManager with ScriptManager--%>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.Core.js"
/>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQuery.js"
/>
<
asp:ScriptReference
Assembly
=
"Telerik.Web.UI"
Name
=
"Telerik.Web.UI.Common.jQueryInclude.js"
/>
</
Scripts
>
</
telerik:RadScriptManager
>
<
div
id
=
"TabStop"
>
<
telerik:RadAjaxLoadingPanel
ID
=
"StopLoadingPanel"
runat
=
"server"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadCodeBlock
ID
=
"RadCodeBlock_StopScript"
runat
=
"server"
>
<
script
type
=
"text/javascript"
>
function showLoadingPanel(sender, args) {
toggleLoadingPanel(sender.get_id(), true);
}
function hideLoadingPanel(sender, args) {
toggleLoadingPanel(sender.get_id(), false);
}
function toggleLoadingPanel(elementId, show) {
var loadingPanel = $find("StopLoadingPanel");
if (show) {
loadingPanel.show(elementId);
}
else {
loadingPanel.hide(elementId);
}
}
function clientDragCreating(sender, args) {
var grid = $find("<%=GridSearchStops.ClientID %>");
var MasterTable = grid.get_masterTableView();
var selectedRows = MasterTable.get_selectedItems();
var name = MasterTable.getCellByColumnUniqueName(selectedRows[0], "Name");
var lines = MasterTable.getCellByColumnUniqueName(selectedRows[0], "Lines");
$("#rgDraggedItemHeader").html(name.innerHTML);
$("#rgDraggedItemSub").html(lines.innerHTML);
}
var currentGrid;
var zone;
var mouseX;
var mouseY;
var displayPlaceholder = false;
function onRowDragStarted(sender, args) {
currentGrid = sender;
zone = $find("RadDockZoneStops");
$(document).mousemove(function (e) {
mouseX = e.pageX;
mouseY = e.pageY;
if (zone != null && displayPlaceholder)
zone._showPlaceholder(args.get_gridDataItem());
});
$("#RadDockZoneStops").mouseenter(function () {
displayPlaceholder = true;
}).mouseleave(function () {
displayPlaceholder = false;
if (zone != null)
zone._hidePlaceholder();
});
}
function onRowDropping(sender, args) {
zone = $find("RadDockZoneStops");
if (zone != null)
zone._hidePlaceholder();
$(document).unbind('mousemove');
$("#RadDockZoneStops").unbind('mouseenter').unbind('mouseleave');
if (sender.get_id() == "<%=GridSearchStops.ClientID %>") {
var node = args.get_destinationHtmlElement();
if (isChildOf('RadDockZoneStops', node)) {
$find("<%= RadAjaxPanel1.ClientID%>").ajaxRequestWithTarget("<%= RadAjaxPanel1.UniqueID %>", "LoadDock¤" + args._dragedItems[0].getDataKeyValue('Id'));
args.set_cancel(true);
}
}
args.set_cancel(true);
}
function isChildOf(parentId, element) {
while (element) {
if (element.id && element.id.indexOf(parentId) > -1) {
return true;
}
element = element.parentNode;
}
return false;
}
</
script
>
</
telerik:RadCodeBlock
>
<
div
id
=
"Search"
>
<
telerik:RadGrid
ID
=
"GridSearchStops"
runat
=
"server"
AllowPaging
=
"true"
PageSize
=
"42"
AutoGenerateColumns
=
"false"
Height
=
"820px"
>
<
PagerStyle
Mode
=
"NextPrevNumericAndAdvanced"
/>
<
MasterTableView
TableLayout
=
"Fixed"
DataKeyNames
=
"Id"
ClientDataKeyNames
=
"Id"
>
<
Columns
>
<
telerik:GridBoundColumn
DataField
=
"Id"
HeaderText
=
"ID"
/>
<
telerik:GridBoundColumn
DataField
=
"Name"
HeaderText
=
"Stop Name"
/>
<
telerik:GridBoundColumn
DataField
=
"Lines"
HeaderText
=
"Currently On Lines"
/>
</
Columns
>
</
MasterTableView
>
<
ClientSettings
AllowRowsDragDrop
=
"true"
>
<
Scrolling
AllowScroll
=
"true"
EnableVirtualScrollPaging
=
"true"
UseStaticHeaders
=
"true"
/>
<
DataBinding
Location
=
"StopsMgr.aspx"
SelectMethod
=
"GetStopData"
SelectCountMethod
=
"GetStopCount"
StartRowIndexParameterName
=
"startRowIndex"
MaximumRowsParameterName
=
"maxRows"
/>
<
ClientEvents
OnCommand
=
"showLoadingPanel"
OnDataBound
=
"hideLoadingPanel"
OnRowDragStarted
=
"onRowDragStarted"
OnRowDropping
=
"onRowDropping"
/>
<
Selecting
AllowRowSelect
=
"true"
/>
</
ClientSettings
>
</
telerik:RadGrid
>
<
ext:GridCustomDragExtender
ID
=
"GridCustomDragExtender1"
runat
=
"server"
TargetControlID
=
"GridSearchStops"
CursorOffsetLeft
=
"0"
CursorOffsetTop
=
"0"
OnClientDragContentCreating
=
"clientDragCreating"
>
<
DragContentTemplate
>
<
div
class
=
"rgDraggedItem"
>
<
div
id
=
"rgDraggedItemHeader"
>
</
div
>
<
div
id
=
"rgDraggedItemSub"
>
</
div
>
</
div
>
</
DragContentTemplate
>
</
ext:GridCustomDragExtender
>
</
div
>
<
div
id
=
"DropZone"
>
<
input
type
=
"text"
id
=
"currentPlaceholderPosition"
runat
=
"server"
style
=
"display: none"
/>
<
telerik:RadAjaxPanel
ID
=
"RadAjaxPanel1"
runat
=
"server"
OnAjaxRequest
=
"OnAjaxRequest_Action"
>
<
telerik:RadDockLayout
ID
=
"RadDockLayout1"
runat
=
"server"
OnLoadDockLayout
=
"RadDockLayout1_LoadDockLayout"
OnSaveDockLayout
=
"RadDockLayout1_SaveDockLayout"
>
<
telerik:RadDockZone
ID
=
"RadDockZoneStops"
runat
=
"server"
MinHeight
=
"300px"
HighlightedCssClass
=
"RadDockZoneStopsHighlight"
>
</
telerik:RadDockZone
>
<
div
style
=
"display: none"
>
Hidden UpdatePanel, which is used to receive the new dock controls. We will move
them with script to the desired initial dock zone.
<
asp:UpdatePanel
runat
=
"server"
ID
=
"UpdatePanel1"
>
<
Triggers
>
<
asp:AsyncPostBackTrigger
ControlID
=
"GridSearchStops"
EventName
=
"RowDrop"
/>
</
Triggers
>
</
asp:UpdatePanel
>
</
div
>
</
telerik:RadDockLayout
>
</
telerik:RadAjaxPanel
>
</
div
>
</
div
>
<
script
type
=
"text/javascript"
>
var $T = Telerik.Web.UI;
var isRowDragged = false;
//parameter can be dock or GridDataItem
Telerik.Web.UI.RadDockZone.prototype._showPlaceholder = function (obj, location) {
if (Object.getTypeName(obj) == "Telerik.Web.UI.GridDataItem") {
isRowDragged = true;
var row = obj;
this._repositionPlaceholder(row.get_element(), location);
var placeholderStyle = this._placeholder.style;
placeholderStyle.height = "50px";
placeholderStyle.width = "100%";
placeholderStyle.display = "block";
isRowDragged = false;
}
else {
var dock = obj;
this._repositionPlaceholder(dock.get_element(), location);
var dockBounds = dock._getBounds();
var placeholderMargin = dock._getMarginBox(this._placeholder);
var placeholderBorder = dock._getBorderBox(this._placeholder);
var horizontal = this.get_isHorizontal();
var placeholderStyle = this._placeholder.style;
placeholderStyle.height = dockBounds.height - (placeholderMargin.vertical + placeholderBorder.vertical) + "px";
placeholderStyle.width = this.get_fitDocks() && !horizontal ? "100%" : dockBounds.width - (placeholderMargin.horizontal + placeholderBorder.horizontal) + "px";
placeholderStyle.display = "block";
}
}
Telerik.Web.UI.RadDockZone.prototype._repositionPlaceholder = function (dock_element, location) {
//fix Row drag
if (isRowDragged == true) {
location = new Sys.UI.Point(mouseX, mouseY);
}
//end fix
var nearestChild = this._findItemAt(location, dock_element);
var zone_element = this.get_element();
if (null == nearestChild) {
// _clearElement must be after all docks and _placeholder
zone_element.insertBefore(this._placeholder, this._clearElement);
}
else {
if (nearestChild.previousSibling != this._placeholder) {
zone_element.insertBefore(this._placeholder, nearestChild);
}
}
//GET placeholder position
for (var i = 0; i <
zone_element.childNodes.length
; i++) {
if (zone_element.childNodes[i] == this._placeholder) {
var
currentPos
=
i
;
$get('currentPlaceholderPosition')
.value
=
currentPos
- 2;
}
}
//end Get
}
</script>
</
form
>
</
body
>
</
html
>
C#
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.Services;
using
System.Data.SqlClient;
using
System.Web.Configuration;
using
System.Data;
using
Telerik.Web.UI;
namespace
test
{
public
partial
class
StopsMgr : System.Web.UI.Page
{
private
List<DockState> CurrentDockStates
{
get
{
//Store the info about the added docks in the session. For real life
// applications we recommend using database or other storage medium
// for persisting this information.
List<DockState> _currentDockStates = (List<DockState>)Session[
"CurrentDockStatesDynamicDocks"
];
if
(Object.Equals(_currentDockStates,
null
))
{
_currentDockStates =
new
List<DockState>();
Session[
"CurrentDockStatesDynamicDocks"
] = _currentDockStates;
}
return
_currentDockStates;
}
set
{
Session[
"CurrentDockStatesDynamicDocks"
] = value;
}
}
private
RadDock CreateRadDockFromState(DockState state)
{
RadDock dock =
new
RadDock();
dock.ID =
string
.Format(
"RadDock{0}"
, state.UniqueName);
dock.ApplyState(state);
dock.Command +=
new
DockCommandEventHandler(dock_Command);
dock.Commands.Add(
new
DockCloseCommand());
dock.Commands.Add(
new
DockExpandCollapseCommand());
return
dock;
}
protected
void
Page_Init(
object
sender, EventArgs e)
{
//Recreate the docks in order to ensure their proper operation
for
(
int
i = 0; i < CurrentDockStates.Count; i++)
{
RadDock dock = CreateRadDockFromState(CurrentDockStates[i]);
//We will just add the RadDock control to the RadDockLayout.
// You could use any other control for that purpose, just ensure
// that it is inside the RadDockLayout control.
// The RadDockLayout control will automatically move the RadDock
// controls to their corresponding zone in the LoadDockLayout
// event (see below).
RadDockLayout1.Controls.Add(dock);
//We want to save the dock state every time a dock is moved.
CreateSaveStateTrigger(dock);
}
}
protected
void
Page_Load(
object
sender, EventArgs e)
{
//this.DataBind();
}
#region Stops
[WebMethod]
public
static
int
GetStopCount()
{
var cmd =
new
SqlCommand(
"P_GetNumberOfStops"
,
new
SqlConnection(WebConfigurationManager.ConnectionStrings[
"TestDB"
].ConnectionString));
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection.Open();
if
(cmd.Connection.State != ConnectionState.Open)
throw
new
Exception(
"Connection to DB failed"
);
var max = (
int
)cmd.ExecuteScalar();
cmd.Connection.Close();
return
max;
}
[WebMethod]
public
static
IEnumerable<Stop> GetStopData(
int
startRowIndex,
int
maxRows)
{
var cmd =
new
SqlCommand(
"P_GetStopData"
,
new
SqlConnection(WebConfigurationManager.ConnectionStrings[
"TestDB"
].ConnectionString));
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(
new
SqlParameter(
"@startRow"
, SqlDbType.Int));
cmd.Parameters.Add(
new
SqlParameter(
"@maxRows"
, SqlDbType.Int));
cmd.Parameters[
"@startRow"
].Value = startRowIndex;
cmd.Parameters[
"@maxRows"
].Value = startRowIndex + maxRows;
cmd.Connection.Open();
if
(cmd.Connection.State != ConnectionState.Open)
throw
new
Exception(
"Connection to DB failed"
);
var sqlRd = cmd.ExecuteReader();
if
(sqlRd.HasRows)
{
while
(sqlRd.Read())
{
var stop =
new
Stop()
{
Id = (
int
)sqlRd[
"S_ID"
],
Name = sqlRd[
"S_NAME"
].ToString(),
Lines =
"---"
};
yield
return
stop;
}
}
cmd.Connection.Close();
}
#region DockPanel
void
dock_Command(
object
sender, DockCommandEventArgs e)
{
if
(e.Command.Name ==
"Close"
)
{
ScriptManager.RegisterStartupScript(
UpdatePanel1,
this
.GetType(),
"RemoveDock"
,
string
.Format(@"function _removeDock() {{
Sys.Application.remove_load(_removeDock);
$find(
'{0}'
).undock();
$
get
(
'{1}'
).appendChild($
get
(
'{0}'
));
$find(
'{0}'
).doPostBack(
'DockPositionChanged'
);
}};
Sys.Application.add_load(_removeDock);", ((RadDock)sender).ClientID, UpdatePanel1.ClientID),
true
);
}
}
private
void
CreateSaveStateTrigger(RadDock dock)
{
//Ensure that the RadDock control will initiate postback
// when its position changes on the client or any of the commands is clicked.
//Using the trigger we will "ajaxify" that postback.
dock.AutoPostBack =
true
;
dock.CommandsAutoPostBack =
true
;
AsyncPostBackTrigger saveStateTrigger =
new
AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName =
"DockPositionChanged"
;
UpdatePanel1.Triggers.Add(saveStateTrigger);
saveStateTrigger =
new
AsyncPostBackTrigger();
saveStateTrigger.ControlID = dock.ID;
saveStateTrigger.EventName =
"Command"
;
UpdatePanel1.Triggers.Add(saveStateTrigger);
}
protected
void
RadDockLayout1_LoadDockLayout(
object
sender, DockLayoutEventArgs e)
{
//Populate the event args with the state information. The RadDockLayout control
// will automatically move the docks according that information.
foreach
(DockState state
in
CurrentDockStates)
{
e.Positions[state.UniqueName] = state.DockZoneID;
e.Indices[state.UniqueName] = state.Index;
}
}
protected
void
RadDockLayout1_SaveDockLayout(
object
sender, DockLayoutEventArgs e)
{
//Save the dock state in the page Session. This will enable us
// to recreate the dock in the next Page_Init.
CurrentDockStates = RadDockLayout1.GetRegisteredDocksState();
}
protected
void
OnAjaxRequest_Action(
object
sender, AjaxRequestEventArgs e)
{
var args = e.Argument.Split(
'¤'
);
if
(args[0] ==
"LoadDock"
&& args.Length > 1)
{
var dock = LoadDock(
int
.Parse(args[1]));
var currentPos =
int
.Parse(currentPlaceholderPosition.Value);
UpdatePanel1.ContentTemplateContainer.Controls.Add(dock);
ScriptManager.RegisterStartupScript(
dock,
this
.GetType(),
"AddDock"
,
string
.Format(@"function _addDock() {{
Sys.Application.remove_load(_addDock);
$find(
'{1}'
).dock($find(
'{0}'
),{2});
$find(
'{0}'
).doPostBack(
'DockPositionChanged'
);
}};
Sys.Application.add_load(_addDock);", dock.ClientID, RadDockZoneStops.ID, currentPos),
true
);
CreateSaveStateTrigger(dock);
}
}
private
RadDock LoadDock(
int
id)
{
try
{
var dock =
new
RadDock();
dock.DockMode = DockMode.Docked;
dock.EnableRoundedCorners =
true
;
dock.UniqueName = Guid.NewGuid().ToString();
dock.ID =
string
.Format(
"RadDock{0}"
, dock.UniqueName);
dock.Title =
"Title "
+ id;
var widget = LoadControl(
this
,
"~/Templates/StopFormTpl.ascx"
, id,
"myTitle"
);
widget.EnableViewState =
false
;
dock.ContentContainer.Controls.Add(widget);
dock.Width = Unit.Percentage(100);
dock.Height = Unit.Pixel(200);
dock.Commands.Add(
new
DockCloseCommand());
dock.Commands.Add(
new
DockExpandCollapseCommand());
dock.Command +=
new
DockCommandEventHandler(dock_Command);
return
dock;
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message, ex.InnerException);
}
}
When, I refresh the page, the dock appears but is not docked to the zone.
Help anyone ?
Cheers