Sometimes it is the simple things that can jam you up. One example is creating a button on a Rich Text editor that will perform a specific action. Easy, right? One might think so. But, what happens when the button opens a Sheer UI dialog and it gets the value from the dialog? Things get a little messier. All of a sudden, you may notice the field value in Rich Text Editor is missing or you get the value but the rest of the content in the Rich Text Editor is now gone.
Check out this scenario:
I had created a new button in the Rich Text Editor. When a user selected this button, I implemented a command that would open a Sheer UI dialog allowing the user to select from a list. I wanted to build a link that would show in the Rich Text Editor based on the selection done on the dialog. The problem was, my content was getting erased.
The link I was building had a value similar to many Sitecore media links like:
<a href="~/media/c91e6ce67216446c8c2af1ae5d2a8120.ashx">My link text</a>
My dialog inherits from Sitecore.Web.UI.Pages.DialogForm. Here is a look at my dialog using the OnOK override method (adapted for the post). The dialogValue would get a link in a string format to pass to the dialog.
protected override void OnOK(object sender, EventArgs args) { //previous code cleared for post purpose... //brings the link to be assigned to the dialog var dialogValue = AssetService.GetValue(); SheerResponse.SetDialogValue(dialogValue); //Calls the base dialog OnOk method base.OnOK(sender, args); }
This custom command set in the RichTextCommands.js is invoking the dialog:
Telerik.Web.UI.Editor.CommandList["SelectAsset"] = function (commandName, editor, args) { var d = Telerik.Web.UI.Editor.CommandList._getLinkArgument(editor); Telerik.Web.UI.Editor.CommandList._getDialogArguments(d, "A", editor, "DocumentManager"); scEditor = editor; editor.showExternalDialog( "/sitecore/shell/default.aspx?xmlcontrol=SelectAsset&currentItemId=" + scItemID + "&assetType=rtelink", null, //argument 1100, 700, scInsertSitecoreLink, //callback null, // callback args "Insert Link", true, //modal Telerik.Web.UI.WindowBehaviors.Close, // behaviors false, //showStatusBar false //showTitleBar ); };
Here are 4 quick steps to resolve the issue
- Define the following Javascript functions on any js file.
Please note the function scClose. This is the function that you will see referenced below in the OnOk method from the Sheer UI dialog. In effect, when the user clicks the dialog Ok button and the server side processing is done, the js function will get triggered on the client side. (I will reference this again in Step 4.)
function GetDialogArguments() { return getRadWindow().ClientParameters; } function getRadWindow() { if (window.radWindow) { return window.radWindow; } if (window.frameElement && window.frameElement.radWindow) { return window.frameElement.radWindow; } return null; } var isRadWindow = true; var radWindow = getRadWindow(); if (radWindow) { if (window.dialogArguments) { radWindow.Window = window; } } function scClose(url, text) { //builds the link and anchor name var returnValue = { url: url, text: text }; getRadWindow().close(returnValue); } function scCancel() { getRadWindow().close(); }
- Make sure you reference your newly created js file on the Dialog XML.
- Add a new property in the Dialog code, beside class. My property definition looks like this:
protected string Mode{ get{ string str = StringUtil.GetString(this.ServerProperties["Mode"]); if (!string.IsNullOrEmpty(str)) return str; return "shell"; } set{ Assert.ArgumentNotNull((object)value, "value"); this.ServerProperties["Mode"] = (object)value; } }
- Look for the OnOk method on the code beside file. In my case, the example above would get the link value and call the SheerResponse.SetDialogValue, passing a link string to it as well as calling the base.OnOk method. Now the dialogValue variable is an object instead of a string and it has two new string properties: Url and Text. Note that on the else clause the base.OnOk method is not being called; instead, the Eval method referencing the scClose function is passing the url and the text (which are used to build the link). After changes are done to the OnOk method, this is how it looks:
var dialogValue = AssetService.GetRawValue(); //Rich text asset if (this.Mode == "webedit" || dialogValue == null) { SheerResponse.SetDialogValue(StringUtil.EscapeJavascriptString(dialogValue)); base.OnOK(sender, args); } else //writes the url and link name(dialogValue .Value). This will build the link on the Rich Text Editor SheerResponse.Eval("scClose(" + StringUtil.EscapeJavascriptString(dialogValue.Url) + "," + StringUtil.EscapeJavascriptString(dialogValue.Text) + ")");
Use these 4 simple steps and you will no longer lose your content or field values in the Rich Text Editor when using a Sheer UI dialog.
Happy coding my friends. Until next time. Diego