AsyncPostBackTriggerによるSPREAD処理によってスクリプトエラーが発生する
対象製品
SPREAD for ASP.NET 8.0J
発生環境
Internet Explorer 8/9
状況
修正済み
詳細
IE8、IE9の利用時、AsyncPostBackTriggerによるSPREAD処理によってスクリプトエラーが発生します。
【再現手順】
1.新規WebフォームにSPREADおよびButtonひとつを配置し、下記の再現コードのようにAsyncPostBackTriggerを設定する
2.Webフォームに下記の再現コードを貼り付け、プロジェクトを起動する
3.Buttonを押下し、子階層を展開したSPREADデータ表示させる
4.Buttonを再度押下する
--- スクリプトエラーが発生する
--- IE9時のエラー: プロパティ"removeData"の値を取得できません。オブジェクトはNullまたは未定義です。
--- IE8時のエラー: エラー: '$element' は Null またはオブジェクトではありません。
【再現コード】
------------------------------------
.aspxファイル body部
------------------------------------
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<FarPoint:FpSpread ID="FpSpread1" runat="server" BorderColor="#A0A0A0"
BorderStyle="Solid" BorderWidth="1px" Height="200" Width="400">
<commandbar backcolor="#F6F6F6" buttonfacecolor="Control"
buttonhighlightcolor="ControlLightLight" buttonshadowcolor="ControlDark">
</commandbar>
<sheets>
<FarPoint:SheetView SheetName="Sheet1">
</FarPoint:SheetView>
</sheets>
</FarPoint:FpSpread>
</ContentTemplate>
<%-- エラー発生の要因 [2/2] ↓ --%>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
<%-- エラー発生の要因 [2/2] ↑ --%>
</asp:UpdatePanel>
</div>
</form>
------------------------------------
Webフォームクラス
------------------------------------
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' データの作成
Dim maxParentRows As Integer = 10 - 1
Dim maxChildRows As Integer = 5 - 1
Dim ds As New DataSet()
Dim Parent As DataTable = ds.Tables.Add("Parent")
Parent.DefaultView.AllowNew = False
Parent.Columns.Add("ParentA", GetType(Int32))
For i As Integer = 0 To maxParentRows
Parent.Rows.Add(i)
Next
Dim child As DataTable = ds.Tables.Add("Child")
child.DefaultView.AllowNew = False
child.Columns.Add("ChildA", GetType(Int32))
child.Columns.Add("ChildB", GetType(String))
For i As Integer = 0 To maxParentRows
For j As Integer = 0 To maxChildRows
child.Rows.Add(i, String.Format("P{0}C{1}", i, j))
Next
Next
ds.Relations.Add("PCRelation", Parent.Columns("ParentA"), child.Columns("ChildA"))
' SPREADの設定
FpSpread1.ActiveSheetView.DataSource = ds
FpSpread1.ActiveSheetView.PageSize = 10
' エラー発生の要因 [1/2]
For i As Integer = 0 To FpSpread1.ActiveSheetView.RowCount - 1
FpSpread1.ActiveSheetView.ExpandRow(i, True)
Next
End Sub
End Class
【再現手順】
1.新規WebフォームにSPREADおよびButtonひとつを配置し、下記の再現コードのようにAsyncPostBackTriggerを設定する
2.Webフォームに下記の再現コードを貼り付け、プロジェクトを起動する
3.Buttonを押下し、子階層を展開したSPREADデータ表示させる
4.Buttonを再度押下する
--- スクリプトエラーが発生する
--- IE9時のエラー: プロパティ"removeData"の値を取得できません。オブジェクトはNullまたは未定義です。
--- IE8時のエラー: エラー: '$element' は Null またはオブジェクトではありません。
【再現コード】
------------------------------------
.aspxファイル body部
------------------------------------
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<FarPoint:FpSpread ID="FpSpread1" runat="server" BorderColor="#A0A0A0"
BorderStyle="Solid" BorderWidth="1px" Height="200" Width="400">
<commandbar backcolor="#F6F6F6" buttonfacecolor="Control"
buttonhighlightcolor="ControlLightLight" buttonshadowcolor="ControlDark">
</commandbar>
<sheets>
<FarPoint:SheetView SheetName="Sheet1">
</FarPoint:SheetView>
</sheets>
</FarPoint:FpSpread>
</ContentTemplate>
<%-- エラー発生の要因 [2/2] ↓ --%>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
<%-- エラー発生の要因 [2/2] ↑ --%>
</asp:UpdatePanel>
</div>
</form>
------------------------------------
Webフォームクラス
------------------------------------
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' データの作成
Dim maxParentRows As Integer = 10 - 1
Dim maxChildRows As Integer = 5 - 1
Dim ds As New DataSet()
Dim Parent As DataTable = ds.Tables.Add("Parent")
Parent.DefaultView.AllowNew = False
Parent.Columns.Add("ParentA", GetType(Int32))
For i As Integer = 0 To maxParentRows
Parent.Rows.Add(i)
Next
Dim child As DataTable = ds.Tables.Add("Child")
child.DefaultView.AllowNew = False
child.Columns.Add("ChildA", GetType(Int32))
child.Columns.Add("ChildB", GetType(String))
For i As Integer = 0 To maxParentRows
For j As Integer = 0 To maxChildRows
child.Rows.Add(i, String.Format("P{0}C{1}", i, j))
Next
Next
ds.Relations.Add("PCRelation", Parent.Columns("ParentA"), child.Columns("ChildA"))
' SPREADの設定
FpSpread1.ActiveSheetView.DataSource = ds
FpSpread1.ActiveSheetView.PageSize = 10
' エラー発生の要因 [1/2]
For i As Integer = 0 To FpSpread1.ActiveSheetView.RowCount - 1
FpSpread1.ActiveSheetView.ExpandRow(i, True)
Next
End Sub
End Class
回避方法
Service Pack 3(v8.0.4004.2010)で修正済み。
Service Pack 3(v8.0.4004.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------
製品のオブジェクト解放処理を適切に行うことで、本現象の回避が可能です。
【回避コード】
------------------------------------
クライアント側スクリプト
------------------------------------
<script>
window.onload = function () {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);
var app = Sys.Application;
app.add_unload(ApplicationUnload);
}
function ApplicationUnload(sender) {
Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(beginRequestHandler);
}
function beginRequestHandler(sender, args) {
var updatePanels = args.get_updatePanelsToUpdate();
if (updatePanels == null || updatePanels.length == 0)
updatePanels = sender._updatePanelClientIDs;
if (updatePanels) {
for (var i = 0; i < updatePanels.length; i++) {
var pnl = document.getElementById(updatePanels[i]);
if (pnl) {
wrapDispose(pnl);
}
}
}
}
function wrapDispose(container) {
var divs = container.getElementsByTagName("DIV");
for (var i = 0; i < divs.length; i++) {
var spread = divs[i];
if (spread.getAttribute("FpSpread") == "Spread" && spread.dispose && !spread.__dispose) {
spread.__dispose = spread.dispose;
spread.dispose = __safeDispose;
}
}
}
function __safeDispose(arg) {
if (this.__dispose) {
try {
if (this.Behavior == null) {
this.__dispose = null;
return;
}
this.__dispose(arg);
} catch (e) {
console.log(e.message);
}
}
}
</script>
Service Pack 3(v8.0.4004.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------
製品のオブジェクト解放処理を適切に行うことで、本現象の回避が可能です。
【回避コード】
------------------------------------
クライアント側スクリプト
------------------------------------
<script>
window.onload = function () {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);
var app = Sys.Application;
app.add_unload(ApplicationUnload);
}
function ApplicationUnload(sender) {
Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(beginRequestHandler);
}
function beginRequestHandler(sender, args) {
var updatePanels = args.get_updatePanelsToUpdate();
if (updatePanels == null || updatePanels.length == 0)
updatePanels = sender._updatePanelClientIDs;
if (updatePanels) {
for (var i = 0; i < updatePanels.length; i++) {
var pnl = document.getElementById(updatePanels[i]);
if (pnl) {
wrapDispose(pnl);
}
}
}
}
function wrapDispose(container) {
var divs = container.getElementsByTagName("DIV");
for (var i = 0; i < divs.length; i++) {
var spread = divs[i];
if (spread.getAttribute("FpSpread") == "Spread" && spread.dispose && !spread.__dispose) {
spread.__dispose = spread.dispose;
spread.dispose = __safeDispose;
}
}
}
function __safeDispose(arg) {
if (this.__dispose) {
try {
if (this.Behavior == null) {
this.__dispose = null;
return;
}
this.__dispose(arg);
} catch (e) {
console.log(e.message);
}
}
}
</script>