zoukankan      html  css  js  c++  java
  • 无依赖简单易用的Dynamics 365公共视图克隆工具

    本人微信公众号:微软动态CRM专家罗勇 ,回复279或者20180818可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me 。

    Dynamics 365 Customer Engagement 新建实体后会自动建立一些公共视图,默认情况下,我们会修改实体的默认公共视图,让他显示更多的列和合适的排序和筛选。但是很多人会觉得比较耗时去修改其他的视图,如果不修改,用户切换到其他视图,默认只有两三列,变化比较大,用户体验不大好。

    那么问题来了,有没有工具可以克隆公共视图呢?当然在克隆的时候保留目标视图的筛选条件,我今天就开发了一个这样的无依赖简单易用的工具,就是一个HTML Web资源,为了方便使用没有引用第三方JavaScript类库。

    可以选择实体,选择一个源视图,一次克隆到这个实体的一个或者多个公共视图。

    代码如下,可以看到Web API功能很强大了,查询元数据,执行操作,比如发布实体等以前做不了的操作都不在话下了,赞。

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dynamics 365公共视图克隆工具_罗勇原创_www.luoyong.me</title>
        <script src="../../../ClientGlobalContext.js.aspx" type="text/javascript"></script>
        <script type="text/javascript">
            var clientUrl = "";
            var savedQueries;
            var targetEntityName = "";
            function initPage() {
                if (typeof GetGlobalContext != "undefined") {
                    crmclientcontext = GetGlobalContext();
                } else {
                    throw new Error("引入ClientGlobalContext.js.aspx失败,请检查!");
                }
                clientUrl = crmclientcontext.getClientUrl() + "/api/data/v8.2/";
                var req = new XMLHttpRequest();
                req.open("GET", encodeURI(clientUrl + "EntityDefinitions?$select=LogicalName&$filter=IsCustomizable/Value eq true"), false);
                req.setRequestHeader("Accept", "application/json");
                req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                req.setRequestHeader("OData-MaxVersion", "4.0");
                req.setRequestHeader("OData-Version", "4.0");
                req.onreadystatechange = function () {
                    if (this.readyState == 4 /* complete */) {
                        req.onreadystatechange = null;
                        if (this.status == 200) {
                            var responseJson = JSON.parse(this.responseText);
                            var targetEntitySelect= document.getElementById("TargetEntity");
                            if (responseJson.value.length >= 1) {
                                var recordCount = responseJson.value.length;
                                for (var i = 0; i < recordCount; i++) {
                                    var option = document.createElement('option');
                                    option.text = option.value = responseJson.value[i].LogicalName;
                                    targetEntitySelect.add(option, 0);
                                }
                            }
                        }
                        else {
                            errorCallback(JSON.parse(this.responseText));
                        }
                    }
                };
                req.send();
            }
    
            function targetEntityOnChange() {
                var targetEntitySelect = document.getElementById("TargetEntity");
                targetEntityName = targetEntitySelect.options[targetEntitySelect.selectedIndex].value;
                if (targetEntityName != "nothing") {
                    var req = new XMLHttpRequest();
                    req.open("GET", encodeURI(clientUrl + "savedqueries?$select=name,savedqueryid,layoutxml,fetchxml,isdefault,querytype&$filter=returnedtypecode eq '" + targetEntityName + "' and createdon ne null&$orderby=name asc"), false);
                    req.setRequestHeader("Accept", "application/json");
                    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                    req.setRequestHeader("OData-MaxVersion", "4.0");
                    req.setRequestHeader("OData-Version", "4.0");
                    req.onreadystatechange = function () {
                        if (this.readyState == 4 /* complete */) {
                            req.onreadystatechange = null;
                            if (this.status == 200) {
                                var responseJson = JSON.parse(this.responseText);
                                var sourceSavedQuerySelect = document.getElementById("SourceSavedQuery");
                                var targetSavedQueryFieldset = document.getElementById("TargetSavedQuery");
                                sourceSavedQuerySelect.options.length = 0;
                                while (targetSavedQueryFieldset.firstChild) {
                                    targetSavedQueryFieldset.removeChild(targetSavedQueryFieldset.firstChild);
                                }
                                savedQueries = responseJson.value;
                                if (responseJson.value.length >= 1) {
                                    var recordCount = responseJson.value.length;
                                    for (var i = 0; i < recordCount; i++) {
                                        var option = document.createElement('option');
                                        option.value = responseJson.value[i].savedqueryid;
                                        option.text = responseJson.value[i].name;
                                        if (responseJson.value[i].isdefault == true && responseJson.value[i].querytype == 0) {
                                            option.selected = true;
                                        }
                                        sourceSavedQuerySelect.add(option, 0);
                                        
                                        var checkbox = document.createElement('input');
                                        checkbox.type = "checkbox";
                                        checkbox.name = "savedquerygroup";
                                        checkbox.value = responseJson.value[i].savedqueryid;
                                        checkbox.id = "savedquery" + i;
                                        var label = document.createElement('label');
                                        label.htmlFor = "savedquery" + i;
                                        label.appendChild(document.createTextNode(responseJson.value[i].name));
                                        targetSavedQueryFieldset.appendChild(checkbox);
                                        targetSavedQueryFieldset.appendChild(label);
                                    }
                                }
                            }
                            else {
                                errorCallback(JSON.parse(this.responseText));
                            }
                        }
                    };
                    req.send();
                }
            }
    
            function getSaveQueryObj(savedQueryId) {
                var returnVal = {};
                var recordCount = savedQueries.length;
                for (var i = 0; i < recordCount; i++) {
                    if (savedQueries[i].savedqueryid == savedQueryId) {
                        returnVal.fetchxml = savedQueries[i].fetchxml;
                        returnVal.layoutxml = savedQueries[i].layoutxml;
                        returnVal.savedqueryid = savedQueries[i].savedqueryid;
                        returnVal.name = savedQueries[i].name;
                    }
                }
                return returnVal;
            }
    
            function Copy() {
                var sourceSavedQuerySelect = document.getElementById("SourceSavedQuery");
                var sourceSavedQueryId = sourceSavedQuerySelect.options[sourceSavedQuerySelect.selectedIndex].value;
                var sourceFetchXml = getSaveQueryObj(sourceSavedQueryId).fetchxml;
                var sourceFetchXmlBeforeFilter = "";
                var sourceFetchXmlAfterFilter = "";
                var sourceFetchXmlFilterStart = sourceFetchXml.indexOf('<filter');
                var sourceFetchXmlFilterEnd = sourceFetchXml.lastIndexOf('</filter>');
                if (sourceFetchXmlFilterStart >= 0) {
                    sourceFetchXmlBeforeFilter = sourceFetchXml.substring(0, sourceFetchXmlFilterStart);
                    sourceFetchXmlAfterFilter = sourceFetchXml.substring(sourceFetchXmlFilterEnd + 9);
                }
                else {
                    sourceFetchXmlBeforeFilter = sourceFetchXml;
                }
                //console.log("source savedquery id=" + sourceSavedQueryId);
                //console.log("source savedquery name=" + getSaveQueryObj(sourceSavedQueryId).name);
                //console.log("source savedquery fetchxml=" + getSaveQueryObj(sourceSavedQueryId).fetchxml);
                //console.log("sourceFetchXmlBeforeFilter=" + sourceFetchXmlBeforeFilter);
                //console.log("sourceFetchXmlAfterFilter=" + sourceFetchXmlAfterFilter);
                //console.log("source savedquery layoutxml=" + getSaveQueryObj(sourceSavedQueryId).layoutxml);
                var selectedTargetSavedQueries = document.forms['myForm'].elements['savedquerygroup'];
                var j = 0;
                for (var i = 0, len = selectedTargetSavedQueries.length; i < len; i++) {
                    if (selectedTargetSavedQueries[i].checked) {
                        //console.log("target savedquery id=" + selectedTargetSavedQueries[i].value);
                        //console.log("target savedquery name=" + getSaveQueryObj(selectedTargetSavedQueries[i].value).name);
                        //console.log("target savedquery fetchxml=" + getSaveQueryObj(selectedTargetSavedQueries[i].value).fetchxml);
                        var targetFetchXml = getSaveQueryObj(selectedTargetSavedQueries[i].value).fetchxml;
                        var targetFetchXmlFilter = "";
                        var targetFetchXmlFilterStart = targetFetchXml.indexOf('<filter');
                        var targetFetchXmlFilterEnd = targetFetchXml.lastIndexOf('</filter>');
                        if (targetFetchXmlFilterStart >= 0) {
                            targetFetchXmlFilter = targetFetchXml.substring(targetFetchXmlFilterStart, targetFetchXmlFilterEnd + 9);
                        }
                        //console.log("targetFetchXmlFilter=" + targetFetchXmlFilter);
                        //console.log("new fetchxml=" + sourceFetchXmlBeforeFilter + targetFetchXmlFilter + sourceFetchXmlAfterFilter);
                        //console.log("target savedquery layoutxml=" + getSaveQueryObj(selectedTargetSavedQueries[i].value).layoutxml);
    
                        var updateObj = {};
                        updateObj.fetchxml = sourceFetchXmlBeforeFilter + targetFetchXmlFilter + sourceFetchXmlAfterFilter;
                        updateObj.layoutxml = getSaveQueryObj(sourceSavedQueryId).layoutxml;
                        var req = new XMLHttpRequest();
                        req.open("PATCH", encodeURI(clientUrl + "savedqueries" + "(" + selectedTargetSavedQueries[i].value + ")"), false);
                        req.setRequestHeader("Accept", "application/json");
                        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                        req.setRequestHeader("OData-MaxVersion", "4.0");
                        req.setRequestHeader("OData-Version", "4.0");
                        req.onreadystatechange = function () {
                            if (this.readyState == 4 /* complete */) {
                                req.onreadystatechange = null;
                                if (this.status == 204) {
                                    j++;
                                }
                                else {
                                    errorCallback(JSON.parse(this.responseText));
                                }
                            }
                        };
                        req.send(JSON.stringify(updateObj));
                    }
                }
                Xrm.Utility.alertDialog("成功克隆到" + j + "个视图!");
            }
    
            function CopyAndPublish() {
                Copy();
                var pulishObj = {};
                pulishObj.ParameterXml = "<importexportxml><entities><entity>" + targetEntityName + "</entity></entities></importexportxml>";
                var req = new XMLHttpRequest();
                req.open("POST", encodeURI(clientUrl + "PublishXml"), true);
                req.setRequestHeader("Accept", "application/json");
                req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                req.setRequestHeader("OData-MaxVersion", "4.0");
                req.setRequestHeader("OData-Version", "4.0");
                req.onreadystatechange = function () {
                    if (this.readyState == 4 /* complete */) {
                        req.onreadystatechange = null;
                        if (this.status == 204) {
                            Xrm.Utility.alertDialog("发布实体【" + targetEntityName + "】成功,去看看效果吧!");
                        }
                        else {
                            errorCallback(JSON.parse(this.responseText));
                        }
                    }
                };
                req.send(JSON.stringify(pulishObj));
            }
    
            function errorCallback(errorJson) {
                console.log(errorJson);
                if (typeof errorJson.error.message === "string") {
                    Xrm.Utility.alertDialog("执行FetchXml出错!" + errorJson.error.message);
                }
                else {
                    Xrm.Utility.alertDialog("执行FetchXml出错,请查看console中的输出信息!");
                }
            }
        </script>
    </head>
    <body onload="initPage()">
        <h3>罗勇原创的Dynamics 365公共视图克隆工具_会保留目标视图的筛选条件</h3>
        <p>请选择实体: <select id="TargetEntity" onchange="targetEntityOnChange()"><option value="nothing">请选择</option></select></p>
        <p>请选择源视图:<select id="SourceSavedQuery"><option value="nothing">请选择</option></select></p>
        <form id="myForm" action="#" method="post">
            <fieldset id="TargetSavedQuery">
                <legend>请选择目标视图</legend>
            </fieldset>
        </form>
        <p><button id="copy" onclick="Copy()">仅复制不发布</button>&nbsp;&nbsp;&nbsp;<button id="copyandpublish" onclick="CopyAndPublish()">复制并且发布</button></p>
    </body>
    </html>

    打开初始界面如下:

    我选择一个实体后,源视图会默认为该实体的默认公共视图,当然你可以修改,可以选择一个或者多个目标视图,如下:

    我这这里选择复制到两个公共视图。下面有有两个按钮,分别为【仅复制不发布】和【复制并且发布】,前面的按钮仅仅更改,不发布,可以等到一定的量后一起发布,而且发布我们知道也是会锁数据库的,会造成Dynamics 365的卡顿,所以不一定修改后经常发布。若需要复制后立即发布的话点击第二个按钮【复制并且发布】,我这里点击这个按钮,会提示两次,分别如下:

     发布后刷新看看效果,目标视图的列和排序和源视图一样了,但是筛选是保留源视图本身的,搞定。

  • 相关阅读:
    input填入字符会出现黄色
    安装Scrapy时出现问题scrapy unicodedecodeerror ascii codec cant decode byte 0xd1 in position
    SVN 出现:Previous operation has not finished; run 'cleanup' if it was interrupted。
    Myeclipse小技巧
    好的开发网站
    BZOJ 1968
    BZOJ 1010
    BZOJ 1015
    BZOJ 3875
    BZOJ 2705
  • 原文地址:https://www.cnblogs.com/luoyong0201/p/Dynamics_365_Clone_View_SavedQuery_Tool.html
Copyright © 2011-2022 走看看