mrvs

HARSHA GOWDA R
Tera Contributor

I added the following script in the client controller to capture MRVS values in the custom widget; however, the values entered by the user are not being captured upon submission of the catalog item.

function ($scope, $http, spUtil, nowAttachmentHandler, $rootScope, $sanitize, $window, $sce, i18n, $timeout, $log, spAriaUtil, $location, spModal) {
    var c = this;
    c.quantity = 1;
    if ($scope.data.sc_cat_item)
        $scope.data.sc_cat_item.description = $sce.trustAsHtml($scope.data.sc_cat_item.description);
    c.widget._debugContextMenu = [
        [ i18n.getMessage("Open") + " sc_cat_item", function(){
            var item = c.data.sc_cat_item;
            $window.open("/sp_config?id=form&table=" + item.table + "&sys_id=" + item.sys_id); }]
    ];
    c.showAddCartBtn = function() {
        return c.options.show_add_cart_button &&
            c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
            !c.data.sc_cat_item.no_cart;
    }

    c.showQuantitySelector = function() {
        return c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
            !c.data.sc_cat_item.no_quantity &&
            (!c.data.sc_cat_item.no_order_now || !c.data.sc_cat_item.no_cart);
    }

    c.showOrderNowButton = function() {
        return c.data.sc_cat_item.use_sc_layout || !c.data.sc_cat_item.no_order_now;
    }

    c.allowOrder = function() {
        if (c.data.sc_cat_item.use_sc_layout)
            return true;

        if (c.data.sc_cat_item.no_order)
            return false;

        if (c.data.sc_cat_item.no_order_now && c.data.sc_cat_item.no_cart)
            return false;

        return true;
    }

    $scope.$on('dialog.upload_too_large.show', function(e){
        $log.error($scope.m.largeAttachmentMsg);
        spUtil.addErrorMessage($scope.m.largeAttachmentMsg);
    });

    $scope.m = $scope.data.msgs;
    $scope.submitButtonMsg = $scope.m.submitMsg;
    var ah = $scope.attachmentHandler = new nowAttachmentHandler(setAttachments, appendError);
    function appendError(error) {
        spUtil.addErrorMessage(error.msg + error.fileName);
    }
    ah.setParams('sp_portal', $scope.data._attachmentGUID, 1024 * 1024 * $scope.data.maxAttachmentSize);
    function setAttachments(attachments, action) {
        $scope.attachments = attachments;
        if (action === "added")
            $scope.setFocusToAttachment();
        if (action === "renamed")
            spAriaUtil.sendLiveMessage($scope.m.renameSuccessMsg);
        if (action === "deleted")
            spAriaUtil.sendLiveMessage($scope.m.deleteSuccessMsg);
    }
    $scope.attachmentHandler.getAttachmentList();

    $scope.confirmDeleteAttachment = function(attachment) {
        spModal.confirm($scope.data.msgs.delete_attachment).then(function() {
          $scope.attachmentHandler.deleteAttachment(attachment);
          $scope.setFocusToAttachmentButton();
        });
  }

    // Breadcrumbs
    if ($scope.data.sc_cat_item) {
        if (!$scope.data.categories)
            $scope.data.categories = [];
//      $scope.data.categories.unshift({label: $scope.data.msgs.serviceCatalogMsg, url: '?id=' + $scope.data.sc_catalog_page});
        $scope.data.categories.push({label: $scope.data.sc_cat_item.name, url: '#'});
        $timeout(function() {
            $scope.$emit('sp.update.breadcrumbs', $scope.data.categories);
        });
        spUtil.setSearchPage('sc');
    }
    else {
        var notFoundBC = [{label: $scope.data.msgs.serviceCatalogMsg, url: '?id=' + $scope.data.sc_catalog_page}];
        $timeout(function() {
            $scope.$emit('sp.update.breadcrumbs', notFoundBC);
        });
        spUtil.setSearchPage('sc');
    }

    c.getItemId = function () {
        return $scope.data.sc_cat_item ? $scope.data.sc_cat_item.sys_id : -1;
    };

    var g_form;
    $scope.$on('spModel.gForm.initialized', function(e, gFormInstance){
        if (gFormInstance.getSysId() != -1 && gFormInstance.getSysId() != c.getItemId())
            return;
        g_form = gFormInstance;

        // This runs after all onSubmit scripts have executed
        g_form.$private.events.on('submitted', function(){
            if ($scope.data.sc_cat_item.item_action === "order")
                getOne();
            else if ($scope.data.sc_cat_item.item_action === "add_to_cart")
                addToCart();
        });
    });

    $scope.triggerAddToCart = function() {
        $scope.data.sc_cat_item.item_action = "add_to_cart";
        $scope.data.sc_cat_item.quantity = c.quantity;
        if (g_form)
            g_form.submit();
    }

    $scope.triggerOnSubmit = function(){
        $scope.data.sc_cat_item.item_action = "order";
        $scope.data.sc_cat_item.quantity = c.quantity;
        if (g_form){
            g_form.submit();
           
        }

    //  $window.location.reload();
       
    }

    // order / create request
    function getOne() {
        postCatalogFormRequest().success(function(response) {
            var a = response.result ? response.result : response.answer;
            var n = a.number;
            $scope.$emit("$$uiNotification", response.$$uiNotification ? response.$$uiNotification : a.$$uiNotification);
            $scope.$emit("$sp.sc_cat_item.submitted", a);
            if (n)
                issueMessage(n, a.table, a.sys_id, a.redirect_to, a.redirect_portal_url);
            $scope.submitting = false;
            $scope.submitButtonMsg = $scope.m.submittedMsg;
                //if($scope.m.submittedMsg){
               // alert('Password reset successfully completed');
                    //$window.location.reload();
               
        //Commented the below code, so that the request can follow the submit process as other catalog items
//                  if( $scope.submitButtonMsg=="Submitted" ){
//                      if(c.data.sc_cat_item.sys_id=='fd2bf35c1bffd410bab14005bd4bcb69'){
//                           myVar = setTimeout(function(){
//                               var alertmsg=c.data.sc_cat_item.name+' successfully completed';
//                        // alert("Password Reset successfully submitted");
//                      //  alert(alertmsg);
//                               $window.location.reload();
//                           }, 1000);
//                      }
//              //alert('Password reset successfully completed');
//                  //$window.location.reload();
//                  
                   
//      }
        }).error(function(response) {
            jslog(response);
        });
   
    }

    function addToCart() {
        postCatalogFormRequest().success(function(response) {
            $rootScope.$broadcast("$sp.service_catalog.cart.add_item");
            $rootScope.$broadcast("$sp.service_catalog.cart.update");
            //spUtil.addInfoMessage("Added item to shopping cart");
            $scope.submitting = false;
            c.status = "Added item to shopping cart";
        });
    }

    function postCatalogFormRequest() {
        setFieldsReadonly();
        $scope.submitted = true;
        $scope.submitting = true;
        var requestUrl;
        var reqData = {};
        if ($scope.data.sc_cat_item.sys_class_name === "sc_cat_item_producer") {
            requestUrl = '/api/sn_sc/v1/servicecatalog/items/' + $scope.data.sc_cat_item.sys_id + '/submit_producer';
            for(var obj in $scope.data.sc_cat_item._fields)
                reqData[$scope.data.sc_cat_item._fields[obj].name] = $scope.data.sc_cat_item._fields[obj].value;
            reqData = {'variables' : reqData, 'attachment_id' : $scope.data._attachmentGUID, 'attachment_table': 'sp_portal', 'get_portal_messages': 'true'};
        }
        else {
            requestUrl = spUtil.getURL('sc_cat_item');
            reqData = $scope.data.sc_cat_item;
            reqData._attachmentGUID = $scope.data._attachmentGUID;
        }
        return $http.post(requestUrl, reqData);
    }

    // spModel populates mandatory - hasMandatory is called by the submit button
    $scope.hasMandatory = function(mandatory) {
        return mandatory && mandatory.length > 0;
    };

    // switch catalog items
    var unregister = $scope.$on('$sp.list.click', onListClick);
    $scope.$on("$destroy", function() {
        unregister();
    });

    function onListClick(evt, arg) {
        $scope.data.sys_id = arg.sys_id;
        spUtil.update($scope);
    }

    function setFieldsReadonly(){
        var allFields = g_form.getFieldNames();
        for(var fieldName in allFields){
            g_form.setReadOnly(allFields[fieldName], true);
        }
    }

    function issueMessage(n, table, sys_id, redirectTo, redirectUrl) {
        var page = table == 'sc_request' ? 'sc_request' : 'ticket';
        if (c.options.page) {page = c.options.page;}
        if (c.options.table) {table = c.options.table;}
        if (redirectTo == 'catalog_home') page = 'sc_home';
        var url = spUtil.format(c.options.url, {page: page, table: table, sys_id: sys_id});
        if (c.options.auto_redirect == "true") {
            $timeout(function() {
                if (redirectUrl)
                    $location.url(redirectUrl);
                else
                    $location.url(url);
            }, 1000);
            return;
        }

        var t = $scope.m.createdMsg + " " + n + " - ";
        t += $scope.m.trackMsg;
        t += ' <a href="' + url + '">' + $scope.m.clickMsg + '</a>';
        spUtil.addInfoMessage(t);
    }
}
1 REPLY 1

