I wrote two posts on the integration and customization of FCKEditor in ASP.NET web application, today I will show how to use FCKEditor to update record.
This demo consists of a GridView with an Edit button for each row which upon clicked will load a DetailsView, and the DetailsView has a field called Note where the FCKEditor is used to update it.
1. GridView layout:
<asp:GridView ID="gvCustomerList" runat="server" AutoGenerateColumns="False" CssClass="grid" Width="100%" CellPadding="6" DataKeyNames="CustomerID"> <Columns> <asp:TemplateField HeaderText="Action"> <ItemTemplate> <asp:Button ID="btnEdit" runat="server" CommandName="cmdEdit" Text="Edit" CommandArgument='<%# Eval("CustomerID") %>' /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="CustomerID" HeaderText="ID" /> <asp:BoundField HeaderText="First Name" DataField="CustomerFirstName" /> <asp:BoundField HeaderText="Last Name" DataField="CustomerLastName" /> <asp:BoundField HeaderText="Phone" DataField="CustomerPhone" /> <asp:BoundField HeaderText="Email" DataField="CustomerEmail" /> <asp:BoundField HeaderText="Note" DataField="Note" HtmlEncode="False" /> </Columns> <RowStyle CssClass="grid-item" /> <AlternatingRowStyle CssClass="grid-alternating-item" /> <HeaderStyle CssClass="grid-header" /> </asp:GridView>
2. DetailsView layout:
<asp:Panel ID="pnlEditCustomer" runat="server" CssClass="popup-div-background"> <asp:Panel ID="pnlCustomerDetails" runat="server" CssClass="popup-div-front"> <asp:DetailsView ID="dvEditCustomer" runat="server" DefaultMode="Edit" AutoGenerateRows="False" Width="100%" DataKeyNames="CustomerID"> <Fields> <asp:BoundField DataField="CustomerID" HeaderText="Customer ID" ReadOnly="True" /> <asp:BoundField DataField="CustomerFirstName" HeaderText="First Name" ReadOnly="True" /> <asp:BoundField DataField="CustomerLastName" HeaderText="Last Name" ReadOnly="True" /> <asp:BoundField DataField="CustomerPhone" HeaderText="Phone" ReadOnly="True" /> <asp:BoundField DataField="CustomerEmail" HeaderText="Email" ReadOnly="True" /> <asp:TemplateField HeaderText="Note"> <ItemTemplate> <FCKeditorV2:FCKeditor ID="fckEditorNote" runat="server" Value='<%#Bind("Note") %>' ToolbarSet="Basic"> </FCKeditorV2:FCKeditor> </ItemTemplate> </asp:TemplateField> <asp:CommandField ShowEditButton="True" /> </Fields> </asp:DetailsView> </asp:Panel> </asp:Panel>
Both the GridView and DetailsView are defined in an UpdatePanel. The reason that the DetailsView is within two Panel controls is that I use AJAX ModalPopupExtender to load the DetailsView when user clicks the Edit button in the GridView. Here is the ModalPopupExtender:
4. ModalPopupExtender for loading the DetailsView
<cc1:ModalPopupExtender ID="mpeEditEmployee" runat="server" TargetControlID="lblPopupTargetID" PopupControlID="pnlEditCustomer"> </cc1:ModalPopupExtender>
TargetControlID=”lblPopupTargetID” is a trick for using AJAX ModalPopupExtender with GridView and “lblPopupTargetID” is a Label control in the UpdatePanel hidden by CSS style. The reason of this trick is that the Edit button that triggers the ModalPopup is defined in a TemplateField of the GridView and cannot be assigned directly to TargetControlID property, and you cannot assign this property on the fly either. However, if we assign TargetControlID to a hidden Label, how can we trigger the ModalPopup? The answer is we will trigger it from code behind by using ModalPopupExtender.Show() function.
5. Code Behind Functions
5.1 Bind GridView
Let’s add a function called LoadCustomerList() to bind the GridView control. This function will be called in Page_Load event handler:
Private Sub LoadCustomerList() Dim dt As New DataTable If (Session("CustomerDT") Is Nothing) Then Dim dc As New DataColumn("CustomerID", _ System.Type.GetType("System.Int32")) dt.Columns.Add(dc) dc = New DataColumn("CustomerFirstName", _ System.Type.GetType("System.String")) dt.Columns.Add(dc) dc = New DataColumn("CustomerLastName", _ System.Type.GetType("System.String")) dt.Columns.Add(dc) dc = New DataColumn("CustomerPhone", _ System.Type.GetType("System.String")) dt.Columns.Add(dc) dc = New DataColumn("CustomerEmail", _ System.Type.GetType("System.String")) dt.Columns.Add(dc) dc = New DataColumn("Note", _ System.Type.GetType("System.String")) dt.Columns.Add(dc) Dim dr As DataRow For i As Integer = 1 To 10 dr = dt.NewRow dr("CustomerID") = i dr("CustomerFirstName") = "FirstName_" & i.ToString() dr("CustomerLastName") = "LastName_" & i.ToString() dr("CustomerPhone") = "123-456-7890" dr("CustomerEmail") = dr("CustomerFirstName").ToString() & _ "." & dr("CustomerLastName").ToString() & _ "@TechProsZone.net" dr("Note") = "Some random notes here." dt.Rows.Add(dr) Next Session("CustomerDT") = dt Else dt = CType(Session("CustomerDT"), DataTable) End If Me.gvCustomerList.DataSource = dt Me.gvCustomerList.DataBind() End Sub
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Me.LoadCustomerList() End If End Sub
In this example, I am not using any database to store and load data. In reality, the LoadCustomerList() function should be pulling data from your database.
5.2 Edit Button Clicked
When the Edit button is clicked, GridView’s RowCommand event is fired. We can use the GridView’s RowCommand event handler to populate the DetailsView and then display the ModalPopup:
Private Sub gvCustomerList_RowCommand(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) _ Handles gvCustomerList.RowCommand If (e.CommandName = "cmdEdit") Then Dim id As Integer = 0 Integer.TryParse(e.CommandArgument.ToString(), id) Dim dt As DataTable = CType(Session("CustomerDT"), DataTable) Dim dv As DataView = New DataView(dt) dv.RowFilter = "CustomerID=" & id.ToString() Me.dvEditCustomer.DataSource = dv Me.dvEditCustomer.DataBind() Me.dvEditCustomer.DefaultMode = DetailsViewMode.Edit Dim fckEditor As FredCK.FCKeditorV2.FCKeditor = _ Me.dvEditCustomer.FindControl("fckEditorNote") fckEditor.BasePath = Request.ApplicationPath & "/Common/fckeditor/" ViewState("CustomerID") = id.ToString() Me.mpeEditEmployee.Show() End If End Sub
5.3 DetailsView Update Button Clicked
When DetailsView’s Update button is clicked, then ItemUpdating event is fired. We can use ItemUpdating event handler to update the record and then hide the ModalPopup when the update is done. The trick here is first to find the DetailsView by casting the “sender” object to a DetailsView object, then to use FindControl to find the FCKEditor control within the DetailsView. Once the FCKEditor control is found, then you can access to the content by calling FCKEditor.Value:
Private Sub dvEditCustomer_ItemUpdating(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DetailsViewUpdateEventArgs) _ Handles dvEditCustomer.ItemUpdating Dim id As Integer = 0 Integer.TryParse(ViewState("CustomerID").ToString(), id) Dim dt As DataTable = CType(Session("CustomerDT"), DataTable) Dim drs As DataRow() = dt.Select("CustomerID=" & id.ToString()) Dim dr As DataRow = drs(0) Dim dv As DetailsView = CType(sender, DetailsView) Dim fckEditor As FredCK.FCKeditorV2.FCKeditor = dv.FindControl("fckEditorNote") dr("Note") = fckEditor.Value dt.AcceptChanges() Session("CustomerDT") = dt Me.LoadCustomerList() Me.mpeEditEmployee.Hide() End Sub
5.4 DetailsView Cancel Button Clicked
Finally we need to hide the ModalPopup when the DetailsView’s Cancel button is clicked. We can use ModeChanging event handler to hide the ModalPopup.
Private Sub dvEditCustomer_ModeChanging(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DetailsViewModeEventArgs) _ Handles dvEditCustomer.ModeChanging If (e.CancelingEdit) Then Me.mpeEditEmployee.Hide() End If End Sub
5.5 Final Note
You will need to set validateRequest=”false” in the Page directive for the page that uses FCKEditor, otherwise, ASP.NET will throw an exception when you try to submit your form: “A potentially dangerous Request.Form value was detected from the client…”.
If you want to see how it works, just follow this link to the demo.
UPDATE:
1. You don’t need to set validateRequest=”false”. It seems that the latest version of FCKEditor will take care of it for you.
2. Rob mentioned in the comment that the demo only works in IE. In FireFox, when you click the “Link” icon in FCKEditor, the popup dialog is behind the ModalPopup. It turns out that when ModalPopup is generated, its z-index is always reset to 100001 to ensure it is on top of other elements. To fix the problem, open FCKEditor’s fckconfig.js file and find a line says:
FCKConfig.FloatingPanelsZIndex = 10000 ;
Change it to a number larger than 100001, for example:
FCKConfig.FloatingPanelsZIndex = 100002 ;
This should fix the problem with FireFox.
Thanks Rob for reporting the problem.
Hi , i am having the problem with sample above that in firefox the fck dialog windows ( like the image editor or hyperlink insert dialog ) will appear behind the modal popup. However in IE8 it works. Do you happen to have any ideas how to solve this ?
@Rob,
Thanks for the comment. I am having the same problem and I am working on it to see if I can find a fix. Will update the post once I find a solution.
@Rob,
Open up fckconfig.js and find this line:
FCKConfig.FloatingPanelsZIndex = 100002 ;
100002 will ensure that the dialog window always on top of ModalPopup window.
@Jeffrey,
Unfortunately that didn’t work for me 🙁
@Shem,
Sometimes, browser will cache the JavaScript code, especially FireFox. You can try clearing your browser cache to see if it will help.
@Jeffrey
that did the trick!!!
Thanks for your help Jeff 😉
Glad it worked for you.