- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 11:47 AM
Below is a MRVS in SP Variable Editor Widget in Service Portal.
But document.getElementsByTagName, ByID,... all returning null when accessing it via client.
I need to access the innerHTML of cells and do styling based on match.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 04:59 PM
Can you share how you're trying to select the elements and also share what the HTML structure is of the MRVS in the variable editor is. Also, perhaps you're running your code that tries to select the HTML td elements before it's been loaded into the DOM. Perhaps you need to add a delay before you try and read the elements (using a MutationObserver can be used to determine when the content has loaded, or setTimeout for an arbitrary delay).
Do be aware that trying to change elements and styles via DOM manipulation is not recommended, as ServiceNow could change how things are structured in a future upgrade.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 04:59 PM
Can you share how you're trying to select the elements and also share what the HTML structure is of the MRVS in the variable editor is. Also, perhaps you're running your code that tries to select the HTML td elements before it's been loaded into the DOM. Perhaps you need to add a delay before you try and read the elements (using a MutationObserver can be used to determine when the content has loaded, or setTimeout for an arbitrary delay).
Do be aware that trying to change elements and styles via DOM manipulation is not recommended, as ServiceNow could change how things are structured in a future upgrade.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 08:52 PM
HTML
<div ng-class="{'panel panel-default': !data.hide_container}" ng-if="data.category == 'Oracle Fusion ASaaS ERP Access'" >
<div class="panel-heading" ng-if="!data.hide_container">
<h3 ng-if="data.itemTitle" class="panel-title">{{data.itemTitle}}</h3>
<h3 ng-if="!data.itemTitle" class="panel-title">${Variables}</h3>
</div>
<div ng-class="{'panel-body': !data.hide_container, 'variable-editor': data.hide_container}">
<sp-model form-model="::data.sc_cat_item" mandatory="[]"></sp-model>
</div>
<!-- <div ng-if="c.showSave && c.options.readonly_variable_editor != 'true'" class="panel-footer">
<button class="btn btn-primary pull-right" name="save" ng-click="c.save()">${Save}</button>
<span ng-if="validating" style="padding-left:4px">${Validating...}</span>
<div style="clear: both;"></div>
</div>-->
</div>
<div class="workspace-variables" ng-if="::c.hasVariables(data.sc_cat_item._fields) && c.options.isServiceWorkspace">
<div class="variables">
<sp-model form-model="::data.sc_cat_item" mandatory="[]"></sp-model>
</div>
<div ng-if="c.showSave && c.options.readonly_variable_editor != 'true'">
<button class="btn btn-primary pull-right" name="save" ng-click="c.save()">${Save}</button>
<span ng-if="validating" style="padding-left:4px">${Validating...}</span>
<div style="clear: both;"></div>
</div>
</div>
<div ng-if="::!c.hasVariables(data.sc_cat_item._fields)">
<h4 class="text-a-c">
{{::c.data.msg}}
</h4>
</div>
<now-message key="Variable saved" value="${Variable saved}"></now-message>
Client
function($scope, $document, $rootScope, i18n, spScUtil) {
/* widget controller */
var c = this;
c.isSaved = false;
var parent_g_form = $scope.page.g_form;
var origActionName;
//alert(s.length);
if (!parent_g_form)
c.showSave = true;
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;
if (parent_g_form)
addSaveHandler();
g_form = gFormInstance;
g_form.$private.events.on('submitted', function() {
if (!c.showSave) {
c.server.update().then(function() {
parent_g_form.submit(origActionName);
c.isSaved = true;
});
}
else {
c.server.update().then(function() {
g_form.addInfoMessage(i18n.getMessage('Variable saved'));
if (c.options.isServiceWorkspace == true) { //Workspace handler
if (window.parent === window) {
console.warn("Parent is missing. Is this called inside an iFrame?");
return;
}
window.parent.postMessage({
messageType: 'IFRAME_MODAL_MESSAGE_TYPE',
modalAction: 'IFRAME_MODAL_ACTION_CONFIRMED',
modalId: 'sn-modal-iframe-singleton'
}, location.origin)
}
if (c.data.table == "sc_cart_item")
$rootScope.$broadcast("$sp.service_catalog.cart.update");
});
}
})
});
// Used when embedded as a formatter
function addSaveHandler() {
parent_g_form.$private.events.on("submit", function() {
var actionName = parent_g_form.getActionName();
// If actionName is none, form has already been re-submitted.
// No need to submit it the third time.
if (actionName === 'none') { return false; }
origActionName = actionName;
if (c.isSaved) return true;
if (!spScUtil.isServerValidationDone($scope.data.sc_cat_item._fields)) {
$scope.validating = true;
return false;
}
if (g_form)
return g_form.submit();
return true;
});
parent_g_form.$private.events.on("submitted", function() {
c.isSaved = false;
});
//var s = $document[0].getElementsByTagName('td');
// alert(s.length);
}
c.save = function() {
var activeElement = $document.activeElement;
if (activeElement)
activeElement.blur();
if (!spScUtil.isServerValidationDone($scope.data.sc_cat_item._fields))
$scope.validating = true;
else if (g_form)
g_form.submit();
};
c.hasVariables = function(fields) {
if (!fields)
return false;
return Object.keys(fields).length > 0;
}
//$('h3').hide();
// var s = $document[0].getElementById('');
//alert(JSON.stringify(s))
var validationComplete = $rootScope.$on('$sp.service_catalog.form_validation_complete', function() { $scope.validating = false; });
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 09:08 PM - edited 02-01-2024 09:13 PM
I can't see where the problematic document.getElementsByTagName/byId is being used in your client script.
Also that appears to be the widget HTML template. I guess once it renders it produces the MRVS using a table? What does that generated HTML look like (as I assume that is what you're trying to access)?
Did you give the setTimeout option a go? Any luck with that?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-01-2024 09:30 PM
yes, after giving setTimeout it is capturing td elements and able to get Collection length.
Thanks a lot.