Itallo Brandão
Tera Guru

Hi @HARSHA GOWDA R ,

The issue is likely in your postCatalogFormRequest function.

Multi-Row Variable Sets (MRVS) are tricky because the backend expects them to be passed as a serialized JSON string, not just the raw object value. When you iterate through $scope.data...value, you often miss that serialization step.

The safest way to handle this in Service Portal is to rely on g_form.getValue(), which automatically formats the MRVS correctly for the API.

Try replacing your postCatalogFormRequest function with this updated version:

 
    function postCatalogFormRequest() {
        setFieldsReadonly();
        $scope.submitted = true;
        $scope.submitting = true;
        var requestUrl;
        var reqData = {};

        if ($scope.data.sc_cat_item.sys_class_name === "sc_cat_item_producer") {
            requestUrl = '/api/sn_sc/v1/servicecatalog/items/' + $scope.data.sc_cat_item.sys_id + '/submit_producer';
            
            // --- UPDATED LOOP ---
            for (var obj in $scope.data.sc_cat_item._fields) {
                var field = $scope.data.sc_cat_item._fields[obj];
                
                // We use g_form.getValue() because it returns the JSON string required for MRVS
                if (typeof g_form !== 'undefined') {
                    reqData[field.name] = g_form.getValue(field.name);
                } else {
                    reqData[field.name] = field.value;
                }
            }
            // --------------------

            reqData = {
                'variables': reqData,
                'attachment_id': $scope.data._attachmentGUID,
                'attachment_table': 'sp_portal',
                'get_portal_messages': 'true'
            };
        } else {
            requestUrl = spUtil.getURL('sc_cat_item');
            reqData = $scope.data.sc_cat_item;
            reqData._attachmentGUID = $scope.data._attachmentGUID;
        }
        return $http.post(requestUrl, reqData);
    }

This ensures that whatever data is in your MRVS gets converted to the string format the server needs.

If this fixes the missing data, please mark it as Accepted Solution.

Best regards,
Brandão.