- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-14-2023 07:03 AM
created a service portal widget but after entering the serial number nothing happens.
Client :
// Widget Script
function handleCheckIn() {
// Get the scanned barcode from the input field
var scannedBarcode = document.getElementById('barcodeInput').value;
// Call a function to process the scanned barcode (e.g., initiateCheckInProcess)
initiateCheckInProcess(scannedBarcode);
// Clear the input field for the next scan
document.getElementById('barcodeInput').value = '';
}
function initiateCheckInProcess(scannedBarcode) {
// Example: Query the alm_hardware table to find the hardware record based on the scanned barcode
var hardwareRecord = new GlideRecord('alm_hardware');
hardwareRecord.addQuery('serial_number', scannedBarcode);
hardwareRecord.query();
if (hardwareRecord.next()) {
// Hardware record found, get the assigned user
var assignedUser = hardwareRecord.assigned_to;
// Check if the assigned user is valid
if (assignedUser) {
// Create an interaction ticket
var interaction = new GlideRecord('interaction');
interaction.initialize();
interaction.caller_id = assignedUser;
interaction.location = hardwareRecord.location; // Assuming 'location' is a field on the hardware table
interaction.reason = "Laptop refresh";
interaction.insert();
// Log success or perform additional actions
gs.info('Check-in process initiated for user: ' + assignedUser.getDisplayValue());
} else {
// Assigned user not found, log an error or handle as needed
gs.error('Assigned user not found for hardware with serial number: ' + scannedBarcode);
}
} else {
// Hardware record not found, log an error or handle as needed
gs.error('Hardware record not found for serial number: ' + scannedBarcode);
}
}
html template. :
<!-- Barcode Check-In Widget Template -->
<div class="barcode-checkin-widget">
<label for="barcodeInput">Scan Barcode:</label>
<input type="text" id="barcodeInput" placeholder="Scan barcode..." autofocus>
<button onclick="handleCheckIn()">Check-In</button>
</div>
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-18-2023 02:39 AM
Well, your code is faulty: 1st you load the asset's user (assigned to) only after that you check whether the asset's user (assigned to) is actually filled in or not.
And that assuming that you have an actual user id in the actual code in line:
alm_hardware.addQuery('serial_number', 'your_serial_number');
Otherwise the Opened for always ends up empty.
Also why would you look up and load the same thing twice?
I mean you 1st load the asset to get the assigned to user than you load the asset once more to check whether the assigned to user is filled in or not and do the rest of the stuff.
Try formatting your code, maybe it will make such things more obvious.
Also you are not calling createInteraction function with the expected data type: parameter userId - it seems - must be a string.
A functioning code should at minimum look something like:
function lookUpAssetAndCreateInteraction (barCode) {
var alm_hardware = new GlideRecord('alm_hardware');
alm_hardware.setLimit(1);
if (alm_hardware.get('serial_number', barCode)) {
if (!alm_hardware.assigned_to.nil()) {
var facade = new sn_walkup.ExtPointUtil().loadExtension('InteractionFacade');
var queueId = '775bd4f62fd5b110207170682799b6c6';
var reasonId = '837468135b8b3300f6bc098b41f91ab8';
var reasonDescription = 'Something not working';
var badgeId = true;
return facade.createInteraction(
// Here a string is needed, not an object -
// alm_hardware.assigned_to is an object, a GlideRecord,
// '' + alm_hardware.assigned_to on the other hand is a string
'' + alm_hardware.assigned_to,
queueId,
reasonId, // reasonID
reasonDescription, // reason description
false, // is_guest
'', // guest_name
'', // guest_email
false, // is_online_checkin
false, // is_appointment
badgeId ? true : false // is_badge_checkin
);
}
else {
data.error = gs.getMessage('Assigned user not found for hardware with serial number: {0}', barCode);
}
}
else {
data.error = gs.getMessage('Hardware record not found for serial number: {0}', barCode);
}
}
Pasting only function lookUpAssetAndCreateInteraction here.
I am assuming that the rest is correct, like the queue id and that if there is an extension point defined, it is working - I have tested with OOB.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-19-2023 04:29 AM
That means you have not updated your Script Include code as suggested previously.
You should have in it
MyScriptInclude.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
not
MyScriptInclude.prototype = Object.extendsObject(AbstractAjaxProcessor, {
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-19-2023 04:50 AM - edited 12-19-2023 04:51 AM
I assume that is because the user has stuff assigned to him that has no serial number.
You could handle this in two ways - depending on the business requirements:
- eliminate assets without a serial number by adding one more condition to the GlideRecord in the server side script include:
gr.addQuery('assigned_to', openedForSysId); // Assuming 'opened_for' is a reference field to sys_user
gr.addNotNullQuery('serial_number') // Don't load assets with no serial number
- or add something else instead of the serial number - if it is missing - when loading the assets:
while (gr.next()) {
serialNumbers.push(gr.serial_number.nil() ?
'#N/A (' + gr.model.getDisplayValue() + ')' :
gr.serial_number.toString());
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-05-2024 05:26 AM
Well, sometimes I get the feeling you are not reading my posts :-).
To quote myself from above:
Which raises the issue that even my configuration is not correct as for this script the proper configuration is Mobile / Service Portal really as variable g_modal is not available in Core UI, so the script would fail in that UI.
For Core UI (what you call "classic workspace"*) the solution is totally different, one based on GlideModal and UI Pages.
If you want to support both UIs, you could write a Client Script something like below:
function onChange (control, oldValue, newValue, isLoading, isTemplate) {
if (newValue != '')
getMessage('Incidents of the Opened for user', showList(newValue));
function showList (callerId) {
return function (title) {
if (typeof g_modal == 'undefined')
showListInCoreUI(title, callerId);
else
showListInWorkspace(title, encodeURIComponent('caller_id=' + callerId + '^ORDERBYDESCsys_created_on'));
};
}
function showListInCoreUI (title, callerId) {
var $gm = new GlideModal('show_list');
$gm.setTitle(title);
$gm.setSize(768);
$gm.setPreference('focusTrap', true);
$gm.setPreference('table', 'incident_list');
$gm.setPreference('sysparm_query', 'caller_id=' + callerId + '^ORDERBYDESCsys_created_on');
$gm.setPreference('sysparm_view', 'sys_popup');
$gm.render();
}
function showListInWorkspace (title, query) {
g_modal.showFrame({
'height': '64rem',
'size': 'lg',
'title': title,
'url': '/incident_list.do?sysparm_query=' + query + '&sysparm_isWorkspace=true&sysparm_view=sys_popup',
});
}
}
As is this uses not GlideAjax, so the Script Include is not even needed anymore.
And pops up mostly the same dialog in both "places".
This could be enhanced so that the Script Include is repurposed to return the no. of incidents an Opened for user has and only do the popping if there is at least one incident - using GlideAjax, of course.
Also it would be possible to do a Workspace native solution where the dialog is defined in UI Builder, end responding to framework events triggers the dialog, but it would be far more complex.
And the difference would be maybe nicer visuals (in Service Operations Workspace).
*) In ServiceNow world classic and workspace are actually yin and yen - two different, opposing terms when talking about UI; workspace is what replaces classic UI, so anything but the same thing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-26-2023 07:02 AM
Well, I assume GlideAjax('YourAjaxScript') will actually end up as GlideAjax('Last10TicketsUtil').
But there are more questions to be answered before the code could be declared OK.
Like what are the scopes of the client side script and of the Script Include?
Has the Script Include been marked as Client callable?
Where will the client script run - Core UI, Portal or Workspace?
One thing that might not be correct is g_modal.show.
I don't know that g_modal has a method called show - but I might be wrong here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-26-2023 02:24 PM
Create a UI Script:
- Navigate to "System Definition" > "Scripts" > "Client Scripts" in ServiceNow.
- Create a new client script for the table or interaction where you want to trigger the pop-up.
Write JavaScript to Fetch and Display Data:
- In the client script, you'll need to use GlideAjax or another mechanism to fetch the last 10 tickets based on the opened_for field.
- Display the results in a modal/pop-up.
Client-Side Scripting (Optional):
- If you want to dynamically load and display these records on the user interface when an interaction loads, you may also need to write client-side scripts.
- Use JavaScript to interact with the DOM and fetch the records from the server.
- You might use ServiceNow's GlideAjax or a similar mechanism to fetch the records asynchronously.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-27-2023 03:24 PM
@-O- I would run it on the interaction form and will check on client callable
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-27-2023 10:47 PM
So assuming both data and the scripts reside in global scope and that the correct Script Include name is used when creating the GlideAjax, it should mostly be OK, except for the
g_modal.show('Last 10 Tickets', answer);
part, as that object has no such method.
This can be solved in various ways:
- use g_modal.alert to display the data, but in this case you need to return plain text from the Script Include, as HTML is not supported in the message
- use g_modal.showFields to display the data placing the returned HTML into a field of type HTML; this however might not be configurable to only display an OK button - or at least I don't know how to do it.
- use g_modal.showFrame to display a UI Page which will also "collect" the data to display - in this case the GlideAjax call and related Script Include is not even needed.
- create a new page variant for the Workspace that displays these Interaction records, adding a modal to the page variant and configure actions and events to trigger that modal; it may be that creating a new page variant is not needed, if the currently use page variant can be edited, you could just add the modal and configure raising and reacting to events.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-28-2023 04:43 AM
@-O- so what is the best method to use when the interaction load that the last 10 tickets of the users be displayed ?