Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Getting an HTML Input date field to display a date from a record (service portal widget)

Wayne Richmond
Tera Guru

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:

find_real_file.png The data saved in the back-end:

find_real_file.png

The widget when I revisit the page:

find_real_file.png

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:

find_real_file.png

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"/>
            &nbsp;
            <!--<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>
    &nbsp;
    <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"/>
      &nbsp;
      <!--<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();
	}
}

 

1 ACCEPTED SOLUTION

Community Alums
Not applicable

Hi @Wayne Richmond ,

 

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!

View solution in original post

5 REPLIES 5

g k1
Tera Guru

full working code here "this will add names and all also properly" and all credits and special thanks to @SN Hackery 
HTML:-

<snh-panel title="'${My Delegates}'" class="panel panel-primary">
  <!-- level 1 -->
  <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;">Meeting Invitations</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" ng-hide="item.removed">
          <td data-th="Delegate">
            
            
            <span class="navbar-avatar">
              <sn-avatar class="avatar-small-medium" primary="item.id" show-presence="true"/>
            </span>
            &nbsp;
            <a href="?id=user_profile&table=sys_user&sys_id={{item.id}}" title="{{item.delegate}}">{{item.delegate}}</a>
            
          </td>
          <p>
            {{item.start_date}}
          </p>
          <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="Meeting Invitations" style="text-align: center;"><input type="checkbox" ng-model="item.invitations"/></td>
          <td data-th="Start Date" style="text-align: center;"><sp-date-picker  field="item.starts" ng-model="item.starts" sn-change="" sn-include-time="true"/></td>
          <td data-th="End Date" style="text-align: center;"><sp-date-picker  field="item.ends" ng-model="item.ends" sn-change="" sn-include-time="true"/></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>
    <!-- level 1 end -->
    
    
    <!-- level 2 start-> gaurav kumar -->
    
    <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" default-query="'active=true^emailISNOTEMPTY^nameISNOTEMPTY'"></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>
    &nbsp;
    <button ng-click="returnToProfile()" class="btn ng-binding ng-scope" role="button" title="Click here to cancel your changes">Cancel</button>
  </div>
<!-- level 2 end -->
  
  <!-- level 3 start -->
  <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;">
      <span class="navbar-avatar">
              <sn-avatar class="avatar-small-medium" primary="item.id" show-presence="true"/>
            </span>
     <!-- <sn-avatar class="avatar-small-medium" primary="item.id" show-presence="true"/>-->
      &nbsp;
      <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>
<!-- level 3 end -->
</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.invitations = (delegateGR.getValue('invitations') == 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 (delegationGR.getValue('invitations') == 1) {
delegations.push('Meeting Invitations');
}
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.invitations = thisDelegate.invitations;
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.invitations = 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();
}
}
gk1_0-1707413806772.png

download the widget update set (whole page) :
https://snhackery.com/2020/04/21/my-delegates-widget-enhanced/