Set variable ReadOnly when Multi Row Variable Set not empty
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-30-2024 11:09 AM
Hi all,
I need some help or guidance on how to set a variable Read-Only when the Multi Row Variable Sets (MRVS) not empty i.e. once it populated at least one item.
Basically, once I added Report Name & Email the field outside of MRVS should be set to Read-Only
I've tried onLoad client script but it doesn't work quite right
function onLoad() {
var mrvs = JSON.parse(g_form.getValue('report_name_and_email'));
if(mrvs.length > 0) {
g_form.setReadOnly('add_or_remove', true);
}
}
Is there something else that I missed?
Thank you in advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-31-2024 08:11 AM
In the widget script, can you make sure your MRVS variable name is correct?
If my response helped you, please click on "Accept as solution" and mark it as helpful.
- Saloni
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-31-2024 08:24 AM
Here is my MRVS
And here is my widget script
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-01-2024 07:08 AM
I think pretty much everyone who ever worked with MRVS wished, that we had a way on the "parent" (the catalog item) to detect a change of a MRVS. All solutions posted (and some even got accepted as a "solution") have flaws:
They either don't work in the classic UI and/or they are built in a way that the does the change-detection every angular-cycle. So I did some tinkering and came up with a solution which works in the Classic UI as well as Service Portal.
Create a new variable of type custom, and make it Hidden=true.
In the 'Type Specification' Section of the new custom variable, use a new widget with the following Client Controller:
api.controller=function($scope, $rootScope, $timeout) {
var handlers = [];
var lastValues = {};
var g_form = $scope.page.g_form;
g_form.getFieldNames().forEach(function (fieldName) {
var field = g_form.getField(fieldName);
if (field.type != 'sc_multi_row') {
return;
}
var unregister = $rootScope.$on('field.change.' + fieldName, function ($event, data) {
// Note: data.oldValue is the *original* value (upon form load) ...
var operation = (function (oldData, newData) {
if (newData.length > oldData.length) {
return 'create';
} else if (newData.length < oldData.length) {
return 'delete';
} else {
return 'update';
}
})(JSON.parse(lastValues[fieldName] || '[]'), JSON.parse(data.newValue || '[]'));
// ... because of this, we simply preserve a copy of the previous value
lastValues[fieldName] = data.newValue;
CustomEvent.fire('scp_mrvs_changed', fieldName, operation);
});
handlers.push(unregister);
});
$scope.$on('$destroy', function () {
handlers.forEach(function (fn) { fn(); });
});
};
You also need to reference a UI Macro in the Custom Variable with the following code:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<script>
(function () {
if (window.TableVariable) {
window.TableVariable = scPlusTableVariable(window.TableVariable);
} else {
Object.defineProperty(window, 'TableVariable', {
configurable: true,
set: function (v) {
Object.defineProperty(window, 'TableVariable', {
configurable: true, enumerable: true, writable: true, value: scPlusTableVariable(v)
});
}
});
}
function scPlusTableVariable(ootbTableVariable) {
const SCPlusTableVariable = {
notifyOperation: function (operation) {
var res = ootbTableVariable.prototype.notifyOperation.apply(this, arguments);
CustomEvent.fire('scp_mrvs_changed', this.internal_name, operation);
return res;
},
type: 'SC+TableVariable'
};
return window.Class.create(ootbTableVariable, SCPlusTableVariable);
}
})();
</script>
</j:jelly>
Now you can use the following onLoad - Catalog Client Script on the Catalog Item itself:
UI Type: All
Script:
function onLoad() {
updateVariableState();
CustomEvent.on('scp_mrvs_changed', function (mrvsName, operation) {
if (mrvsName == 'report_name_and_email') {
updateVariableState();
}
});
function updateVariableState() {
var mrvs = JSON.parse(g_form.getValue('report_name_and_email') || '[]');
if (mrvs.length > 0) {
g_form.setReadOnly('add_or_remove', true);
} else {
g_form.setReadOnly('add_or_remove', false);
}
}
}