- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-12-2022 06:43 AM
I recently downloaded the 'My Delegates Widget' from https://snhackery.com/ and was having a go at modifying it so I can add the Start and End dates to the widget. I suceeded in getting the date fields to show and even saving the information entered. However, I can't get the fields to display the data once saved. I don't know the code well enough to understand what's acheviable. Hopefully someone can help.
This is me adding a new record:
The data saved in the back-end:
The widget when I revisit the page:
If I change the input type to 'text', I can see the data is there, so I reckon I need to do something clever to get the data showing in the date input type:
Here's the code from the widget:
HTML:
<snh-panel title="'${My Delegates}'" class="panel panel-primary">
<div style="width: 100%; padding: 5px 50px;">
<table class="table table-hover table-condensed">
<thead>
<tr>
<th style="text-align: center;">Delegate</th>
<th style="text-align: center;">Approvals</th>
<th style="text-align: center;">Assignments</th>
<th style="text-align: center;">CC on Notifications</th>
<th style="text-align: center;">Start Date</th>
<th style="text-align: center;">End Date</th>
<th style="text-align: center;">Remove</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in c.data.listItems track by item.id | orderBy: 'delegate'" ng-hide="item.removed">
<td data-th="Delegate">
<sn-avatar class="avatar-small-medium" primary="item.id" show-presence="true"/>
<!--<a href="?id=user_profile&table=sys_user&sys_id={{item.id}}" title="{{item.delegate}}">{{item.delegate}}</a>-->
</td>
<td data-th="Approvals" style="text-align: center;"><input type="checkbox" ng-model="item.approvals"/></td>
<td data-th="Assignments" style="text-align: center;"><input type="checkbox" ng-model="item.assignments"/></td>
<td data-th="CC on Notifications" style="text-align: center;"><input type="checkbox" ng-model="item.notifications"/></td>
<td data-th="Start Date" style="text-align: center;"><input type="date" ng-model="item.starts"/></td>
<td data-th="End Date" style="text-align: center;"><input type="date" ng-model="item.ends"/></td>
<td data-th="Remove" style="text-align: center;"><img src="/images/delete_row.gif" ng-click="removePerson($index)" alt="Click here to remove this person as a delegate" title="Click here to remove this person from the list" style="cursor: pointer;"/></td>
</tr>
</tbody>
</table>
<p>To add a delegate to the list, select a person from below:</p>
<sn-record-picker id="snrp" field="data.personToAdd" ng-change="addSelected()" table="'sys_user'" display-field="'name'" display-fields="'title,department,location,email'" value-field="'sys_id'" search-fields="'name'" page-size="20"></sn-record-picker>
<br/>
<p>To remove a delegate from the list, click on the Remove icon.</p>
</div>
<div style="width: 100%; padding: 5px 50px; text-align: center;">
<button ng-click="saveDelegates()" class="btn btn-primary ng-binding ng-scope" role="button" title="Click here to save your changes">Save</button>
<button ng-click="returnToProfile()" class="btn ng-binding ng-scope" role="button" title="Click here to cancel your changes">Cancel</button>
</div>
<div style="width: 100%; padding: 5px 50px;" ng-show="data.list2Items.length>0">
<b>I am a Delegate for:</b>
<div ng-repeat="item in c.data.list2Items track by item.id | orderBy: 'user'" style="padding: 5px;">
<sn-avatar class="avatar-small-medium" primary="item.id" show-presence="true"/>
<!--<a href="?id=user_profile&table=sys_user&sys_id={{item.id}}" title="{{item.user}}">{{item.user}}</a>-->
for {{item.delegations}}
<span ng-show="item.ends"> until {{item.ends}}</span>
</div>
</div>
</snh-panel>
Server Script:
(function() {
data.userID = gs.getUser().getID();
data.listItems = data.listItems || fetchList();
data.list2Items = data.list2Items || fetchList2();
if (input) {
data.listItems = input.listItems || fetchList();
if (input.personToAdd && input.personToAdd.value > '') {
addPersonToList(input.personToAdd.value);
}
if (input.button == 'save') {
saveList();
}
}
function fetchList() {
var gdt = new GlideDateTime();
var list = [];
var delegateGR = new GlideRecord('sys_user_delegate');
delegateGR.addQuery('user', data.userID);
delegateGR.orderBy('delegate.name');
delegateGR.query();
while (delegateGR.next()) {
var thisDelegate = {};
thisDelegate.sys_id = delegateGR.getValue('sys_id');
thisDelegate.id = delegateGR.getValue('delegate');
thisDelegate.delegate = delegateGR.getDisplayValue('delegate');
thisDelegate.approvals = (delegateGR.getValue('approvals') == 1);
thisDelegate.assignments = (delegateGR.getValue('assignments') == 1);
thisDelegate.notifications = (delegateGR.getValue('notifications') == 1);
thisDelegate.starts = delegateGR.getDisplayValue('starts');
thisDelegate.ends = delegateGR.getDisplayValue('ends');
list.push(thisDelegate);
}
return list;
}
function fetchList2() {
var list = [];
var today = new Date();
var delegationGR = new GlideRecord('sys_user_delegate');
delegationGR.addQuery('delegate', data.userID);
delegationGR.orderBy('user.name');
delegationGR.query();
while (delegationGR.next()) {
var stillActive = true;
var endDate = '';
if (delegationGR.getValue('ends')) {
endDate = new GlideDate();
endDate.setValue(delegationGR.getValue('ends'));
endDate = endDate.getByFormat('dd/MM/yyyy');
if (today.after(new Date(endDate))) {
stillActive = false;
} else {
if (new Date(endDate).getFullYear() == 2100) {
endDate = '';
}
}
}
if (stillActive) {
var thisDelegation = {};
var delegations = [];
if (delegationGR.getValue('approvals') == 1) {
delegations.push('Approvals');
}
if (delegationGR.getValue('assignments') == 1) {
delegations.push('Assignments');
}
if (delegationGR.getValue('notifications') == 1) {
delegations.push('CC on Notifications');
}
if (delegations.length > 0) {
thisDelegation.sys_id = delegationGR.getValue('sys_id');
thisDelegation.id = delegationGR.getValue('user');
thisDelegation.user = delegationGR.getDisplayValue('user');
thisDelegation.ends = endDate;
thisDelegation.delegations = '';
var separator = '';
for (var i=0; i<delegations.length; i++) {
thisDelegation.delegations += separator;
thisDelegation.delegations += delegations[i];
if (delegations.length > 2) {
separator = ', ';
if (i == (delegations.length - 2)) {
separator = ', and ';
}
} else {
separator = ' and ';
}
}
list.push(thisDelegation);
}
}
}
return list;
}
function saveList() {
for (var i=0; i<data.listItems.length; i++) {
var thisDelegate = data.listItems[i];
if (thisDelegate.removed) {
if (thisDelegate.sys_id != 'new') {
var gr = new GlideRecord('sys_user_delegate');
gr.get(thisDelegate.sys_id);
gr.deleteRecord();
}
} else {
var delegateGR = new GlideRecord('sys_user_delegate');
if (thisDelegate.sys_id != 'new') {
delegateGR.get(thisDelegate.sys_id);
} else {
delegateGR.initialize();
delegateGR.user = data.userID;
delegateGR.delegate = thisDelegate.id;
delegateGR.starts = thisDelegate.starts;
delegateGR.ends = thisDelegate.ends;
}
delegateGR.approvals = thisDelegate.approvals;
delegateGR.assignments = thisDelegate.assignments;
delegateGR.notifications = thisDelegate.notifications;
delegateGR.update();
}
}
gs.addInfoMessage('Your Delegate information has been updated.');
}
function addPersonToList(selected) {
var existing = -1;
for (var i=0; i<data.listItems.length && existing == -1; i++) {
if (data.listItems[i].id == selected) {
existing = i;
}
}
if (existing == -1) {
var thisDelegate = {};
thisDelegate.sys_id = 'new';
thisDelegate.id = selected;
var userGR = new GlideRecord('sys_user');
userGR.get(selected);
thisDelegate.delegate = userGR.getDisplayValue('name');
thisDelegate.approvals = true;
thisDelegate.assignments = true;
thisDelegate.notifications = true;
thisDelegate.starts = true;
thisDelegate.ends = true;
data.listItems.push(thisDelegate);
} else {
data.listItems[existing].removed = false;
}
input.personToAdd = {};
}
})();
Client controller:
function MyDelegates($scope, $window) {
var c = this;
$scope.addSelected = function() {
$scope.server.update().then(function(response) {
$('#snrp').select2("val","");
});
};
$scope.removePerson = function(i) {
c.data.listItems[i].removed = true;
};
$scope.saveDelegates = function() {
c.data.button = 'save';
$scope.server.update().then(function(response) {
reloadPage();
});
};
$scope.returnToProfile = function() {
reloadPage();
};
function reloadPage() {
$window.location.reload();
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-14-2022 01:55 PM
Hi
You can use <sn-date-picker> for this:
Replace '<input type="date" ng-model="item.starts"/>' with
<sp-date-picker field="item.starts" ng-model="item.starts" sn-change="" sn-include-time="true"/>
and
Replace '<input type="date" ng-model="item.ends"/>' with
<sp-date-picker field="item.ends" ng-model="item.ends" sn-change="" sn-include-time="true"/>
Taranjeet
Please mark reply as Helpful/Correct, if applicable. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-14-2022 01:55 PM
Hi
You can use <sn-date-picker> for this:
Replace '<input type="date" ng-model="item.starts"/>' with
<sp-date-picker field="item.starts" ng-model="item.starts" sn-change="" sn-include-time="true"/>
and
Replace '<input type="date" ng-model="item.ends"/>' with
<sp-date-picker field="item.ends" ng-model="item.ends" sn-change="" sn-include-time="true"/>
Taranjeet
Please mark reply as Helpful/Correct, if applicable. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-15-2022 01:55 AM
Excellent! Thanks
Here's the working widget:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-17-2022 03:41 PM
Nice enhancement! I like it!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-19-2022 01:37 AM
Thanks! I appreciate you sharing the widget in the first place.
I've parked this for the time being as I get intermittent results where I select a user to delegate to, but it doesn't get added to the form on the portal. However, the record is created on the backend. I can't replicate it now so maybe my tinkering has fixed it.
Also, I want to hide delegations that have expired. Looking at the code, I thought it did this already, but that isn't the case. I've considered running a daily scheduled job to delete delegation records that have expired anyway, just to keep things tidy.
Thanks again! I love stumbling across little widgets and apps like this. I wish there were a better resource for them.
All the best