O resultado gerado por um Sitecore Sheer UI dialog apagava o valor do campo Rich Text Editor. Qual era o problema e como resolvi?

Ao trabalhar com Sitecore depois de um tempo, nos deparamos com requisitos a serem implementados que são bem corriqueiros, como criar um botão no Rich Text editor e realizar alguma ação. Porém e se o botão abrir uma janela de Sheer UI, da qual você precise selecionar um valor e atualizar um campo no rich text editor?

Você conseguiria mas o valor do campo pode ser sobrescrito. Se você está procurando por uma solução para esse comportamento descrito, continue lendo 🙂

CENARIO

Neste cenário eu criei um botão no Rich Text Editor e quando o usuário clicava o botão, um comando de abrir uma janela de Sheer UI era disparado, e o usuario poderia selecionar de uma lista e depois um link era gerado e mostrado no editor a partir do valor selecionado. O problema, como mencionei a pouco, é que o restante do conteúdo era apagado. O link que eu estava gerando era similar a qualquer link de midia gerado pelo Sitecore:

 

<a href="~/media/c91e6ce67216446c8c2af1ae5d2a8120.ashx">PDF_test</a>

O meu diálogo Sheer herda de Sitecore.Web.UI.Pages.DialogForm. Eis como o método OnOk do meu diálogo foi definido(adaptado para este post). A variável dialogValue era uma string que continha um link, e passava ele para a janela de Sheer.

protected override void OnOK(object sender, EventArgs args)
{
        //previous code cleared from this question
        //this would bring the link to be assigned to the dialog
        var dialogValue = AssetService.GetValue();
        SheerResponse.SetDialogValue(dialogValue);
        base.OnOK(sender, args);
}

Este era o command que eu implementei no arquivo RichTextCommands.js para fazer a chamada da janela de Sheer:

Telerik.Web.UI.Editor.CommandList["SelectAsset"] = function (commandName, editor, args) {
    scEditor = editor;

    editor.showExternalDialog(
        "/sitecore/shell/default.aspx?xmlcontrol=SelectAsset&currentItemId=" + scItemID + "&assetType=link",
        null, //argument
        1105,
        700,
        scInsertSitecoreLink,
        null,
        "Asset",
        true, //modal
        Telerik.Web.UI.WindowBehaviors.Close, // behaviors
        false, //showStatusBar
        false //showTitleBar
    );
};


SOLUÇÃO

Para resolver esse problema existem algumas coisas que precisam serem feitas. Abaixo seguem 4 passos que fiz para resolvê-las.

1- Defina as funções de javascript em um arquivo de js:


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();
}

Note a função scClose. Esta função será referenciada abaixo on método OnOk. Em outras palavras, quando o usuário clica na janela de Sheer no botão OK, e depois que o processamento do lado do servidor terminou, esta função de js é chamada no lado do cliente(ver passo 4)

2- Referencie o arquivo de js que você criou no arquivo XML do seu diálogo Sheer.

3- Na classe de code beside do diálogo adicione uma nova propriedade. No meu caso ela ficou definida assim:

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;
      }
}

4- No método OnOk agora a variável dialogValue é um objeto com duas propriedades: Url e Text. Após realizar essas mudanças o método OnOk ficou definido assim:


          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.Value) + ")");
            

Note que na clausula else, o método base.OnOk não está sendo chamado mas sim o método Eval referenciando a função scClose e passando os parametros url e text(utilizados para construir o link). No fim o resultado era um link no mesmo formato descrito no início deste post mas o conteúdo do campo Rich Text editor não era mais apagado

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s