I wrote two posts before regarding the integration and the customization of FCKEditor in ASP.NET and was asked by a reader how to use the “Save” icon in the FCKEditor’s toolbar set to perform the actual save on the server side. I am sorry for the long delayed answer for that question because I have been tied up with my work and haven’t had much time to look into the problem until recently.
When the “Save” icon in FCKEditor’s toolbar is clicked, a PostBack is generated. The reason is that it initiates a JavaScript function call to submit the form automatically. The question is how to capture this PostBack? The intuitive place to check is Page_Load event handler:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not IsPostBack Then 'Set up FCKEditor's BasePath Me.fckEditorNote.BasePath = Request.ApplicationPath & "/Common/fckeditor/" 'Perform Page Load tasks, if any Else 'Capture PostBack and then save data here End If End Sub
This will work if you don’t have any other server control that cause PostBack. However, the more common scenario is you have some other server controls that also cause PostBack, such as Button, LinkButton, HyperLink, ImageButton, etc., then the above code will not be able to tell which PostBack was caused by the “Save” icon and which was caused by the other server controls. The good news is that ASP.NET injects two famous hidden fields when a page is rendered: “__EVENTTARGET” and “__EVENTARGUMENT”. “__EVENTTARGET” stores the control that causes the PostBack and “__EVENTARGUMENT” stores the argument of the PostBack, and they are populated only when a PostBack is generated by server control. It means that if the “Save” icon is clicked, then “__EVENTTARGET” field will have an empty value upon PostBack, so it tells us that the PostBack is caused by the “Save” icon, not a server control. The above code can be modified as follows:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not IsPostBack Then 'Set up FCKEditor's BasePath Me.fckEditorNote.BasePath = Request.ApplicationPath & "/Common/fckeditor/" 'Perform Page Load tasks, if any Else 'Capture PostBack here Dim ctrlPostback As String = Request.Params.Get("__EVENTTARGET") If (ctrlPostback = "") Then 'Save icon clicked? 'Save data here Me.SaveRecords() End If End If End Sub
The above code works fine until you have Button control and ImageButton control on your page because when a Button (or ImageButton) control is clicked, __EVENTTARGET is not populated and the above code will still think the PostBack is coming from the “Save” icon. The reason that __EVENTTARGET is not populated is that those controls are rendered as <input type=”submit”>, which will just submit the form. So if there is any server control on the page that will be rendered as <input type=”submit”>, the above code will not work as expected.
So what are we gonna do then? What we can do is to use another hidden field to store the source of the PostBack (from client or server), then in the code behind we first check “__EVENTTARGET”, if it is empty, then we check this hidden field to see where the PostBack came from. If it came from client, then we know the PostBack was caused by the “Save” icon, otherwise, it was caused by a server control, then we can skip it to let the control’s event handler to take over the process.
Here is the hidden field:
<asp:HiddenField ID="hdnPostBackSource" runat="server" Value="Client" />
The Page_Load is modified as follows:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not IsPostBack Then 'Set up FCKEditor's BasePath Me.fckEditorNote.BasePath = Request.ApplicationPath & "/Common/fckeditor/" 'Perform Page Load tasks, if any Else 'Capture PostBack here Dim ctrlPostback As String = Request.Params.Get("__EVENTTARGET") If (ctrlPostback = "" AndAlso Me.hdnPostBackSource.Value = "Client") Then 'Save icon is clicked 'Save data here Me.SaveRecords() 'This is just a function to save content in FCKEditor End If End If End Sub
Now the question is: if a Button control is clicked, how do we change this hidden field before Page_Load gets fired. The answer is to use JavaScript to change the value of hdnPostBackSource:
<script type="text/javascript"> function setPostBackSource() { var ctrl = document.getElementById('<%=hdnPostBackSource.ClientID() %>'); ctrl.value="Server"; } </script>
And set the Button control’s OnClientClick=”setPostBackSource()”:
<asp:Button ID="btnSave" runat="server" Text="Save" OnClientClick="setPostBackSource()" />
Remember, for any server control that will not populate __EVENTTARGET field upon PostBack, you will need to add OnClientClick=”setPostBackSource()”.
Here is the complete code snippet of the code behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not IsPostBack Then 'Set up FCKEditor's BasePath Me.fckEditorNote.BasePath = Request.ApplicationPath & "/Common/fckeditor/" 'Perform Page Load tasks, if any Else 'Capture PostBack here Dim ctrlPostback As String = Request.Params.Get("__EVENTTARGET") If (ctrlPostback = "" AndAlso Me.hdnPostBackSource.Value = "Client") Then 'Save icon is clicked 'Save data here Page.Validate() 'Must call this first before Page.IsValid If (Page.IsValid()) Then Me.SaveRecords() 'This is just a function to save content in FCKEditor End If End If End If End Sub Protected Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnSave.Click If (Page.IsValid) Then Me.SaveRecords()
'Remember to reset the hidden field Me.hdnPostBackSource.Value = "Client"
'Perform additional tasks if needed
End If End Sub Protected Sub SaveRecords() Me.lblResults.Text = Me.fckEditorNote.Value End Sub
I hope this will help someone and appreciate any comment on this post.