zoukankan      html  css  js  c++  java
  • Crm2011 用Htm Webresource添加另外一个实体的信息到当前实体

    之前接手这个项目的时候,看到的设计是这样的:

    实体A的页面上有一个Lookup,连到实体B;

    实体B的所有Fields都要展示到实体A;

    实体A不能改动这些Fields;

    实体B改动了这些Fields,也要体现到实体A;

    在实体A重复创建和实体B一模一样的Fields……

    这样的设计非常无聊,既然实体A要展示那些Fields,又不能改,其实只要直接拿实体B的信息即可,不需要重复创建Fields。

    但是他们这样做是有原因的,因为CRM的sub grid展示形式很单一,无法达到用户的需要。

    于是,现在,我改成了用Htm Web Resource来实现。

    如图:

    上图中的红框的信息全是来自“Property”这个Lookup的实体。

    实现方法如下:

    1. 创建一个Css,用来控制样式保持和CRM一致。我这里的名字是master.css,上传到CRM,(new_/Styles/master.css)

    body { font-family:Tahoma; font-size:11px; color:393839; margin:0px; background-color:F6F8FA; border:0px; }
    table
    {font-size:11px;}
    td
    {padding: 5px 10px 3px 0px;}
    h3
    {font-size:12px;}

    2. 上传sdk里的jquery到CRM(new_/Scripts/jquery1.4.1.min.js), jquery库可以在sdk找到:sdk\samplecode\js\restendpoint\jqueryrestdataoperations\jqueryrestdataoperations\scripts\jquery1.4.1.min.js

    3. 创建Htm页面,上传到CRM(new_/PropertyInfo.htm),这里我省略部分方法只是重复的代码,大家要根据需要修改:

    <HTML><HEAD><TITLE></TITLE> 
    <SCRIPT src="../ClientGlobalContext.js.aspx"></SCRIPT>
    <SCRIPT type=text/javascript src="Scripts/jquery1.4.1.min.js"></SCRIPT>
    <SCRIPT type=text/javascript src="Scripts/sdk.metadata.js"></SCRIPT>
    <LINK rel=stylesheet type=text/css href="Styles/master.css"></LINK>
    <SCRIPT language=javascript>

    var _serverUrl;
    function retrievePropertyInfo() {

    var customerAttribute = parent.Xrm.Page.data.entity.attributes.get("new_property");


    if (customerAttribute != null) {


    customerValue
    = customerAttribute.getValue();


    if (customerValue != null && customerValue[0] != null) {
    var customerType = customerValue[0].typename;
    var customerId = customerValue[0].id;
    return retrieveRecord(customerId, "new_propertySet", retrieveCompleted, null);


    }
    }
    }


    function retrieveRecord(id, odataSetName, successCallback, errorCallback) {
    var context = GetGlobalContext();
    var serverUrl = context.getServerUrl();
    _serverUrl
    = serverUrl;

    var odataEndPoint = "/XRMServices/2011/OrganizationData.svc";


    if (!id) {
    alert(
    "record id is required.");
    return;
    }


    if (!odataSetName) {
    alert(
    "odataSetName is required.");
    return;
    }


    $.ajax({
    type:
    "GET",
    contentType:
    "application/json; charset=utf-8",
    datatype:
    "json",

    url: serverUrl
    + odataEndPoint + "/" + odataSetName + "(guid'" + id + "')",
    beforeSend:
    function (XMLHttpRequest) {

    XMLHttpRequest.setRequestHeader(
    "Accept", "application/json");
    },
    success:
    function (data, textStatus, XmlHttpRequest) {
    if (successCallback) {
    successCallback(data.d, textStatus, XmlHttpRequest);
    }
    },
    error:
    function (XmlHttpRequest, textStatus, errorThrown) {
    if (errorCallback)
    errorCallback(XmlHttpRequest, textStatus, errorThrown);
    else
    errorHandler(XmlHttpRequest, textStatus, errorThrown);
    }
    });
    }


    function retrieveCompleted(data, textStatus, XmlHttpRequest) {
    /*Display the required fields and hide if the fields are null */
    var entity = data;
        
    //Picklist
    var Type = (entity.new_Type.Value == null) ? "" : RetrieveOptionsetLabel("new_property", "new_type", entity.new_Type.Value, "type");
    //Text
    var AddressLine1 = (entity.new_AddressLine1 == null) ? "" : entity.new_AddressLine1;

    if (addressline1 != "") {
    document.getElementById(
    "addressline1").innerHTML = AddressLine1;

    }
    //Hyperlink
    var PortfolioName = (entity.new_Portfolio.Name == null) ? "" : entity.new_Portfolio.Name;
    var PortfolioId = (entity.new_Portfolio.Id == null) ? "" : entity.new_Portfolio.Id;
    if (portfolio != "") {
    document.getElementById(
    "portfolio").innerHTML =
    "<a href='" + _serverUrl + "/main.aspx?etc=10014&id=%7b" + PortfolioId + "%7d&pagetype=entityrecord' target=_blank>" + PortfolioName + "</a>";


    }




    }


    function RetrieveOptionsetLabel(entityName, optionSetName, optionSetValue, attributeId) {
    // Entity schema name
    var entityLogicalName = entityName;
    // option set schema name
    var RetrieveAttributeName = optionSetName;
    // Target Field schema name to which optionset text needs to be assigned
    var AssignAttributeName = attributeId;

    // Option set value for which label needs to be retrieved
    var stateValue = optionSetValue;

    // Calling Metadata service to get Optionset Label
    SDK.MetaData.RetrieveEntityAsync(SDK.MetaData.EntityFilters.Attributes,
    entityLogicalName,
    null,
    false,
    function (entityMetadata) {
    successRetrieveEntity(entityLogicalName, entityMetadata, RetrieveAttributeName, stateValue, AssignAttributeName);
    },
    errorDisplay);


    }

    // Called upon successful metadata retrieval of the entity
    function successRetrieveEntity(logicalName, entityMetadata, RetrieveAttributeName, OptionValue, AssignAttributeName) {
    ///<summary>
    /// Retrieves attributes for the entity
    ///</summary>

    var success = false;
    for (var i = 0; i < entityMetadata.Attributes.length; i++) {
    var AttributeMetadata = entityMetadata.Attributes[i];
    if (success) break;
    if (AttributeMetadata.SchemaName.toLowerCase() == RetrieveAttributeName.toLowerCase()) {
    for (var o = 0; o < AttributeMetadata.OptionSet.Options.length; o++) {
    var option = AttributeMetadata.OptionSet.Options[o];
    if (option.OptionMetadata.Value == OptionValue) {
    document.getElementById(AssignAttributeName).innerHTML
    = option.OptionMetadata.Label.UserLocalizedLabel.Label;
    success
    = true;

    break;
    }
    }
    }

    }


    }

    function errorDisplay(XmlHttpRequest, textStatus, errorThrown) {

    alert(errorThrown);
    }

    </SCRIPT>


    <META charset=utf-8></HEAD>
    <BODY onload=retrievePropertyInfo() contentEditable=false>
    <div id=propertyinfo>
    <table style="100%">

    <tbody>

    <tr>
    <td style="8%">Address Line 1</td>
    <td id="addressline1" style="18%"></td>
    <td style="8%">Type</td>
    <td id="type" style="18%"></td>

    <td style="8%">Asset ID</td>
    <td id="assetid" style="18%"></td>
    <td style="8%">Country</td>
    <td id="country" style="auto"></td>

    </tr>
    <tr>
    <td>Address Line 2</td>
    <td id="addressline2"></td>


    <td>Property Type</td>
    <td id="propertytype"></td>

    <td>Portfolio</td>
    <td id="portfolio"></td>
    <td>State/Province</td>
    <td id="state"></td>
    </tr>

    <tr>

    <td>Address Line 3</td>
    <td id="addressline3"></td>
    <td>Property SubType</td>
    <td id="propertysubtype"></td>



    <td>County</td>
    <td id="county"></td>
    <td>City</td>
    <td id="city"></td>
    </tr>

    </tbody>
    </table>
    </div>

    </BODY></HTML>


    4. 将这个Htm Webresource插入我们需要它的地方,这样就可以了。

    注意,我们的property lookup必须要在页面上才可以,设为不可见也行,因为如果它不在页面上,我们就拿不到它的id了,当然,通过别的方法拿到也是可以,但是就增加了不必要的麻烦。

    补充,我们这里是用odata来取得数据的,写odata query的时候要注意。我是觉得很讨厌写这个query,所以我是用这个工具的:CRM 2011 OData Query Designer

    如果我们是取一个实体的数据(
    http://XXXX:8080/OOOOO/xrmservices/2011/OrganizationData.svc/odataSetName (guid'3653C6D5-2077-E111-920A-000C29139AA1')),那么返回的肯定是一个实体,则我们分析数据的时候只要用类似entity.fieldname 就可以拿到相应的值。

    如果我们取得是多个实体的数据(http://XXXX:8080/OOOOO/xrmservices/2011/OrganizationData.svc/odataSetName?$select=new_Field1Name,new_new_entityB_new_entityA_entityBName/new_Field2Name$expand=new_new_entityB_new_entityA_entityBName&$filter=new_entityAId eq guid'3653C6D5-2077-E111-920A-000C29139AA1'),那么返回的是一个数组,我们分析数据的时候,对于a的数据要这样entity.results[0].field1name;对于b的数据则是:entity.results[0].new_new_entityB_new_entityA_entityBName.field2name

    再补充:

    如果取得是数据是Date,需要进行一下转换,odata返回的Date是这样的Date(1235764800000)

    这样转换:

    function ConvertTime(date) {
    //This function use for convert the Date value get from odata, convert to javascript readable value
    if (date == "") {
    return "";
    }
    else {
    var utcTime = parseInt(date.substr(6)); //date is like Date(1235764800000)
    var result = new Date(utcTime);
    result.setHours(result.getHours() + 8); //Database time is 8 hours late before local time
    return result.format("M/dd/yyyy");
    }
    }


    好的,基本上就是这样。

    
    
  • 相关阅读:
    lr参数化取值规则总结
    LoadRunner中InvokeMethod failure: 外部组件发生异常解决办法
    Error: Exception was raised when calling event-notify Vuser function in extension parameng.dll: System Exceptions: EXCEPTION_ACCESS_VIOLATION
    loadrunner场景执行出现:Failed to Initialize. Reason: TimeOut
    loadrunner场景中按scenario和group执行的区别
    lr关联抓有相同左右边界的动态值
    lr中用strtok函数分割字符串
    LoadRunner11设置场景百分比模式完成多台客户端压力测试
    lr如何屏蔽全局变量的影响
    Oracle in与exist条件分析
  • 原文地址:https://www.cnblogs.com/nixjojo/p/2421386.html
Copyright © 2011-2022 走看看