- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-27-2018 07:42 AM
Hi
I'm in need of some help with a service portal widget. Here's what I've got so far: the widget displays a list of assets issued to the current user (using a glide record in the server script and ng-repeat in the HTML template). For each asset listed, I've also got a button which doesn't do much at the moment other than display a message (just to prove the click works).
What I want is for the user to be able to click the button along side a particular asset, to confirm they still have it, and for this to update the status / last confirmed date in the respective asset record.
Please can someone confirm the syntax:
- in the HTML template, to pass the sys_id back to the client script (via ng-click?)
- in the client script, to grab the sys_id and pass it on to the server script (via a function and c.server.update?)
- in the server script, to get the sys_id and update a glide record for the correct asset (via input?)
Thanks in advance.
Martin
Solved! Go to Solution.
- 12,385 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-28-2018 12:34 PM
If you're using an ng-repeat with the buttons inside (I assume you are), you have access to the current model that you can pass into the ng-click, like this:
<div ng-repeat="asset in controller.assets">
<button ng-click="confirmAsset(asset);">Confirm!</button>
</div>
In your controller's ng-click handler (I named it confirmAsset here), you would do something like this:
// This is the confirmAsset method on your controller
this.confirmAsset = function(asset) {
// Asset is being bassed from the ng-click
// The controller has a server property with a method called get on it.
// The object you pass to the get() call is passed as "input" on the server-side code.
this.server.get({
// NOTE: This method property is totally unneeded technically.
// I am adding it here so that my server-side code can know exactly what it's supposed to do.
method: "confirmAsset",
asset_sys_id: asset.sys_id
});
}
The server side script would do something like this:
if (input) {
// Adding a method here just in case anything else sends information to the
// client side script, we can distinguish and only handle what we need to.
if (input.method === "confirmAsset") {
// NOTE: tableName here should be the name of the table
var record = new GlideRecord(tableName);
// NOTE: asset_sys_id should be the name of the field you want to update for
// confirmation
record.addQuery("asset_sys_id", input.asset_sys_id);
record.query();
if (record.next()) {
// NOTE: Set whatever field you're using to confirm the asset
record.confirmed = true;
// Update the record.
record.update();
}
}
}
Hope this helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-30-2018 06:42 AM
"asset_sys_id" is just the name of the property of the object I am sending over. Its value is "asset.sys_id", which is the sys_id of the asset at the current iteration. That asset is an object. You may replace that label with anything you'd like. I've simply named it that because that property name reads well to me and lets me know what the value contains.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-05-2024 04:07 AM
Hello,
Wondering if you can help, I am trying to implement the above.
Requirement - when a widget is clicked on the ESC, it counts the clicks. Specifically using the Quick Link widget (or a customised variation of the widget).
Based on the above I have added this to the HTML:
This to the server script:
This to the client controller:
As you can see in the Server Script, I have created a new table and referenced it where required, but do I need to add anything else too it?
Any help appreciated!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-05-2024 04:26 AM
Hi Michael,
Can you give me the exact widget name you're trying to modify? Because this post was originally around assets, I would change some of the variable names to match, and I also suspect that the widget may have an ng-repeat already present that we can drop our code into.
If you'll provide the name of the widget, I can adjust the above example to be better suited for that use case.
m
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-05-2024 04:37 AM
Hi @matthewmaxwell,
It's a duplicate of the Quick Links widget called "Service Catalog (service_Catalog)", the only alterations are some minor formatting, CSS changes.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-05-2024 06:48 AM
Hey Michael,
I was able to get a working example of this.
I created a custom table, as you did here with the same name.
I cloned the Quick Links widget, and made the following changes:
Because there are multiple links in the widget, I opted to leverage event delegation, so in the Widget Link field, I added the following code:
element.on("click", ".link-container a", function (event) {
// Use event delegation so there is only a single DOM event instead of n, where n would be the numebr of quick links
var link;
var itemId;
// This would be the anchor tag, but because events bubble, this could be the span if they clicked the text
link = event.target;
// If the link is not an anchor tag, find the nearest parent element that is an anchor tag
if (link.nodeName !== "A") {
link = $(link).parents("a").get(0);
}
// There is no error handling here, so this may need to be fleshed out a little more
// ID will be a sys_id plus the item-n where n is the index in the array
// Example: "2fd7d372775530104cdac0c23e5a9953-item-0"
// This will replace "2fd7d372775530104cdac0c23e5a9953-item-" with nothing and give us the number
itemId = link.getAttribute("id").replace(/\w+-item-/, "");
controller.recordClick(controller.data.json_data[itemId]);
});
This sets up event delegation to listen for click events on the anchor tags in the link container. I used this method because there are multiple links and because there are multiple different ways that those links display, which you can see by looking at the HTML Template for the `c.data.card_type` checks in the `ng-if`s.
Because events bubble, if someone clicks on the text in the link (the Span node), this will not be the anchor tag, which contains the information we need, so we find the closest parent using `$(link).parents("a")`.
The links have an `id` attribute that is `sys_id-item-index_in_array`. In the second to last line, we get rid of the sys_id, the hypens, and the word `item`, and use that index in the last line to look up the actual link object in the controller data and then pass that into a method I added to the controller.
In the controller, I added the following method:
c.recordClick = function (link) {
this.server.get({
method: "recordClick",
link_sys_id: link.id
});
};
This method will take the link and pass its sys_id to the Server Script.
In the Server Script, I declared a `linkClick` variable at the very top because I like to declare all my variables at the top of the scope, so the definition is not in the following code, but here is the code that records the click into the table:
if (input && input.method === "recordClick") {
linkClick = new GlideRecord("sn_ex_sp_employee_service_center_clicks");
linkClick.initialize();
linkClick.setValue("u_quick_link", input.link_sys_id);
// This console.log should be removed before this goes to production
console.log("Created: " + linkClick.insert());
}
For that table, I did add a single field which is a reference to the quick link table.
Now, when I click the link, I see the following in that table:
I am attaching an update set that has this in it. If you put this in a fresh PDI, you should see everything there.
Let me know if you have any other questions.
m