Skip to content

Commit 3d7ccc0

Browse files
csharpfritzCopilot
andcommitted
feat: add PostBack + ScriptManager demo page (Phase 2)
- PostBackDemo/Index.razor with GetPostBackEventReference, hyperlink, and ScriptManager sections - Stable element IDs for Playwright integration testing (postback-button, postback-link, scriptmanager-target, etc.) - Added to ComponentCatalog.cs under Migration Helpers category - Added to ComponentList.razor under Migration Helpers section - Inherits WebFormsPageBase for PostBack event, ClientScript access, and ScriptManagerShim.GetCurrent(this) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0c75aba commit 3d7ccc0

3 files changed

Lines changed: 217 additions & 0 deletions

File tree

samples/AfterBlazorServerSide/ComponentCatalog.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ public static class ComponentCatalog
200200
Keywords: new[] { "response", "redirect", "navigation", "tilde", "aspx", "migration", "shim" }),
201201
new("IsPostBack", "Migration Helpers", "/migration/ispostback", "IsPostBack status, guard pattern, and IsHttpContextAvailable check",
202202
Keywords: new[] { "ispostback", "postback", "guard", "httpcontext", "lifecycle", "migration", "shim" }),
203+
new("PostBack Demo", "Migration Helpers", "/ControlSamples/PostBackDemo", "GetPostBackEventReference, GetPostBackClientHyperlink, and ScriptManager.GetCurrent demos",
204+
Keywords: new[] { "postback", "dopostback", "scriptmanager", "clientscript", "hyperlink", "callback", "migration", "shim" }),
203205

