I developed a control to sort and order modules in a document. This is done in a telerik treeview control.
This works fine in Sharepoint 2010. Now I have the requirement to deploy this to Sharepoint 2013, but the site collection is running in "2010 compatibility mode". What happens now is, the page is loaded and I see all the controls. But after the second, sometimes the third click on any button in the treeview (does not affect other standard buttons on the page), the control disappears when trying to rebind. The code behind is executed, but in the browser console (same behaviour in IE/FF) I see errors like
IE: window._WebForm_InitCallback() -> (SCRIPT438: Object doesn't support this
property or method )
FF: init.js -> too much recursion
The control is still "available" in the page source, but seems not to be able to draw itself again. I added screenshots to show the control before and after. The browser shows a long list of maybe 100 entries "WebForm_Initcallback, init.js. This is probably the "too much recursion shown in the javascript debugger.
I started with a 2011 Telerik.Web.UI control version, since this is an old project, but on seeing the error, updated to the latest version 2014.1.225.35. This solution works fine in Sharepoint 2010, and Sharepoint 2013 (site collection in non-compat mode)
I can't pinpoint the error, since it's thrown in minified sharepoint javascript files. Has anyone experienced this problem before?
ASPX
Code Behind
This works fine in Sharepoint 2010. Now I have the requirement to deploy this to Sharepoint 2013, but the site collection is running in "2010 compatibility mode". What happens now is, the page is loaded and I see all the controls. But after the second, sometimes the third click on any button in the treeview (does not affect other standard buttons on the page), the control disappears when trying to rebind. The code behind is executed, but in the browser console (same behaviour in IE/FF) I see errors like
IE: window._WebForm_InitCallback() -> (SCRIPT438: Object doesn't support this
property or method )
FF: init.js -> too much recursion
The control is still "available" in the page source, but seems not to be able to draw itself again. I added screenshots to show the control before and after. The browser shows a long list of maybe 100 entries "WebForm_Initcallback, init.js. This is probably the "too much recursion shown in the javascript debugger.
I started with a 2011 Telerik.Web.UI control version, since this is an old project, but on seeing the error, updated to the latest version 2014.1.225.35. This solution works fine in Sharepoint 2010, and Sharepoint 2013 (site collection in non-compat mode)
I can't pinpoint the error, since it's thrown in minified sharepoint javascript files. Has anyone experienced this problem before?
ASPX
<
telerik:RadFormDecorator
ID
=
"FormDecorator1"
runat
=
"server"
DecoratedControls
=
"all"
Skin
=
"Telerik"
></
telerik:RadFormDecorator
>
<
telerik:RadAjaxPanel
ID
=
"RadAjaxPanel1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
>
<
asp:Button
ID
=
"btnExpandAll"
runat
=
"server"
onclick
=
"btnExpandAll_Click"
Text="<%$Resources:MSH_DocumentCreatorUI,ReportGenerator_ExpandButtonText%>"/>
<
telerik:RadTreeList
runat
=
"server"
ID
=
"RadTreeList1"
DataKeyNames
=
"ID"
ParentDataKeyNames
=
"ParentChapter"
OnNeedDataSource
=
"RadTreeList1_NeedDataSource"
OnUpdateCommand
=
"RadTreeList1_UpdateCommand"
OnInsertCommand
=
"RadTreeList1_InsertCommand"
OnItemCommand
=
"RadTreeList1_ItemCommand"
OnItemDataBound
=
"RadTreeList1_ItemDataBound"
AutoGenerateColumns
=
"false"
EditMode
=
"InPlace"
OnDataBinding
=
"RadTreeList1_DataBinding"
GridLines
=
"None"
NoRecordsText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_NoRecordsText%>">
<
Columns
>
<
docCreator:CustomTreeListEditCommandColumn
UniqueName
=
"EditCommandColumn"
ButtonType
=
"ImageButton"
InsertText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_SaveButtonText%>"
AddRecordText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_AddButtonText%>"
HeaderStyle-Width="200px" DeleteButtonImageUrl="/_layouts/Images/DocumentCreator/delete.png"
DeleteButtonID="DeleteButton" DeleteButtonCommand="Delete" DeleteButtonText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_DeleteButtonText%>"
UpButtonImageUrl="/_layouts/Images/DocumentCreator/up.png" UpButtonID="UpButton"
UpButtonCommand="Up" UpButtonText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_MoveUpButtonText%>"
DownButtonImageUrl="/_layouts/Images/DocumentCreator/down.png" DownButtonID="DownButton"
DownButtonCommand="Down" DownButtonText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_MoveDownButtonText%>"
LeftButtonImageUrl="/_layouts/Images/DocumentCreator/left.png" LeftButtonID="LeftButton"
LeftButtonCommand="Left" LeftButtonText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_MoveLeftButtonText%>"
RightButtonImageUrl="/_layouts/Images/DocumentCreator/right.png" RightButtonID="RightButton"
RightButtonCommand="Right" RightButtonText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_MoveRightButtonText%>">
</
docCreator:CustomTreeListEditCommandColumn
>
<
telerik:TreeListTemplateColumn
HeaderText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_ChapterNumberColumnHeaderText%>"
ItemStyle-Width="70px" HeaderStyle-Width="70px" UniqueName="ChapterNumber">
<
ItemTemplate
>
<
asp:Label
ID
=
"lblChapterNumber"
runat
=
"server"
></
asp:Label
>
</
ItemTemplate
>
<
EditItemTemplate
>
<
asp:Label
ID
=
"lblChapterNumber"
runat
=
"server"
></
asp:Label
>
</
EditItemTemplate
>
</
telerik:TreeListTemplateColumn
>
<
telerik:TreeListBoundColumn
DataField
=
"Title"
HeaderText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_TextColumnHeaderText%>"
UniqueName="Title">
</
telerik:TreeListBoundColumn
>
<
telerik:TreeListTemplateColumn
HeaderText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_LinkColumnHeaderText%>"
UniqueName="Link">
<
ItemTemplate
>
<
asp:Repeater
ID
=
"textModulesRepeater"
runat
=
"server"
>
<
ItemTemplate
>
<
asp:HyperLink
ID
=
"lblLink"
runat
=
"server"
Text='<%# DataBinder.Eval(Container.DataItem, "Title") %>' NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "Url") %>'></
asp:HyperLink
>
<
br
/>
</
ItemTemplate
>
</
asp:Repeater
>
</
ItemTemplate
>
<
EditItemTemplate
>
<
div
style
=
"overflow: auto; width: 100%; max-height: 200px; position: relative;"
>
<
asp:CheckBoxList
ID
=
"textModulesList"
runat
=
"server"
CssClass
=
"textModuleCheckboxList"
/>
</
div
>
</
EditItemTemplate
>
</
telerik:TreeListTemplateColumn
>
<
telerik:TreeListTemplateColumn
HeaderText="<%$Resources:MSH_DocumentCreatorUI,ChapterEditor_StatusColumnHeaderText%>"
UniqueName="Status">
<
ItemTemplate
>
<
asp:Image
ID
=
"Image1"
ImageUrl='<%# this.GetImageUrlForColumnStatus(DataBinder.Eval(Container.DataItem, "Status")) %>'
runat="server" /><
asp:Label
ID
=
"lblStatus"
Style
=
"vertical-align: top; margin-left: 5px"
runat
=
"server"
Text='<%# this.GetLabelForColumnStatus(DataBinder.Eval(Container.DataItem, "Status")) %>'></
asp:Label
>
</
ItemTemplate
>
<
EditItemTemplate
>
<
asp:DropDownList
runat
=
"server"
ID
=
"ddlStatus"
>
<
asp:ListItem
Text="<%$Resources:MSH_DocumentCreatorUI,StatusEnum_Green_Description%>"
Value="Green"></
asp:ListItem
>
<
asp:ListItem
Text="<%$Resources:MSH_DocumentCreatorUI,StatusEnum_Yellow_Description%>"
Value="Yellow"></
asp:ListItem
>
<
asp:ListItem
Text="<%$Resources:MSH_DocumentCreatorUI,StatusEnum_Red_Description%>"
Value="Red" Selected="True"></
asp:ListItem
>
</
asp:DropDownList
>
</
EditItemTemplate
>
</
telerik:TreeListTemplateColumn
>
</
Columns
>
</
telerik:RadTreeList
>
</
telerik:RadAjaxPanel
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
/>
Code Behind
using
System;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Collections;
using
Microsoft.SharePoint;
using
System.Collections.Generic;
using
Microsoft.SharePoint.Linq;
using
Telerik.Web.UI;
using
System.Data;
using
System.Linq;
using
MSH.DocumentCreator.DataAccess;
using
MSH.DocumentCreator;
using
MSH.DocumentCreator.DocumentGeneration;
namespace
MSH.DocumentCreator.ChapterEditor
{
public
partial
class
ChapterEditorUserControl : UserControl
{
ReportStructure _docStructure;
DataTable _textModules;
IEnumerable<
int
> selectedTextModules;
ReportStructure DocumentStructure
{
get
{
if
(_docStructure ==
null
)
_docStructure =
new
ReportStructure();
return
_docStructure;
}
}
private
Dictionary<
int
,
double
?> itemOrderMaxValuesByParent =
new
Dictionary<
int
,
double
?>();
private
Dictionary<
int
,
double
?> itemOrderMinValuesByParent =
new
Dictionary<
int
,
double
?>();
private
Dictionary<
int
,
string
> itemChapterNumber =
new
Dictionary<
int
,
string
>();
private
Dictionary<
int
,
int
> chapterParentIds =
new
Dictionary<
int
,
int
>();
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
selectedTextModules =
new
List<
int
>();
foreach
(ChaptersItem item
in
DocumentStructure.Chapters)
{
selectedTextModules = selectedTextModules.Union(item.LinkId.Select(l => l.Value));
}
}
protected
void
btnExpandAll_Click(
object
sender, EventArgs e)
{
RadTreeList1.ExpandAllItems();
}
#region Commands
protected
void
RadTreeList1_InsertCommand(
object
sender, TreeListCommandEventArgs e)
{
this
.DocumentStructure.Chapters.InsertOnSubmit(GetChapter(e.Item
as
TreeListDataInsertItem));
this
.DocumentStructure.SaveChapters();
}
protected
void
RadTreeList1_UpdateCommand(
object
sender, TreeListCommandEventArgs e)
{
GetChapter(e.Item
as
TreeListDataItem);
this
.DocumentStructure.SaveChapters();
ReBind();
}
public
void
RadTreeList1_ItemCommand(
object
sender, TreeListCommandEventArgs e)
{
if
(e.CommandName ==
"InitInsert"
|| e.CommandName ==
"PerformInsert"
|| e.CommandName ==
"Edit"
|| e.CommandName ==
"Cancel"
)
return
;
ChaptersItem currentItem = GetChapter(e.Item
as
TreeListDataItem);
int
id = (e.Item
as
TreeListDataItem).GetId(
"ID"
);
switch
(e.CommandName)
{
case
"Left"
:
DocumentStructure.MoveLeft(currentItem);
break
;
case
"Right"
:
DocumentStructure.MoveRight(currentItem);
break
;
case
"Up"
:
DocumentStructure.MoveUp(currentItem);
break
;
case
"Down"
:
DocumentStructure.MoveDown(currentItem);
break
;
case
"Delete"
:
DocumentStructure.DeleteRecursively(currentItem);
DocumentStructure.SaveChapters();
break
;
default
:
break
;
}
RadTreeList1.Rebind();
}
#endregion
#region Binding
protected
void
RadTreeList1_NeedDataSource(
object
sender, TreeListNeedDataSourceEventArgs e)
{
RadTreeList1.DataSource = DocumentStructure.Chapters.OrderBy(ch => ch.ItemOrder).ToList<ChaptersItem>();
}
protected
void
RadTreeList1_DataBinding(
object
sender, EventArgs e)
{
ReportParts tm =
new
ReportParts();
_textModules = tm.GetByContentType(
"Text-Module"
,
"Text Module"
);
}
public
void
RadTreeList1_ItemDataBound(
object
sender, TreeListItemDataBoundEventArgs e)
{
if
(e.Item
is
TreeListHeaderItem)
{
(e.Item.Controls[0].Controls[0]
as
Button).ToolTip = MSH.DocumentCreator.Modules.UIResources.MSH_DocumentCreatorUI.ChapterEditor_AddChapterText;
}
switch
(e.Item.ItemType)
{
case
TreeListItemType.EditItem:
DropDownList ddlStatus = e.Item.FindControl(
"ddlStatus"
)
as
DropDownList;
ChaptersItem spItem =
null
;
if
(e.Item
is
TreeListDataItem)
spItem =
this
.DocumentStructure.GetChapter((e.Item
as
TreeListDataItem).GetId(
"ID"
));
if
(spItem !=
null
&& spItem.Status.HasValue)
ddlStatus.SelectedValue = spItem.Status.Value.ToString();
CheckBoxList chkListTextModules = e.Item.FindControl(
"textModulesList"
)
as
CheckBoxList;
if
(spItem !=
null
)
{
var item = DocumentStructure.GetChapter(spItem.ID.Value);
PopulateHierarchyDictionaries(item);
}
if
(chkListTextModules !=
null
)
{
chkListTextModules.DataSource = GetUnusedOrOwnTextModules(spItem ==
null
?
null
: spItem.LinkId);
chkListTextModules.DataTextField =
"Title"
;
chkListTextModules.DataValueField =
"ID"
;
chkListTextModules.DataBind();
}
if
(spItem !=
null
&& spItem.LinkId !=
null
&& spItem.LinkId.Count != 0)
{
foreach
(
int
? docId
in
spItem.LinkId)
{
foreach
(ListItem item
in
chkListTextModules.Items)
if
(docId.Value.ToString() == item.Value)
{
item.Selected =
true
;
}
}
}
if
(spItem !=
null
)
{
Label lblChNumber = e.Item.FindControl(
"lblChapterNumber"
)
as
Label;
lblChNumber.Text = itemChapterNumber[spItem.ID.Value];
}
break
;
case
TreeListItemType.Item:
case
TreeListItemType.AlternatingItem:
int
id = (e.Item
as
TreeListDataItem).GetId(
"ID"
);
var currentItem = DocumentStructure.GetChapter(id);
var parentChapterId = currentItem.ParentChapter ?? -1;
PopulateHierarchyDictionaries(currentItem);
if
(!itemOrderMinValuesByParent[parentChapterId].HasValue || itemOrderMinValuesByParent[parentChapterId] >= currentItem.ItemOrder)
{
ImageButton upButton = e.Item.FindControl(
"UpButton"
)
as
ImageButton;
upButton.Enabled =
false
;
upButton.ImageUrl =
"/_layouts/Images/DocumentCreator/up_gray.png"
;
}
if
(!itemOrderMaxValuesByParent[parentChapterId].HasValue || itemOrderMaxValuesByParent[parentChapterId] <= currentItem.ItemOrder)
{
ImageButton downButton = e.Item.FindControl(
"DownButton"
)
as
ImageButton;
downButton.Enabled =
false
;
downButton.ImageUrl =
"/_layouts/Images/DocumentCreator/down_gray.png"
;
}
if
(!currentItem.ParentChapter.HasValue)
{
ImageButton leftButton = e.Item.FindControl(
"LeftButton"
)
as
ImageButton;
leftButton.Enabled =
false
;
leftButton.ImageUrl =
"/_layouts/Images/DocumentCreator/left_gray.png"
;
}
if
(!DocumentStructure.Chapters.Any(ch => ch.ParentChapter == currentItem.ParentChapter && ch.ItemOrder < currentItem.ItemOrder))
{
ImageButton rightButton = e.Item.FindControl(
"RightButton"
)
as
ImageButton;
rightButton.Enabled =
false
;
rightButton.ImageUrl =
"/_layouts/Images/DocumentCreator/right_gray.png"
;
}
Repeater textModulesRepeater = e.Item.FindControl(
"textModulesRepeater"
)
as
Repeater;
if
(textModulesRepeater !=
null
)
{
textModulesRepeater.DataSource = GetTextModulesWithCountry(currentItem.LinkId);
textModulesRepeater.DataBind();
}
Label lblNumber = e.Item.FindControl(
"lblChapterNumber"
)
as
Label;
lblNumber.Text = itemChapterNumber[currentItem.ID.Value];
break
;
default
:
break
;
}
}
protected
void
checkBoxList_DataBound(
object
sender, EventArgs args)
{
CheckBoxList checkBoxes = sender
as
CheckBoxList;
foreach
(ListItem item
in
checkBoxes.Items)
{
item.Attributes.Add(
"Style"
,
"padding: 0px !important;"
);
}
}
private
void
ReBind()
{
RadTreeList1.DataSource =
this
.DocumentStructure.Chapters.OrderBy(ch => ch.ItemOrder);
RadTreeList1.DataBind();
}
#endregion
#region Helpers
protected
string
GetImageUrlForColumnStatus(
object
status)
{
switch
((Status)status)
{
case
Status.Red:
return
"/_layouts/Images/DocumentCreator/red_ball.png"
;
case
Status.Green:
return
"/_layouts/Images/DocumentCreator/green_ball.png"
;
case
Status.Yellow:
return
"/_layouts/Images/DocumentCreator/yellow_ball.png"
;
default
:
return
string
.Empty;
}
}
protected
string
GetLabelForColumnStatus(
object
status)
{
return
Helpers.GetDescription((Status)status);
}
private
ChaptersItem GetChapter(TreeListDataItem item)
{
return
GetChapterValues(item, item.ParentItem);
}
private
ChaptersItem GetChapter(TreeListDataInsertItem item)
{
return
GetChapterValues(item, item.ParentItem);
}
private
ChaptersItem GetChapterValues(TreeListEditableItem item, TreeListDataItem parentItem)
{
int
? id =
null
;
ChaptersItem chapter =
null
;
if
(item
is
TreeListDataItem)
{
id = (item
as
TreeListDataItem).GetId(
"ID"
);
chapter = DocumentStructure.GetChapter(id.Value);
}
else
chapter =
new
ChaptersItem();
chapter.ParentChapter = GetParentId(parentItem);
Hashtable values = item.GetValues();
DropDownList ddlStatus = item.FindControl(
"ddlStatus"
)
as
DropDownList;
if
(ddlStatus !=
null
)
{
Status statusValue = Status.None;
if
(ddlStatus.SelectedValue !=
null
)
statusValue = (Status)Enum.Parse(
typeof
(Status), ddlStatus.SelectedValue);
chapter.Status = statusValue;
}
CheckBoxList chkListTextModules = item.FindControl(
"textModulesList"
)
as
CheckBoxList;
if
(chkListTextModules !=
null
)
{
foreach
(ListItem chkItem
in
chkListTextModules.Items)
{
int
linkId = Int32.Parse(chkItem.Value);
if
(chkItem.Selected)
{
if
(chapter.Status.Value == Status.Red)
chapter.Status = Status.Yellow;
if
(chapter.LinkId.Count(v => v.Value == linkId) == 0)
chapter.LinkId.Add(linkId);
}
else
{
if
(chapter.LinkId.Count(v => v.Value == linkId) != 0)
chapter.LinkId.Remove(chapter.LinkId.Where(v => v.Value == linkId).First());
}
}
}
if
(!chapter.ID.HasValue)
chapter.ItemOrder = DocumentStructure.Chapters.Where(ch => ch.ParentChapter == chapter.ParentChapter).Max(ch => ch.ItemOrder) + 1 ?? 1;
chapter.Title = values[
"Title"
]
as
string
;
return
chapter;
}
private
int
? GetParentId(TreeListDataItem parent)
{
if
(parent ==
null
)
return
null
;
ChaptersItem parentItem =
this
.DocumentStructure.GetChapter(parent.GetId(
"ID"
));
if
(parentItem ==
null
)
return
null
;
return
parentItem.ID;
}
private
string
GetChapterNumber(ChaptersItem item)
{
if
(!item.ParentChapter.HasValue)
{
return
(chapterParentIds.Values.Count(v => v == -1) + 1).ToString();
}
else
{
return
itemChapterNumber[item.ParentChapter.Value] +
"."
+ (chapterParentIds.Values.Count(v => v == item.ParentChapter.Value) + 1);
}
}
private
DataTable GetTextModulesWithCountry(IList<
int
?> ds)
{
DataTable result =
new
DataTable();
result.Columns.Add(
"ID"
);
result.Columns.Add(
"Title"
);
result.Columns.Add(
"URL"
);
if
(ds !=
null
)
foreach
(DataRow module
in
_textModules.Rows)
{
int
moduleId = (
int
)module[
"ID"
];
if
(ds.FirstOrDefault(r => r.Value == moduleId) !=
null
)
{
var tmEntity = DocumentStructure.TextModules.FirstOrDefault(tm => tm.ID == moduleId);
if
(tmEntity !=
null
)
result.Rows.Add(moduleId, module[
"Title"
], tmEntity.Path +
"/"
+ tmEntity.Name);
}
}
return
result;
}
private
object
GetUnusedOrOwnTextModules(IList<
int
?> ds)
{
DataTable result =
new
DataTable();
result.Columns.Add(
"ID"
);
result.Columns.Add(
"Title"
);
foreach
(DataRow module
in
_textModules.Rows)
{
if
((ds !=
null
&& ds.FirstOrDefault(r => r.Value == (
int
)module[
"ID"
]) !=
null
) || !selectedTextModules.Contains((
int
)module[
"ID"
]))
result.Rows.Add(module[
"ID"
], module[
"Title"
]);
}
result.DefaultView.Sort =
"Title"
;
return
result.DefaultView;
}
private
void
PopulateHierarchyDictionaries(ChaptersItem item)
{
var parentChapterId = item.ParentChapter ?? -1;
if
(!itemOrderMaxValuesByParent.ContainsKey(parentChapterId))
itemOrderMaxValuesByParent.Add(parentChapterId, DocumentStructure.Chapters.Where(ch => ch.ParentChapter == item.ParentChapter).Max(ch1 => ch1.ItemOrder));
if
(!itemOrderMinValuesByParent.ContainsKey(parentChapterId))
itemOrderMinValuesByParent.Add(parentChapterId, DocumentStructure.Chapters.Where(ch => ch.ParentChapter == item.ParentChapter).Min(ch1 => ch1.ItemOrder));
if
(!itemChapterNumber.ContainsKey(item.ID.Value))
{
itemChapterNumber.Add(item.ID.Value, GetChapterNumber(item));
}
if
(!chapterParentIds.ContainsKey(item.ID.Value))
{
chapterParentIds.Add(item.ID.Value, parentChapterId);
}
}
#endregion
}
}