原文地址:https://www.wipfli.com/insights/blogs/connect-microsoft-dynamics-365-blog/160810-calling-custom-actions-from-javascript
Overview
Actions in processes are a way to create custom messages in CRM for an entity. For example, let’s say you have an entity record that needs escalation or approval. You could create a custom action that performs the steps needed for this process. Then you could add a button to the form that the user clicks to initiate the process. Out of the box for most entities, you have Create, Update, Delete, Assign, and SetState messages and you have the option of writing custom business logic in the form of Plugins or Workflows on these. With custom actions, you have the ability to create whatever message you need to fulfil your requirements. Then you can attach plugin code to that message and perform any operations you need without restrictions. In this post, I am going to explain how to create a custom action, pass input and output parameters, and call that action from JavaScript. With these basic building blocks, you can create whatever you need.
Overall Process
The example I am going to document here will involve a button on the ribbon that, when clicked, will display a notification on the form, call the custom action, will run a plugin, will call a web service to get the temperature for the account's zip code, will return that information, and will display it in a notification on the form. In this case, we are going to have a plugin that will do all the real work. There will be JavaScript that will handle the form notifications and calling the action.
The result will look like this:
To make all this happen, I will be using a couple of JavaScript libraries that make working with custom Actions and Notifications much easier. The first one is called Notify.js and can be found
here. This library makes it easy to display form notifications and adds some functionality to the standard CRM notifications. The second one is called Process.js and can be found
here. This library simplifies calling custom actions from JavaScript. Calling custom actions involves creating rather lengthy XML Http Requests and this library simplifies that down to a function call with a couple of parameters. It also provides callbacks for success and errors.
The process looks something like this.
The components needed for this are:
- A Custom Action
- JavaScript Web Resource (to call the custom action)
- Custom Ribbon button (to call the JavaScript)
- Plugin to call the weather web service
- Notify.js library
- Process.js library
Components
The Custom Action
In this example, the custom action is fairly simple. We just need a couple of parameters. The custom action gives us a way to pass the parameters to and from the plugin. It also allows us to register the plugin step against the custom action message.
JavaScript Web Resource
The JavaScript manages the notifications and calling the custom action. It will validate that we have a Zip Code, load the input parameters, and then call the custom action. When the action completes, it will call the success callback and display the information on the form as a notification. While the action is working, there will be a notification on the form letting the user know that something is happening.
function CallAction() {
//Verify that we have a Zip Code
if (Xrm.Page.getAttribute("address1_postalcode").getValue() == null) {
Notify.add("Zip code is missing", "ERROR", "nozip", null, 5);
}
else {
//Display the notification that we are working on something
Notify.add("Processing Action...", "LOADING", "myProcessing");
//Load the input parameters
var inputParams = [
{ key: "ParamPostalCode", type: Process.Type.String, value: Xrm.Page.getAttribute("address1_postalcode").getValue() },
{ key: "Target", type: Process.Type.EntityReference, value: new Process.EntityReference(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId()) }
];
//Call the custom action
Process.callAction("wipfli_GetWeather", inputParams, successCallback, errorCallback);
}
}
function successCallback(params) {
//Get the result from the plugin and display the information in a notification
var outputParamOne = params["OutputParamOne"];
Notify.add(outputParamOne, "INFO", "mySuccess", [{ type: "button", text: "Clear", callback: function () { Notify.remove("mySuccess"); } }]);
Notify.remove("myProcessing");
}
function errorCallback(error, trace) {
Notify.remove("myProcessing");
Notify.add("Error: " + error, "ERROR", "myError");
}
Custom Ribbon Button
The ribbon button just has to call the "CallAction" function from the above JavaScript. Use the Ribbon Workbench for CRM to create a custom button that points to a web resource and calls the CallAction function.
Plugin
The plugin will read the input parameters and then call the weather web service. Using the response from the web service, it will format the output information and then return it in the output parameter. Don’t forget to register the plugin using the Plugin Registration Tool in the CRM SDK. Then register a step on the GetWeather message.
protected override void ExecuteCrmPlugin(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
//Get the parameters from the Action call
EntityReference accountRef = (EntityReference)localContext.PluginExecutionContext.InputParameters["Target"];
string paramPostalCode = (string)localContext.PluginExecutionContext.InputParameters["ParamPostalCode"];
string webAddress = @"http://api.openweathermap.org/data/2.5/weather?zip=" + paramPostalCode + ",us&mode=xml&units=imperial&appid={your specific APPID}";
string output = "";
try
{
using (WebClient client = new WebClient())
{
Byte[] responseBytes = client.DownloadData(webAddress);
String response = Encoding.UTF8.GetString(responseBytes);
localContext.TracingService.Trace("Response is: " + response);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(response);
XmlNodeList current = xmlDoc.SelectNodes("/current");
foreach (XmlNode xn in current)
{
output = xn["city"].Attributes["name"].Value + " is " + Math.Round(Double.Parse(xn["temperature"].Attributes["value"].Value), 0) + " " + xn["temperature"].Attributes["unit"].Value;
}
localContext.TracingService.Trace("OUTPUT IS: " + output);
}
}
catch (WebException exception)
{
string str = string.Empty;
if (exception.Response != null)
{
using (StreamReader reader =
new StreamReader(exception.Response.GetResponseStream()))
{
str = reader.ReadToEnd();
}
exception.Response.Close();
}
if (exception.Status == WebExceptionStatus.Timeout)
{
throw new InvalidPluginExecutionException(
"The timeout elapsed while attempting to issue the request.", exception);
}
throw new InvalidPluginExecutionException(String.Format(CultureInfo.InvariantCulture,
"A Web exception occurred while attempting to issue the request. {0}: {1}",
exception.Message, str), exception);
}
localContext.PluginExecutionContext.OutputParameters["OutputParamOne"] = output;
}
Additional Libraries
The Notifiy.js and Process.js libraries will need to be loaded on the form. To do this, include them as form libraries in the Form Properties.
Conclusion
With all the components in place, clicking the button should produce the weather notification. While this example may not be very useful in the real world, the purpose was to demonstrate some of the basic concepts of custom actions. It shows you how to call a custom action from JavaScript and pass input and output parameters. It also demonstrates triggering a Plugin from a custom action.
- Installation Phases and In-Script Execution for Custom Actions in Windows Installer
用 InstallShield 依照 Custom Action Wizard 创建 Custom Action 时,会遇到下面的几个选项: In-Script Execution Install U ...
- custom event in javascript and jquery
javascript: // add a eventListener document.addEventListener("abc", function(){alert('this ...
- [转]UIWebView的Javascript运行时对象
An alternative, that may get you rejected from the app store, is to use WebScriptObject. These APIs ...
- WIX Custom Action (immediate, deffered, rollback)
Following content is directly reprinted from From MSI to WiX, Part 19 - The Art of Custom Action, Pa ...
- I Take It All Back: Using Windows Installer (MSI) Rollback Actions
Original Link: http://blogs.flexerasoftware.com/installtalk/2011/10/i-take-it-all-back-using-windows ...
- Default Custom Action Locations and IDs
Default Custom Action Locations and IDs SharePoint 2013 The following ta ...
- Wix打包系列(三)自定义Action(Custom Action)
原文:Wix打包系列(三)自定义Action(Custom Action) 3.1 关于Action 我们已经知道如何生成具有标准安装界面的安装程序了,Windows Installer按照我们的界面 ...
- How To Add Custom Build Steps and Commands To setup.py
转自:https://jichu4n.com/posts/how-to-add-custom-build-steps-and-commands-to-setuppy/ A setup.py scrip ...
- 所有selenium相关的库
通过爬虫 获取 官方文档库 如果想获取 相应的库 修改对应配置即可 代码如下 from urllib.parse import urljoin import requests from lxml im ...
随机推荐
- HTTP rfc是什么及其工作过程
概念: HTTP协议描述的是发送方与接收方的通信协议,通过两方的自觉遵守而存在,HTTP是运行于应用层的协议,基于TCP协议而运作.基本上是客户/服务器对答模式,其中也包括在传输过程中的代理,网关,通 ...
- call、apply、bind,你有多了解?
call.apply.bind 1.相同也不同 我们先从浅显的部分开始讲, 这三个方法都可以改变this的指向,都可以进行传参,第一个参数都是修改this的指向 call() 和 apply() 改变 ...
- 老司机浅谈linux系统学习技巧
Linux起源于20世纪70年代,是一种优秀的操作系统系统.初次接触到linux这个系统是在大学期间,这样才发现除了windows外的另外一个有趣系统.开始抱着好奇的心态去了解,随着深入学习,笔者被它 ...
- java课堂笔记3
- Vue解决同一页面跳转页面不更新
问题分析:路由之间的切换,其实就是组件之间的切换,不是真正的页面切换.这也会导致一个问题,就是引用相同组件的时候,会导致该组件无法更新. 方案一:使用 watch 进行监听 watch: { /* = ...
- java中的\b是什么意思?
java中有2个地方有\b,一个是特殊字符\b,另一个是在正则表达式中表示边界的意思. 我们这里只讨论特殊字符\b 我这里一共接受到几种解释: 1.退格符相当于键盘上的Backspace符号 back ...
- ADO.NET之SqlConnection、sqlcommand的应用(学习笔记)
一.知识描述点 1.SqlConnection (1)使用SqlConnection类可以连接到SQL Server数据库.SqlConnection对象的主要属性和方法如下: ——属性:Connec ...
- C#获取文件目录
Form1.cs using System;using System.Collections.Generic;using System.ComponentModel;using System.Data ...
- Ubuntu虚拟机屏幕自适应与文件拖拽复制方法
使用VMware-tools的替代品:open-vm-tools 安装步骤: 1 更新下系统源 sudo apt update 2 安装open-vm-tools sudo apt install o ...
- IOS Block代码块的定义与使用
代码块的本质是和其他的变量类似,不同的是,代码块存储的数据是一个函数体.使用代码块,你可以像调用其他标准函数一样的调用,可以传入参数,并得到返回值. 脱字符是代码块的语法标记.下图表示代码块的 ...