zoukankan      html  css  js  c++  java
  • MSCRM4 在过滤后的LOOKUP框中实现查找

    在MSCRM中让Lookup根据一定的条件实现过滤功能, 这个需求很常见, 在我接触的诸多项目中似乎都需要有这个功能. 但非常遗憾是, MSCRM 的SDK并没有提供实现这个功能的方法. 不过我们应该还是感到庆幸, 据说, 微软CRM产品组有透露下面这样的方法:

    场景:

    实体:

    实体名 架构名
    客户 account
    联系人 contact

    客户:

    字段名 架构名 类型 关联实体
    上级单位 parentaccountid lookup 客户
    主要联系人 primarycontactid lookup 联系人

    联系人:

    字段名 架构名 类型 关联实体
    上司 parentcustomerid lookup 客户

    需求:

    在客户实体中, 当选择上级单位后, 点击主要联系人Lookup按钮, 在弹出的lookup选择对话框中必须过滤出上司等于上级单位的所有联系人.

    实现方法:

    第一步:

    进入高级查找, 根据需求设置查找条件。

    点击查找,然后在地址栏中输入javascript:alert(resultRender.FetchXml.value);后回车, 获取fetchxml

    第二步:

    将第一步获取的Fetchxml做适当的修改,并将其在客户实体的OnLoad事件 和 上级单位的OnChange事件 中 对上级单位字段设置参数如下:

    if(crmForm.all.primarycontactid.DataValue != null){
    crmForm.all.primarycontactid.lookupbrowse = 1;
    crmForm.all.primarycontactid.additionalparams = "search=<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"><entity name="contact"><order attribute="fullname" descending="false"/><filter type="and"><condition attribute="parentcustomerid" operator="eq" uiname=""+crmForm.all.parentaccountid.DataValue[ 0 ].name+"" uitype="account" value=""+crmForm.all.parentaccountid.DataValue[ 0 ].id+""/></filter></entity></fetch>";
    }

    第三步:

    修改CRMWeb\_controlslookuplookupsingle.aspx文件,在该文件头部加入如下代码:
    <script runat="server">
    protected override void OnLoad( EventArgs e )
    {
          base.OnLoad(e);
          crmGrid.PreRender += new EventHandler( crmgrid_PreRender );
    }

    void crmgrid_PreRender( object sender , EventArgs e )
    {
          crmGrid.AddParameter( "fetchxml" , Request["search"] );
          crmGrid.Parameters.Remove( "searchvalue" );
    }
    </script>

     OK, 以上就是传说中产品组透露的方法.实现的效果过下图:

    从上图可以看到, 经过过滤后的lookup没有了查找框. 当然, 如果过滤后的出来的结果数据量并不是很大的话, 那么我个人认为已经满足需求, 但关键是, 如果过滤后的结果有几百条之多. 那么用户体验就差了. 也就在这个时候我们往往会想方设法去改善他.

    接下来是我要谈到的重点, 如何在过滤后的lookup中实现查找

    其实, 之前的方法之所以没有了查找框, 是在脚本中加了这么条语句:

    crmForm.all.primarycontactid.lookupbrowse = 1; 但当这个值改为0时, 会出现下面的效果:

    显然这并不是我们想要的结果

    但这个结果也并不是最糟糕的, 至少它给了一个提示, 告诉我们可以在fetchxml上做文章.

    没错, 还是偷梁换柱的方法, 但这里需要注意一点, 直接将fetchxml作为查找条件是得不出任何结果的. 在这里我们需要通过另外一种方式来实现.

    其实, 经过分析lookup页面会发现, fetchxml 被存储在lookup页面的的一个隐藏div中, 如下图:

    当点击视图的刷新按钮时, MSCRM自动的会根据fetchxml的条件重新加载数据.

    通过以上信息, 便可很轻松的实现这个功能.

    实现方法:

    之前的三个步骤不变, 更改步骤二的代码如下:

    if(crmForm.all.primarycontactid.DataValue != null){

    crmForm.all.primarycontactid.lookupbrowse = 0;
    crmForm.all.primarycontactid.additionalparams = "search=<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"><entity name="contact"><order attribute="fullname" descending="false"/><filter type="and"><condition attribute="fullname" operator="like" value="%%"/><condition attribute="parentcustomerid" operator="eq" uiname=""+crmForm.all.parentaccountid.DataValue[ 0 ].name+"" uitype="account" value=""+crmForm.all.parentaccountid.DataValue[ 0 ].id+""/></filter></entity></fetch>";
    }

    在CRMWeb\_controlslookuplookupsingle.aspx页面中添加如下代码, 并在onload中调用FindCriteria方法

    function FindCriteria(){
        try{
            var criteriaObj = document.getElementById("findValue");
            var fetchObj = document.getElementById("fetchxml");
            var searchObj = document.getElementById("search");
            var criteriaObj2 = criteriaObj.cloneNode(true);

            criteriaObj2.value = "";
            if(fetchObj.value == ""){
                criteriaObj.value = "*"+criteriaObj2.value;
                if(criteriaObj.value == "*"){criteriaObj.value = "";}
            }
            else{
                document.getElementById("btnGo").onclick = function(){
                    document.getElementById("grid_refresh").click();
                }
            }
            criteriaObj2.onchange = function(){
                if(fetchObj.value == ""){
                    criteriaObj.value = "*"+criteriaObj2.value;
                    if(criteriaObj.value == "*"){criteriaObj.value = "";}
                }
                else{
                    fetchObj.value = searchObj.value.replace("value="%%"","value="%"+criteriaObj2.value.replace(/*/g,"%") +"%"");
                    document.getElementById("btnGo").onclick = function(){
                        document.getElementById("grid_refresh").click();
                    }
                }
            }
            criteriaObj2.id = "findCriteria2";
            criteriaObj.parentElement.appendChild(criteriaObj2);
            criteriaObj.style.position = "absolute";
            criteriaObj.style.zIndex = "1000";
            criteriaObj.style.left = "-1000px";
            criteriaObj.style.top = "-1000px";
            criteriaObj2.onkeydown = function(){
                if(event.keyCode==13){
                    if(fetchObj.value == ""){
                        criteriaObj.value = "*"+criteriaObj2.value;
                        if(criteriaObj.value == "*"){criteriaObj.value = criteriaObj.value = "";}
                        document.getElementById("btnGo").click();
                    }
                    else{
                        fetchObj.value = searchObj.value.replace("value="%%"","value="%"+criteriaObj2.value.replace(/*/g,"%")+"%"");
                        document.getElementById("btnGo").onclick = function(){
                            document.getElementById("grid_refresh").click();
                        }
                    }
                }
            }
        }catch(e){alert(e.message)}
    }

    最终效果:

    转载自http://www.cnblogs.com/xingbake/archive/2009/04/03/1428608.html

  • 相关阅读:
    map用法详解
    求用1,2,5这三个数不同个数组合的和为100的组合个数
    【雅虎笔试题】两个已经排好序的数组,找中位数
    C++ STL算法系列4---unique , unique_copy函数
    C++ STL算法系列3---求和:accumulate
    C++ STL算法系列2---find ,find_first_of , find_if , adjacent_find的使用
    C/C++面试小知识点
    C语言内存地址基础
    C语言函数指针基础
    C++ STL算法系列1---count函数
  • 原文地址:https://www.cnblogs.com/hanc/p/3752605.html
Copyright © 2011-2022 走看看