CRM 2013 Javascript Object Model - UI

by Pedro Azevedo 30. August 2014 19:48

Boas pessoal,

 

Mais um post sobre o object model. Desta vez estaremos a ver o “namespace” Xrm.Page.ui.

 

Xrm.Page.ui.close()

Como o próprio nome diz fecha o formulário, infelizmente não conseguir tirar um printscreen Cool mas acreditem que funciona.

function closeTest() {
	Xrm.Page.ui.close();
}

 

formSelector.getCurrentItem

function getCurrentItemTest() {
                var formSelect = Xrm.Page.ui.formSelector.getCurrentItem();
                if (formSelect == null) {
                               Xrm.Utility.alertDialog("é nulo quando existe apenas um form para escolha");
                }
                else {
                               Xrm.Utility.alertDialog("Este é o form escolhido: " + item.getLabel());
                }
}

formSelector.items
function formSelectorItemsTest() {
                Xrm.Page.ui.formSelector.items.forEach(function (item, index) {
                               Xrm.Utility.alertDialog(item.getLabel());
                });
}

Xrm.Page.ui.getViewPortHeight() e Xrm.Page.ui.getViewPortWidth()
function getViewPortHeightWidthTest() {
                Xrm.Utility.alertDialog("Largura: " + Xrm.Page.ui.getViewPortWidth() + ", Altura: " + Xrm.Page.ui.getViewPortHeight());
}

Xrm.Page.ui.getCurrentControl()

function getCurrentControlTest() {
                var currentControl = Xrm.Page.ui.getCurrentControl();
                if (currentControl == null) {
                               alert("Não há controlos com focus");
                }
                else {
                               alert("O controlo com focus é o '" + currentControl.getLabel());
                }
}

Xrm.Page.ui.getFormType()

Valores possíveis de retorno deste método:

Valor

Tipo de formulário

0

Undefined

1

Create (Dá para Quick Create)

2

Update

3

Read Only

4

Disabled

5

Quick Create (Deprecated)

6

Bulk Edit

11

Read Optimized (Deprecated)

function getFormTypeTest() {
                Xrm.Utility.alertDialog(Xrm.Page.ui.getFormType());
}

navigation.items

 

Xrm.Page.ui.setFormNotification(message, level, uniqueId)

Os valores possíveis para definir o nível da mensagem, referir também que o elemento uniqueid deve-se dar uma id único para podermos retirar mais tarde esta notificação.

ERROR

Notification will use the system error icon

WARNING

Notification will use the system warning icon

INFO

Notification will use the system info icon

function setFormNotificationTest() {
                Xrm.Page.ui.setFormNotification("Isto é um teste as notificações", "INFO", "TesteNotificacaoInfo");
}

Xrm.Page.ui.clearFormNotification(uniqueId)
function clearFormNotificationTest() {
                Xrm.Page.ui.clearFormNotification("TesteNotificacaoInfo");
}

 

Mais uma vez não consigo tirar um screenshot que ajude por isso acreditem que funciona.

Xrm.Page.ui.refreshRibbon()

Este método permite refrescar a ribbon, mas o que isto significa? Por exemplo quando temos um botão na ribbon onde o seu estado depende de um valor no formulário, se este for alterado agora podemos dizer que queremos que ele aplique novamente as regras.

function refreshRibbonTest() {
                Xrm.Page.ui.refreshRibbon();
}

 

 

Neste caso coloquei uma condição baseada no campo email, só mostra o botão se o valor for psazevedo@psa.com

 

Até a próxima.

Tags: , , ,

Colocar uma subgrid disabled in CRM 2013

by Pedro Azevedo 23. August 2014 01:24

Boas pessoal,

Há algum tempo nos fóruns de discussão surgiu a dúvida de como colocar uma grid readonly criei um script na altura e foram surgindo várias dúvidas e eu fui complementando o script. Por isso estou aqui para explicar e partilhar o script. Este post será atualizado sempre que surgir problemas de não funcionar ou quando falhar numa atualização da Microsoft.

Este script não está no seu código mais atualizado mas espero que num futuro próximo espero melhorar muito. Por exemplo uma coisa que não gosto é misturar Javascript puro como JQuery.

Para começar e como primeira alternativa foi tentar usar o seguinte código:

document.getElementById(gridName).disabled = "true";

Mas este código não tem qualquer efeito na grid, pelo menos no CRM Online. Por isso o meu primeiro objetivo foi prevenir que o utilizador pudesse abrir um registo na grid, para isso apliquei o seguinte código:

disableSubgrid = function(gridName) {
	var subgridArea = document.getElementById(gridName + "_divDataArea");
	if (subgridArea != null) {
		var subgridTable = subgridArea.childNodes[0].childNodes[1];
                              
		for(j = 1; j < subgridTable.rows[i].cells.length; j++) { 
			if (subgridTable.rows[i].cells[j].childNodes[0].childNodes[0] != null && subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].nodeName == "A") {
				subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].outerHTML = subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].innerText;
			}
		}
	}
}