204206
// Cross-Cutting / Base Properties
205207
new("BaseProperties", "Utility", "/ControlSamples/BaseProperties", "AccessKey, ToolTip, BackColor, ForeColor and other base class properties",

samples/AfterBlazorServerSide/Components/Pages/ComponentList.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
<ul>
108108
<li><a href="/ControlSamples/ClientScript">ClientScript (IJSRuntime)</a></li>
109109
<li><a href="/ControlSamples/ClientScriptShim">ClientScriptShim (Zero-Rewrite)</a></li>
110+
<li><a href="/ControlSamples/PostBackDemo">PostBack &amp; ScriptManager</a></li>
110111
</ul>
111112

112113
<h3>Migration Tools</h3>
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
@page "/ControlSamples/PostBackDemo"
2+
@inherits WebFormsPageBase
3+
4+
<PageTitle>PostBack &amp; ScriptManager Demo</PageTitle>
5+
6+
<h2>PostBack &amp; ScriptManager Demo</h2>
7+
8+
<p>This sample demonstrates the Phase 2 <strong>ClientScript</strong> postback shims.
9+
These methods return the same JavaScript strings as Web Forms, letting migrated
10+
code-behind work unchanged in Blazor.</p>
11+
12+
<div class="alert alert-info">
13+
<h4 class="alert-heading">💡 What this shows</h4>
14+
<ul class="mb-0">
15+
<li><code>GetPostBackEventReference()</code> — returns a <code>__doPostBack('id','arg')</code> JS string</li>
16+
<li><code>GetPostBackClientHyperlink()</code> — returns a <code>javascript:__doPostBack(...)</code> URL</li>
17+
<li><code>ScriptManagerShim.GetCurrent(this)</code> — obtains a ScriptManager, registers startup scripts</li>
18+
</ul>
19+
</div>
20+
21+
<hr />
22+
23+
@* ═══════════════════════════ Section 1: GetPostBackEventReference ═══════════════════════════ *@
24+
25+
<h3>1. GetPostBackEventReference</h3>
26+
27+
<p><code>ClientScript.GetPostBackEventReference(this, "save")</code> returns a
28+
<code>__doPostBack</code> call string — the same pattern Web Forms uses for server-side
29+
event wiring.</p>
30+
31+
<div class="row">
32+
<div class="col-md-6">
33+
<h4>Before (Web Forms)</h4>
34+
<pre><code class="language-csharp">string script = ClientScript.GetPostBackEventReference(this, "save");
35+
btnSave.Attributes["onclick"] = script;</code></pre>
36+
</div>
37+
<div class="col-md-6">
38+
<h4>After (Blazor with BWFC)</h4>
39+
<pre><code class="language-csharp">// Same API — works unchanged
40+
_postBackScript = ClientScript.GetPostBackEventReference(this, "save");
41+
// Wire via onclick="@@_postBackScript"</code></pre>
42+
</div>
43+
</div>
44+
45+
<div class="card mt-3" data-audit-control="postback-event-reference-demo">
46+
<div class="card-body">
47+
<h5 class="card-title">Live Demo — PostBack via Button</h5>
48+
<p>Click the button to fire <code>__doPostBack</code> from JavaScript.
49+
The <code>PostBack</code> event on <code>WebFormsPageBase</code> receives it server-side.</p>
50+
<button id="postback-button" class="btn btn-primary" onclick="@_postBackScript">
51+
Trigger PostBack
52+
</button>
53+
<p class="mt-2">Generated script: <code id="postback-script">@_postBackScript</code></p>
54+
<p id="postback-result" class="fw-bold">@_postBackMessage</p>
55+
</div>
56+
</div>
57+
58+
<hr />
59+
60+
@* ═══════════════════════════ Section 2: GetPostBackClientHyperlink ═══════════════════════════ *@
61+
62+
<h3>2. GetPostBackClientHyperlink</h3>
63+
64+
<p><code>ClientScript.GetPostBackClientHyperlink(this, "navigate")</code> returns a
65+
<code>javascript:__doPostBack(...)</code> URL — drop it into an <code>href</code>
66+
and it triggers a postback when clicked.</p>
67+
68+
<div class="row">
69+
<div class="col-md-6">
70+
<h4>Before (Web Forms)</h4>
71+
<pre><code class="language-csharp">lnk.NavigateUrl = ClientScript.GetPostBackClientHyperlink(this, "navigate");</code></pre>
72+
</div>
73+
<div class="col-md-6">
74+
<h4>After (Blazor with BWFC)</h4>
75+
<pre><code class="language-csharp">// Same call
76+
_hyperlink = ClientScript.GetPostBackClientHyperlink(this, "navigate");</code></pre>
77+
</div>
78+
</div>
79+
80+
<div class="card mt-3" data-audit-control="postback-hyperlink-demo">
81+
<div class="card-body">
82+
<h5 class="card-title">Live Demo — PostBack via Hyperlink</h5>
83+
<p>An anchor tag whose <code>href</code> is a <code>javascript:__doPostBack</code> URL:</p>
84+
<a id="postback-link" href="@_postBackHyperlink" class="btn btn-outline-primary">
85+
Click to PostBack via Link
86+
</a>
87+
<p class="mt-2">Generated href: <code id="hyperlink-script">@_postBackHyperlink</code></p>
88+
<p id="hyperlink-result" class="fw-bold">@_hyperlinkMessage</p>
89+
</div>
90+
</div>
91+
92+
<hr />
93+
94+
@* ═══════════════════════════ Section 3: ScriptManager.GetCurrent ═══════════════════════════ *@
95+
96+
<h3>3. ScriptManager.GetCurrent</h3>
97+
98+
<p><code>ScriptManager.GetCurrent(this)</code> returns a <code>ScriptManagerShim</code> that
99+
wraps <code>ClientScriptShim</code>. You can call <code>RegisterStartupScript</code> on it —
100+
the same code you wrote in Web Forms.</p>
101+
102+
<div class="row">
103+
<div class="col-md-6">
104+
<h4>Before (Web Forms)</h4>
105+
<pre><code class="language-csharp">var sm = ScriptManager.GetCurrent(this);
106+
sm.RegisterStartupScript(GetType(), "init",
107+
"document.getElementById('target').innerText = 'Hello!';",
108+
true);</code></pre>
109+
</div>
110+
<div class="col-md-6">
111+
<h4>After (Blazor with BWFC)</h4>
112+
<pre><code class="language-csharp">// Same pattern
113+
var sm = ScriptManagerShim.GetCurrent(this);
114+
sm.RegisterStartupScript(GetType(), "init",
115+
"document.getElementById('target').innerText = 'Hello!';",
116+
true);</code></pre>
117+
</div>
118+
</div>
119+
120+
<div class="card mt-3" data-audit-control="scriptmanager-getcurrent-demo">
121+
<div class="card-body">
122+
<h5 class="card-title">Live Demo — ScriptManager Startup Script</h5>
123+
<p>On first render, <code>ScriptManagerShim.GetCurrent(this).RegisterStartupScript(...)</code>
124+
sets the text below via JavaScript — just like Web Forms.</p>
125+
<div id="scriptmanager-target" class="alert alert-secondary">
126+
(waiting for startup script…)
127+
</div>
128+
</div>
129+
</div>
130+
131+
<hr />
132+
133+
@* ═══════════════════════════ Section 4: Source Code ═══════════════════════════ *@
134+
135+
<h3>Source Code</h3>
136+
137+
<pre><code class="language-csharp">@@page "/ControlSamples/PostBackDemo"
138+
@@inherits WebFormsPageBase
139+
140+
@@code {
141+
private string _postBackScript = "";
142+
private string _postBackMessage = "No postback received yet.";
143+
private string _postBackHyperlink = "";
144+
private string _hyperlinkMessage = "No hyperlink postback received yet.";
145+
146+
protected override void OnInitialized()
147+
{
148+
base.OnInitialized();
149+
150+
// GetPostBackEventReference — same call as Web Forms
151+
_postBackScript = ClientScript.GetPostBackEventReference(this, "save");
152+
153+
// GetPostBackClientHyperlink — same call as Web Forms
154+
_postBackHyperlink = ClientScript.GetPostBackClientHyperlink(this, "navigate");
155+
156+
// Subscribe to PostBack event
157+
PostBack += (sender, args) =>
158+
{
159+
if (args.EventArgument == "save")
160+
_postBackMessage = $"PostBack received! Target: {args.EventTarget}, Argument: {args.EventArgument}";
161+
else if (args.EventArgument == "navigate")
162+
_hyperlinkMessage = $"Hyperlink PostBack! Target: {args.EventTarget}, Argument: {args.EventArgument}";
163+
StateHasChanged();
164+
};
165+
}
166+
167+
protected override void OnAfterRender(bool firstRender)
168+
{
169+
if (firstRender)
170+
{
171+
var sm = ScriptManagerShim.GetCurrent(this);
172+
sm.RegisterStartupScript(GetType(), "smDemo",
173+
"document.getElementById('scriptmanager-target').innerText = " +
174+
"'ScriptManager startup script executed!';",
175+
true);
176+
}
177+
}
178+
}</code></pre>
179+
180+
@code {
181+
private string _postBackScript = "";
182+
private string _postBackMessage = "No postback received yet.";
183+
private string _postBackHyperlink = "";
184+
private string _hyperlinkMessage = "No hyperlink postback received yet.";
185+
186+
protected override void OnInitialized()
187+
{
188+
base.OnInitialized();
189+
190+
_postBackScript = ClientScript.GetPostBackEventReference(this, "save");
191+
_postBackHyperlink = ClientScript.GetPostBackClientHyperlink(this, "navigate");
192+
193+
PostBack += (sender, args) =>
194+
{
195+
if (args.EventArgument == "save")
196+
_postBackMessage = $"PostBack received! Target: {args.EventTarget}, Argument: {args.EventArgument}";
197+
else if (args.EventArgument == "navigate")
198+
_hyperlinkMessage = $"Hyperlink PostBack! Target: {args.EventTarget}, Argument: {args.EventArgument}";
199+
200+
StateHasChanged();
201+
};
202+
}
203+
204+
protected override void OnAfterRender(bool firstRender)
205+
{
206+
if (firstRender)
207+
{
208+
var sm = ScriptManagerShim.GetCurrent(this);
209+
sm.RegisterStartupScript(GetType(), "smDemo",
210+
"document.getElementById('scriptmanager-target').innerText = 'ScriptManager startup script executed!';",
211+
true);
212+
}
213+
}
214+
}

0 commit comments

Comments
 (0)