 |
|
 |
 |
Display an Iron Speed Designer Record Panel in Popup |
|
Learn how to display an Iron Speed Designer record panel in the built-in AJAX popup.
- Herman Chan, Founder of Presence Consulting Group
July 7, 2009
Iron Speed Designer V6.X
|
|
Introduction |
|
The record panel and the AJAX popup are two outstanding Iron Speed Designer features. A record panel
allows developers to display a database record in a professional-looking panel, in most cases without
the need to write a single line of custom code. The AJAX popup enables pages to deliver large amounts
of text and/or images on demand. This makes it easier to lay out pages and reduce the initial page load time.
Out-of-the-box a popup will display either text or image from a single database field, but not both.
It is possible to display both text and an image (i.e. a record panel) in the popup with just a few lines
of custom code. This article will show you how to customize your application to display an Iron Speed
Designer record panel in the built-in AJAX popup.

|
Where does this come from? |
|
This idea was inspired by ScottGu’s Blog:
Cool UI Templating Technique to use with ASP.NET AJAX for non-UpdatePanel scenarios.
We will design the record panel as a UserControl (.ascx), instead of an .aspx page. When the panel is requested on
AJAX calls, use the UserControl to render the panel, and return its HTML content as a string.
|
Implementation |
Step 1: Create a web service
Under the website root folder, we create a new web service using Microsoft Visual Studio’s Add New Item wizard.
Visual Studio will create a template .asmx file under the website root folder, and a template C# (or Visual Basic .NET)
file under App_Code folder. Insert the following code into the appropriate file.

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using BaseClasses.Data;
using BaseClasses.Utils;
using PopupPanelDemo.UI;
/// <summary>
/// Summary description for RecordPanelService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class RecordPanelService : System.Web.Services.WebService {
private static string businessLayerPrefix = "PopupPanelDemo.Business.";
public RecordPanelService() {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod(EnableSession = true)]
public string GetRecordPanel(string tblName, string pnlPath, string rcdId) {
// Find the App_Code assembly.
var appAssm = (from a in AppDomain.CurrentDomain.GetAssemblies()
where a.FullName.StartsWith("App_Code")
select a).First();
// Find the table or view class
string tblTypeFullName = businessLayerPrefix + tblName + "Table";
string tblQualifiedName = Assembly.CreateQualifiedName(appAssm.FullName,
tblTypeFullName);
Type tblType = Type.GetType(tblQualifiedName);
if (tblType == null) {
tblTypeFullName = businessLayerPrefix + tblName + "View";
tblQualifiedName = Assembly.CreateQualifiedName(appAssm.FullName, tblTypeFullName);
tblType = Type.GetType(tblQualifiedName);
if (tblType == null)
throw new Exception(string.Format("Cannot find class {0}Table or {0}View.", tblName));
}
// Retrieve the record
PrimaryKeyTable tblInstance = tblType.GetField("Instance").GetValue(null) as
PrimaryKeyTable;
PrimaryKeyRecord rcd = tblInstance.GetRecordData(rcdId, false) as PrimaryKeyRecord;
// Create a blank page and load the record panel user control.
Page pg = new BaseApplicationPage();
pg.EnableViewState = false;
Control panel = pg.LoadControl(pnlPath);
Control rcdCtrl = MiscUtils.FindControlRecursively(panel, string.Format("_{0}RecordControl",
tblName));
// Bind data to the panel
rcdCtrl.GetType().GetProperty("DataSource").SetValue(rcdCtrl, rcd, null);
rcdCtrl.DataBind();
// Render the page
HtmlForm tempForm = new HtmlForm();
tempForm.Controls.Add(panel);
pg.Controls.Add(tempForm);
StringWriter sw = new StringWriter();
try {
HttpContext.Current.Server.Execute(pg, sw, false);
} catch (Exception ex) {
string msg = ex.Message;
}
// Strip out the panel html
string outputToReturn = sw.ToString();
outputToReturn = outputToReturn.Substring(outputToReturn.IndexOf("<div%gt;"));
outputToReturn = outputToReturn.Substring(0, outputToReturn.IndexOf("</form>"));
return outputToReturn;
}
}
|
Visual Basic .NET
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Reflection
Imports System.Web
Imports System.Web.Services
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports BaseClasses.Data
Imports BaseClasses.Utils
Imports PopupPanelDemo.UI
''' <summary>
''' Summary description for RecordPanelService
''' </summary>
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
<WebService([Namespace] := "http://tempuri.org/")> _
<WebServiceBinding(ConformsTo := WsiProfiles.BasicProfile1_1)> _
<System.Web.Script.Services.ScriptService()> _
Public Class RecordPanelService
Inherits System.Web.Services.WebService
Private Shared businessLayerPrefix As String = "PopupPanelDemo.Business."
Public Sub New()
'Uncomment the following line if using designed components
'InitializeComponent();
End Sub
<WebMethod(EnableSession := True)> _
Public Function GetRecordPanel(ByVal tblName As String, ByVal pnlPath As String, ByVal rcdId
As String) As String
' Find the App_Code assembly.
Dim appAssm = (From a In AppDomain.CurrentDomain.GetAssemblies() _
Where a.FullName.StartsWith("App_Code") _
Select a).First()
' Find the table or view class
Dim tblTypeFullName As String = businessLayerPrefix + tblName & "Table"
Dim tblQualifiedName As String = Assembly.CreateQualifiedName(appAssm.FullName,
tblTypeFullName)
Dim tblType As Type = Type.[GetType](tblQualifiedName)
If tblType Is Nothing Then
tblTypeFullName = businessLayerPrefix + tblName & "View"
tblQualifiedName = Assembly.CreateQualifiedName(appAssm.FullName, tblTypeFullName)
tblType = Type.[GetType](tblQualifiedName)
If tblType Is Nothing Then
Throw New Exception(String.Format("Cannot find class {0}Table or {0}View.", tblName))
End If
End If
' Retrieve the record
Dim tblInstance As PrimaryKeyTable = TryCast(tblType.GetField("Instance").GetValue
(Nothing), PrimaryKeyTable)
Dim rcd As PrimaryKeyRecord = TryCast(tblInstance.GetRecordData(rcdId, False),
PrimaryKeyRecord)
' Create a blank page and load the record panel user control.
Dim pg As Page = New BaseApplicationPage()
pg.EnableViewState = False
Dim panel As Control = pg.LoadControl(pnlPath)
Dim rcdCtrl As Control = MiscUtils.FindControlRecursively(panel, String.Format("_{0}
RecordControl", tblName))
' Bind data to the panel
rcdCtrl.[GetType]().GetProperty("DataSource").SetValue(rcdCtrl, rcd, Nothing)
rcdCtrl.DataBind()
' Render the page
Dim tempForm As New HtmlForm()
tempForm.Controls.Add(panel)
pg.Controls.Add(tempForm)
Dim sw As New StringWriter()
Try
HttpContext.Current.Server.Execute(pg, sw, False)
Catch ex As Exception
Dim msg As String = ex.Message
End Try
' Strip out the panel html
Dim outputToReturn As String = sw.ToString()
outputToReturn = outputToReturn.Substring(outputToReturn.IndexOf("<div>"))
outputToReturn = outputToReturn.Substring(0, outputToReturn.IndexOf("</form>"))
Return outputToReturn
End Function
End Class
|
Step 2: Build a ShowRecord ascx UserControl
Create a new ShowRecord panel and save it as an .ascx UserControl. Configure and customize it as usual.
Turn off SmoothPanelUpdate on the record panel to ensure the web service executes successfully.
Alternatively, turn the panel heading off and use the popup frame in its place.
Step 3: Register the web service on calling page
In the calling page’s codebehind file (xxx.aspx.cs or xxx.aspx.vb), we register the web service
with the following code.
C#
public ApplicationList() {
this.Initialize();
Init += new EventHandler(ApplicationList_Init);
}
void ApplicationList_Init(object sender, EventArgs e) {
scriptManager1.Services.Add(new ServiceReference("~/RecordPanelService.asmx"));
}
|
Visual Basic .NET
Public Sub New()
Me.Initialize()
AddHandler Init, AddressOf ApplicationList_Init
End Sub
Private Sub ApplicationList_Init(ByVal sender As Object, ByVal e As EventArgs)
scriptManager1.Services.Add(New ServiceReference("~/RecordPanelService.asmx"))
End Sub
|
Step 4: Add JavaScript code to display popup on calling page
To display the web service’s return result (record panel HTML content) define a javascript function in
the xxx.html (.aspx) file. This calls the detailRolloverPopup() predefined in ApplicationWebForm.js.
If the calling page requires several different record panels with similar sizes, we can define a single
function to serve all panels. Or, depending on the scenario, we might want to define separate functions
for different panels.
JavaScript
<script type="text/javascript">
function popupApplicantDetail(result){
detailRolloverPopup("Applicant Detail", result, true, 350, 150, true);
}
</script>
|
Step 5: Customize the trigger control to call the web service
On the calling page, we place controls such as LinkButton or ImageButton to call the web service.
The following code adds the trigger to an ImageButton’s OnClick event. The code is in the
xxx.Controls.cs (xxx.Controls.vb) file.
C#
public class ApplicationsTableControlRow : BaseApplicationsTableControlRow {
public override void DataBind() {
base.DataBind();
if (DataSource != null) {
ApplicationsRowViewButton.Attributes["OnClick"] = string.Format(
"SaveMousePosition(event); RecordPanelService.GetRecordPanel('{0}', '{1}', '{2}',
popupApplicantDetail); return false;",
"Applications", "~/Applications/ApplicantDetail.ascx", DataSource.ID0.ToString());
}
}
}
|
Visual Basic .NET
Public Class ApplicationsTableControlRow
Inherits BaseApplicationsTableControlRow
Public Overloads Overrides Sub DataBind()
MyBase.DataBind()
If DataSource IsNot Nothing Then
ApplicationsRowViewButton.Attributes("OnClick") = String.Format("SaveMousePosition(event)
; RecordPanelService.GetRecordPanel('{0}', '{1}', '{2}', popupApplicantDetail); return
false;", "Applications", "~/Applications/ApplicantDetail.ascx", DataSource.ID0.ToString())
End If
End Sub
End Class
|
|
Conclusion |
|
Displaying a record panel in the AJAX popup combines two excellent Iron Speed Designer features and is an attractive
alternative to redirect to a separate ShowRecord page. This is especially true where the record panel content is
more appropriately displayed as a popup.
|
Download |
|
Popup Demo project (Iron Speed Designer v6.1.0)
|
About the Author |
|
Herman Chan, PMP, MCAD.NET, J2CP, is the founder of Presence Consulting Group. With over 12 years of experience in
Information Technology, he has assumed different technical roles which include project manager, development lead,
independent technical consultant, developer, etc. He is passionate about technology and always believes delivering
good user experience is one of the most important aspects of software development. Currently, he is leading various
technical projects with a consulting, service-oriented approach.
Presence Consulting Group is an established technical consulting firm servicing a wide range of clients, ranging
from land management company to direct mail marketers. Our services include .NET consulting, Iron Speed Designer
training, database modeling, creative website design, and project management.
|
|
|
|
|
|