sensenet

Sensenet Content Picker Customization


I created two custom content types, ProjectContract and PaymentRequest. Under PaymentRequest, I have a reference field Contract which I would like to use to reference ProjectContract. When I am creating/changing PaymentRequest, I need the following:

  1. how can I initialize Content Picker to display ContractNumber field of available ProjectContracts?
  2. how can I display selected ProjectContract's ContractNumber under ReferenceField Grid control?

Solution

  • The SN js code and the mvc contains/returns fix field values. I did not find any setting where I can add custom fields to show. First of all, what is the version of that SN package, because the oData.svc request will not work on older versions. It is available from 6.2. About the oData, here is a link: http://wiki.sensenet.com/OData_REST_API

    There is another way to solve it, but with this, you need to modify the existion SN codes. You need to copy (" /Root/Global/scripts/sn/SN.Picker.js ") file into your skin folder with the same structure. (" /Root/Skins/[yourskinfolder]/scripts/sn/SN.ReferenceGrid.js ") You need to copy (" /Root/Global/scripts/sn/SN.ReferenceGrid.js ") file into your skin folder as well.

    Do not modify the original SN file, because it will be overwrite after an SN update.

    Next step: copy the following code to line 1068, before the ("$grid.jqGrid({") line, into the InitGrid function.

        ...
        var neededTypeName = "ProjectContract";
        var neededFieldName = "ContractNumber";
        var findField = false;
        o2 = (function () {
            var result = [];
            var itemArray = [];
            $.each(o2, function (index, el) {
                el.ContentField = "";
                result.push(el);
                if (el.ContentTypeName == neededTypeName) {
                    itemArray.push([index, el.Path]);
                    findField = true;
                }
            });
            if (findField) {
                $.each(itemArray, function (itemIndex, itemElArray) {
                    var itemId = itemElArray[0];
                    var itemEl = itemElArray[1];
                    var thisLength = itemEl.length;
                    var thislastSplash = itemEl.lastIndexOf("/");
                    var thisPath = itemEl.substring(0, thislastSplash) + "('" + itemEl.substring(thislastSplash + 1, thisLength) + "')";
                    $.ajax({
                        url: "/oData.svc" + thisPath + "?metadata=no$select=Path," + neededFieldName,
                        dataType: "json",
                        async: false,
                        success: function (d) {
                            result[itemId].ContentField = d.d[neededFieldName];
                        }
                    });
                });
                colNames.splice(6, 0, "ContentField");
                colModel.splice(6, 0, { index: "ContentField", name: "ContentField", width: 100 });
                return result;
            }
            return o2;
        })();
    
        ...
        $grid.jqGrid({
        ...
    

    The "neededTypeName" may contains your content type value, and the "neededFieldName" may contains the field name you want to render. The other will build up the grid. This will modify the Content picker table.

    You need to add this code into the GetResultDataFromRow function, at line 660 before the return of the function.

    ...
    if (rowdata.ContentField != undefined) {
        result.ContentField = rowdata.ContentField;
    }
    ...
    

    This will add the selected item properties from the Content picker to the reference field table.

    Then you need to open the SN.ReferenceGrid.js and add the following code into the init function before the "var $grid = $("#" + displayAreaId);"

     var neededTypeName = "CustomItem2";
        var neededFieldName = "Custom2Num";
        var findField = false;
        var alreadyAdded = false;
        var btnAttr = $("#"+addButtonId).attr("onClick");
        if (btnAttr.indexOf(neededTypeName) > -1) {
            alreadyAdded = true;
            colNames[4].width = 150;
            colModel[4].width = 150;
            colNames.splice(3, 0, "ContentField");
            colModel.splice(3, 0, { index: "ContentField", name: "ContentField", width: 60 });
        }
    
        initialSelection = (function () {
            var result = [];
            var itemArray = [];
            $.each(initialSelection, function (index, el) {
                el.ContentField = "";
                result.push(el);
                if (el.ContentTypeName == neededTypeName) {
                    itemArray.push([index, el.Path]);
                    findField = true;
                }
            });
            if (findField) {
                $.each(itemArray, function (itemIndex, itemElArray) {
                    var itemId = itemElArray[0];
                    var itemEl = itemElArray[1];
                    var thisLength = itemEl.length;
                    var thislastSplash = itemEl.lastIndexOf("/");
                    var thisPath = itemEl.substring(0, thislastSplash) + "('" + itemEl.substring(thislastSplash + 1, thisLength) + "')";
                    $.ajax({
                        url: "/oData.svc" + thisPath + "?metadata=no$select=Path," + neededFieldName,
                        dataType: "json",
                        async: false,
                        success: function (d) {
                            result[itemId].ContentField = d.d[neededFieldName];
                        }
                    });
                });
                if (!alreadyAdded) {
                    colNames.splice(3, 0, "ContentField");
                    colModel.splice(3, 0, { index: "ContentField", name: "ContentField", width: 100 });
                }
                return result;
            }
            return initialSelection;
        })();
    

    I hope this will help but the SN version should be helpful.