Este código retirei desta thread num fórum de discussão mas este não funciona totalmente pois a primeira coluna ficava sem dados, a thread era especifica para a versão 2011. Para além disso não tratava do double-click.

Com base nesse código fiz a minha própria versão para que este comportamento não acontecesse e tratar do double-click:

disableSubgrid = function(gridName) {
	var subgridArea = document.getElementById(gridName + "_divDataArea");
	if (subgridArea != null) {
		var subgridTable = subgridArea.childNodes[0].childNodes[1];
                              
		for(i = 1; i < subgridTable.rows.length; i++) {
			subgridTable.rows[i].ondblclick=function(e){
				if (!e)
					e = window.event;

				if (e.stopPropagation) {
					e.stopPropagation();
				}
				else {
					e.cancelBubble = true;
				}
			};
			
			for(j = 1; j < subgridTable.rows[i].cells.length; j++) { 
				if (subgridTable.rows[i].cells[j].childNodes[0].childNodes[0] != null && subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].nodeName == "A") {
					var node = subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].childNodes[0];
					subgridTable.rows[i].cells[j].childNodes[0].removeChild(subgridTable.rows[i].cells[j].childNodes[0].childNodes[0]);
					subgridTable.rows[i].cells[j].childNodes[0].appendChild(node);
				}
			}
		}
	}
}

 

Este código funciona muito bem, só que tem um problema quando ordenamos ele voltava a recarregar a lista e tanto o link com o double-click passavam a funcionar:

Aqui a minha primeira opção era apanhar o reload da sub-grid mas não conseguir por isso a minha solução foi desativar a funcionalidade de ordenar, com este código em JQuery:

$("#" + gridName + " .ms-crm-List-Sortable").bind("click", function(event){
	event.stopPropagation();
});

Com este código aplicado ele não consegue ordenar logo fica tudo bem J não é a melhor opção mas por agora funciona. Agora só faltava desabilitar os botões de adicionar e de mostrar o detalhe dos registos, aqui também recorri ao JQuery:

$("#" + gridName + "_addImageButtonImage").bind("click", function(event){
	event.stopPropagation();
});

$("#" + gridName + "_openAssociatedGridViewImageButtonImage").bind("click", function(event){
	event.stopPropagation();
});

Et voilà tornamos a nossa subgrid totalmente disabled. Vejam o código completo usado, onde também tentei tornar o mais dinâmico possível para isso bastando passar o nome da sub-grid:

disableSubgrid = function(gridName) {
	var subgridArea = document.getElementById(gridName + "_divDataArea");
	if (subgridArea != null) {
		$("#" + gridName + " .ms-crm-List-Sortable").bind("click", function(event){
			event.stopPropagation();
		});
		
		$("#" + gridName + "_addImageButtonImage").bind("click", function(event){
			event.stopPropagation();
		});

		$("#" + gridName + "_openAssociatedGridViewImageButtonImage").bind("click", function(event){
			event.stopPropagation();
		});

		var subgridTable = subgridArea.childNodes[0].childNodes[1];
                              
		for(i = 1; i < subgridTable.rows.length; i++) {
			subgridTable.rows[i].ondblclick=function(e){
				if (!e)
					e = window.event;

				if (e.stopPropagation) {
					e.stopPropagation();
				}
				else {
					e.cancelBubble = true;
				}
			};
			
			for(j = 1; j < subgridTable.rows[i].cells.length; j++) { 
				if (subgridTable.rows[i].cells[j].childNodes[0].childNodes[0] != null && subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].nodeName == "A") {
					var node = subgridTable.rows[i].cells[j].childNodes[0].childNodes[0].childNodes[0];
					subgridTable.rows[i].cells[j].childNodes[0].removeChild(subgridTable.rows[i].cells[j].childNodes[0].childNodes[0]);
					subgridTable.rows[i].cells[j].childNodes[0].appendChild(node);
				}
			}
		}
	}
	else {
		setTimeout("disableSubgrid('" + gridName + "');", 1500);
	}
}

function onload() {
	setTimeout("disableSubgrid('Contacts');", 1500);
	setTimeout("disableSubgrid('accountopportunitiesgrid');", 1500);
}

 

 

PS: Se tiverem problemas coloquem nos comentários ou coloquem a dúvida no fórum de discussão.

 

Até a próxima

Tags: , , , ,

Como obter guids de registos

by Pedro Azevedo 15. August 2014 08:16

Boas pessoal,

Vou iniciar hoje um conjunto de pelo menos dois artigos onde vou tentar resumir as várias formas que temos para obter os vários tipos de guids e nas duas versões 2011 e 2013. Para começar adicionei uma nova entrada no dicionário de CRM com o que significa GUID.

Hoje vou falar em várias possibilidades de obter os guids de registos, num futuro post irei falar como obter guids de vários objetos. O mais comum é obtermos o guid de um registo, se tivermos dentro desse registo temos várias opções:

CRM 2011

No CRM 2011 podemos obter o guid através do URL, mas quase ele esteja no modo aplicação abre assim:

Não temos URL então podemos fazer F11 ou CTRL+N e conseguimos ver o URL associado:

Seleccionamos o URL e retiramos o que queremos:

http://server/org/main.aspx?etc=3&extraqs=%3f_gridType%3d3%26etc%3d3%26id%3d%257b64E808B4-3A1A-E311-9B18-005056907305%257d%26pagemode%3diframe%26preloadcache%3d1412850657742%26rskey%3d566790654&pagetype=entityrecord

CRM 2013

No CRM 2013 aparentemente deixamos de ter a opção de obtermos através do URL, então uma possibilidade passa por utilizarmos este botão:

Obtemos um email e de onde podemos extrair o guid deste registo:

A. Datum Corporation (sample)
<https://cmfazevedo.crm4.dynamics.com/main.aspx?etc=1&extraqs=formid%3d8448b78f-8f42-454e-8e2a-f8196b0419af&id=%7b0DDD50D8-021E-E411-892E-2C59E541AD08%7d&pagetype=entityrecord>

Bem o que disse anteriormente e como vimos no CRM 2011 deixámos de ver o guid no URL, caso façamos popup desse registo obtemos um URL com o guid:

 

https://cmfazevedo.crm4.dynamics.com/main.aspx?etc=1&extraqs=&histKey=604351270&id={0DDD50D8-021E-E411-892E-2C59E541AD08}&newWindow=true&pagetype=entityrecord#945933055

Outra possibilidade e que funciona para as duas versões é colocar um botão (vou mostrar como fazer mais adiante) para mostrar o guid e para isso basta usar o seguinte código:

function showMeGuid() {
    prompt("Este é o teu GUID",  Xrm.Page.data.entity.getId());
}

 

Este pedaço de código Xrm.Page.data.entity.getId() é o mais importante, é o que permite obter o guid do registo atual.

Agora vamos ver o caso de numa lista de registos querermos saber quais os registos que estão selecionados, para este exemplo vou mostrar como criar o botão com o Ribbon Workbench para refrescar a memória e para mostrar como trabalhar com parâmetros por defeito.

Vamos então acrecentar um botão:

 

Para executar uma ação teremos que adicionar um comando, este comando adicionamos regras para mostrar e tornar disable. Mas onde me quero focar é nas “actions”:

Adiciono uma nova ação de Javascript:

 Dentro da configuração da ação para a chamada de uma função Javascript temos que especificar qual o Recurso Web e qual a função dentro desse recurso que queremos chamar. Para o primeiro caso bastava este passo:

 Mas agora o objetivo é que o CRM nos passe os registos selecionados, conseguimos indicar através dos “parameters”, que neste caso é um parâmetro do CRM:

Como podemos ver podemos passar vários parâmetros, neste caso existe um parâmetro mesmo para aquilo que queremos:

 Terminada a nossa configuração do comando podemos associá-la ao nosso botão:

 E é este o resultado:

Outra maneira que habitualmente queremos saber o guid de um registo é quando temos um lookup no formulário e temos um registo selecionado, aqui recorremos a um post já realizado para ver como podemos aceder a estes dados.

 

Até a próxima

Tags: , , , ,

CRM 2013 Javascript Object Model - Data

by Pedro Azevedo 8. August 2014 02:34

 Boas pessoal,

Continuando a “saga” dos métodos Javascript vamos agora ver os métodos Xrm.Page.data.

Xrm.Page.data.getIsValid()

function getIsValidTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.getIsValid());
}

Xrm.Page.data.refresh(save).then(successCallback, errorCallback)

Esta função refresh recebe um booleano para dizer se queremos que ele salve depois do formulário ser refrescado. Depois existe a possibilidade de passar funções quando houver sucesso ou insucesso na execução da função.

function refreshTest()
{
                Xrm.Page.data.refresh(false).then(function() {
                                               Xrm.Utility.alertDialog("Sucesso no refrescamento");
                               },
                               function() {
                                               Xrm.Utility.alertDialog("Erro no refrescamento");
                });
}

Esta caixa aparece porque como estou a colocar o evento no onchange de um campo do CRM, ele verifica que estamos a querer refrescar a página sem guardarmos as alterações.

Xrm.Page.data.save().then(successCallback, errorCallback)

function saveTest() {
                Xrm.Page.data.save().then(function() {
                                               Xrm.Utility.alertDialog("Sucesso no save");
                               },
                               function() {
                                               Xrm.Utility.alertDialog("Erro no save");
                });
}

As duas últimas funções são muito rápidas isto porque o refrescamento é só dos dados e não da página inteira.

 

Até a próxima.

Tags: , , , , ,

About

Muito bem casado, Pai babado e um gosto muito grande pela tecnologia.

Tenho um lema "Sharing is Learning"

Mais aqui -> http://www.psazevedo.com

Month List