Input validation on profile page portal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 hours ago
Hi Team,
I am new to service portal/widget. I have one requirement below.
Apply Validation Regex for all the profile fields that user can edit.
- Apply RegX validation for profile page.
So could anyone please help to how to add the validation logic in below code.
HTML:<div class="default-focus-outline">
<div ng-if="!data.userExists" class="panel panel-default">
<div class="panel-body wrapper-lg text-center">
<p>${Requested user not found}</p>
</div>
</div>
<div ng-if="data.userExists">
<div class="panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-sm-4 text-center">
<div class="row">
<div class="avatar-extra-large avatar-container" style="cursor:default;">
<div class="avatar soloAvatar bottom">
<div class="sub-avatar mia" ng-style="avatarPicture"><i class="fa fa-user"></i></div>
</div>
</div>
</div>
<div class="row">
<button ng-if="::connectEnabled()" ng-click="openConnectConversation()" type="button"
class="btn btn-primary send-message"><span class="glyphicon glyphicon-comment pad-right"></span>${Message}</button>
<!-- file upload -->
<span ng-if="::data.isLoggedInUsersProfile">
<input ng-show="false" type="file" accept="image/jpeg,image/png,image/bmp,image/x-windows-bmp,image/gif,image/x-icon,image/svg+xml" ng-file-select="attachFiles({files: $files})" />
<button ng-click="uploadNewProfilePicture($event)"
ng-keypress="uploadNewProfilePicture($event)" type="button"
class="btn btn-default send-message">${Upload Picture}</button>
</span>
</div>
</div>
<div class="col-xs-12 col-sm-8">
<h2>{{data.name}}</h2>
<p ng-if="::displayField('sys_user', 'company', true)"><strong class="pad-right">${Company}</strong><sp-editable-field editable-by-user="false" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.company"></sp-editable-field></p>
<p ng-if="::displayField('sys_user', 'title', true)"><strong class="pad-right">${Title}</strong><sp-editable-field editable-by-user="false" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.title"></sp-editable-field></p>
<p ><strong class="pad-right">${Department}</strong><sp-editable-field editable-by-user="false" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.department"></sp-editable-field></p>
<p ><strong class="pad-right">${Location}</strong><sp-editable-field editable-by-user="false" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.location"></sp-editable-field></p></div>
</div>
</div>
</div>
<div class="row">
<div ng-class="{'col-md-6': teamExists(), 'col-md-12': !teamExists()}" class="col-sm-12 col-xs-12">
<div class="panel panel-default b" ng-if="getSysUserModelFields().length > 0">
<div class="panel-heading">
<h2 class="panel-title">
<i class="fa fa-info-circle m-r-sm"></i>${About}
</h2>
</div>
<div class="body padder-xs">
<div class="list-group">
<div ng-repeat="fieldModel in sysUserModelFields">
<div class="list-group-item">
<div>
<sp-editable-field block="true" table="{{data.table}}" editable-by-user="data.isLoggedInUsersProfile" table-id="data.sysUserID" field-model="fieldModel"></sp-editable-field>
</div>
</div>
</div>
</div>
</div>
<div class="panel-footer clearfix" ng-if="data.dateTimeFormatChanged">
<a id="refresh-to-complete-date-format-change" href="javascript:void(0)"
ng-click="reloadPage()" class="pull-right btn btn-primary"><i class="fa fa-refresh m-r-sm" aria-hidden="true"></i>${Refresh page to complete date/time format change}</a>
</div>
</div>
</div>
<div ng-if="teamExists()" class="col-md-6 col-sm-12 col-xs-12">
<sp-widget widget="data.teamWidget"></sp-widget>
</div>
</div>
<div class="row" ng-if="data.preferencesEnabled.preferencesPanelEnabled">
<div class="col-sm-12 col-xs-12">
<div class="panel panel-default b">
<div class="panel-heading">
<h2 class="panel-title">
<i class="fa fa-cog m-r-sm"></i>${User preferences}
</h2>
</div>
<div class="body padder-xs">
<div class="list-group">
<div class="list-group-item">
<label>${Accessibility enabled} </label>
<div class="input-switch">
<input type="checkbox"
ng-change="setUserPreferenceValue(data.userPreferences.accessibility)"
ng-model="data.userPreferences.accessibility.value"
name="accessibility-enabled" id="accessibility-enabled" aria-label="${Accessibility enabled}"/>
<label class="switch" for="accessibility-enabled" ng-click="toggle($event, data.userPreferences.accessibility)" role="presentation" aria-hidden="true">
<span class="sr-only">${Accessibility enabled}</span>
</label>
</div>
</div>
<div class="list-group-item" ng-if="data.showAnalytics">
<label>${Enable Analytics} </label>
<div class="input-switch">
<input type="checkbox"
ng-change="updateUserTracking(data.userPreferences.analytics)"
ng-model="data.userPreferences.analytics.value"
name="analytics-enabled" id="analytics-enabled" aria-label="${Enable Analytics}"/>
<label class="switch" for="analytics-enabled" ng-click="toggle($event, data.userPreferences.analytics)" role="presentation" aria-hidden="true">
<span class="sr-only">${Enable Analytics}</span>
</label>
</div>
</div>
<div class="list-group-item" ng-if="data.preferencesEnabled.timezoneEnabled">
<label for="time_zone_picker_select">${Time zone}</label>
<select id="time_zone_picker_select" class="form-control "
name="time_zone_picker_select" ng-model="data.listProperties.timezone.current"
ng-change="setPreferenceValue('timezone', data.listProperties.timezone.current.value)"
ng-options="item as item.label for item in data.listProperties.timezone.list"/>
</div>
<div class="list-group-item" ng-if="data.preferencesEnabled.languageEnabled">
<label for="language_picker_select">${Language}</label>
<select id="language_picker_select" class="form-control"
name="language_picker_select" ng-model="data.listProperties.language.current"
ng-change="setPreferenceValue('language', data.listProperties.language.current.value)"
ng-options="item as item.label for item in data.listProperties.language.list "/>
</div>
<div class="list-group-item" ng-if="data.preferencesEnabled.encryptionEnabled">
<label for="encryption_picker_select">${Encryption}</label>
<span class="fa fa-lock"></span>
<select id="encryption_picker_select" class="form-control"
name="encryption_picker_select" ng-model="data.listProperties.encryption.current"
ng-change="setPreferenceValue('encryption', data.listProperties.encryption.current.value)"
ng-options="item as item.label for item in data.listProperties.encryption.list "/>
</div>
<div class="list-group-item" ng-if="data.preferencesEnabled.mfaEnabled">
<button class="btn btn-link" ng-click="triggerMFAConfigurationModal()" aria-haspopup="dialog">${Configure Multi-Factor Authentication}</button>
</div>
<div class="list-group-item" ng-if="data.preferencesEnabled.certAuthEnabled">
<button class="btn btn-link" ng-click="triggerCertificateConfigurationModal()" aria-haspopup="dialog">${Register your client certificate}</button>
</div>
<div class="list-group-item" ng-if="data.notificationPreferences">
<button class="btn btn-link" ng-click="c.openModal()" aria-haspopup="dialog">${Configure Alert and Notification Preference}</button>
</div>
</div>
</div>
<div class="panel-footer clearfix" ng-if="data.userPreferencesChanged">
<a id="refresh-to-see-changes" href="javascript:void(0)"
ng-click="reloadPage()" class="pull-right btn btn-primary"><i class="fa fa-refresh m-r-sm" aria-hidden="true"></i>${Refresh to see changes}</a>
</div>
</div>
</div>
<script type="text/ng-template" id="mfaModalTemplate">
<div>
<div class="modal-header">
<h1 class="h4 modal-title" style="display: inline-block">${Complete the steps below to enable multi-factor authentication}</h1>
<i class="fa fa-close pull-right text-base" autofocus="true" tabindex="0" ng-click="dismissMFAConfigurationModal()" aria-label="${Close dialog}" role="button"></i>
</div>
<div class="modal-body">
<iframe id="mfa-config-window" src="/google_auth_setup_dialog" width="100%" height="500px" frameBorder="0"></iframe>
</div>
</div>
</script>
<script type="text/ng-template" id="certAuthModalTemplate">
<div>
<div class="modal-header">
<h1 class="h4 modal-title" id="certAuthModal" style="display: inline-block">${PIV/CAC Certificate Found}</h1>
<i class="fa fa-close pull-right text-base" tabindex="0" ng-click="dismissCertAuthConfigurationModal()" aria-label="${Close dialog}" role="button"></i>
</div>
<div class="modal-body">
<iframe id="cert-auth-config-window" src="/cert_confirm_page" width="100%" height="240px" frameBorder="0"></iframe>
</div></div>
</script>
</div>
</div>
</div>
Client Controller:api.controller = function($scope, $element, $window, $location, $rootScope, $timeout, snAttachmentHandler, $http, spUtil, userPreferences, $filter, i18n, $uibModal, spModal, $q) {//START ALERT USER PREFENCE/* widget controller */var c = this;//open alert preference modal.c.openModal = function() {title: 'Configure Alert and Notification Preference',buttons: [{label: '',hide: true},{label: '',hide: true}],widgetInput: {},size: 'lg'}).then(function() {console.log('widget dismissed');});};$scope.$watch('data.dateTimeFormat', function() {if ($scope.data.dateTimeFormat != g_user_date_time_format)$scope.data.dateTimeFormatChanged = true;});$scope.uploadNewProfilePicture = function($event) {$event.stopPropagation();if ($event.keyCode === 9) {return;}var $el = $element.find('input[type=file]');$el.click();}$scope.attachFiles = function(files) {var file = files.files[0];var validImage = false;switch (file.type) {case 'image/jpeg':case 'image/png':case 'image/bmp':case 'image/x-windows-bmp':case 'image/gif':case 'image/x-icon':case 'image/svg+xml':validImage = true;break;default:break;}if (!validImage) {alert(file.name + " " + i18n.getMessage("isn't a recognized image file format"));return;}snAttachmentHandler.create("live_profile", $scope.data.liveProfileID).uploadAttachment(file, {sysparm_fieldname: "photo"}).then(function(response) {var obj = {};obj.newAvatarId = response.sys_id;$ $rootScope.$broadcast("sp.avatar_changed", obj);});}$scope.avatarPicture = "";spUtil.recordWatch($scope, "sys_user", "sys_id=" + $scope.data.sysUserID);spUtil.recordWatch($scope, "live_profile", "sys_id=" + $scope.data.liveProfileID);$scope.connectEnabled = function() {return $scope.data.connectEnabled && !$scope.data.isLoggedInUsersProfile;}$scope.openUserProfile = function($event, userID) {$event.stopPropagation();$event.preventDefault();$location.search("id=user_profile&sys_id=" + userID);}$scope.getSysUserModelFields = function() {if ($scope.data.userExists) {return $scope.data.sysUserModelList.filter(function(field) {return $scope.displayField("sys_user", field.name);});}return [];}$scope.data.showAnalytics = $scope.data.analytics_enabled && $scope.data.sp_analytics_plugin_active && !$scope.data.consent_popup_disabled && !$scope.data.ucm_encountered_exception && !NOW.user_impersonating && NOW.sp_analytics_portal_override != true;$scope.data.userPreferencesChanged = false;$scope.data.dateTimeFormatChanged = false;var getListValuesForProperty = function(endpoint, listProperty) {if (response && response.data && response.data.result && response.data.result.list) {if (!listProperty.list)listProperty.list = [];listProperty.list = response.data.result.list;if (response.data.result.current) {if (!listProperty.current)listProperty.current = {};listProperty.current = $filter('filter')(listProperty.list, {value: response.data.result.current}, true)[0];}}});};// list of user properties that are not user preferences$scope.data.listProperties = {timezone: {},encryption: {},language: {}}// initialize dropbox datagetListValuesForProperty('timezone', $scope.data.listProperties.timezone);getListValuesForProperty('language', $scope.data.listProperties.language);getListValuesForProperty('encryption', $scope.data.listProperties.encryption);//set the user property$scope.setPreferenceValue = function(endpoint, value) {current: value,id: value}).then(function(response) {if (response && response.data && response.data.result) {$scope.data.userPreferencesChanged = true;}});}//set the user preference value$scope.setUserPreferenceValue = function(userProperty) {userPreferences.setPreference(userProperty.key, userProperty.value).then(function() {$scope.data.userPreferencesChanged = true;});};$scope.updateUserTracking = function(userProperty) {$scope.setUserPreferenceValue(userProperty);$scope.server.get({action: "update_session_tracking_info",user_tracking: userProperty.value}).then(function() {NOW.usage_tracking.usage_tracking_allowed_for_session = userProperty.value;});};$scope.toggle = function(e, userProperty) {if (e.type === 'keypress' && e.keyCode === 32) {userProperty.value = !userProperty.value;$scope.setUserPreferenceValue(userProperty);}}$scope.reloadPage = function() {$window.location.reload(true);};$scope.teamExists = function() {return $scope.data.teamData.direct_reports.length > 0 ||$scope.data.teamData.members.length > 0 ||$scope.data.teamData.manager;}var models = {sys_user: $scope.data.sysUserModel,live_profile: $scope.data.liveProfileModel}$scope.displayField = function(tableName, field, isHeader) {if (!isHeader && fieldExcludes[tableName].indexOf(field) > -1) {// if (fieldExcludes[tableName].indexOf(field) > -1){return false} else {return true;}// if (models[tableName][field] && models[tableName][field].type === "boolean") return false;// if ($scope.data.isLoggedInUsersProfile) {// if (models[tableName][field] && models[tableName][field].readonly)// return models[tableName][field].displayValue;// else// return models[tableName][field];// } else {// return models[tableName][field] && models[tableName][field].displayValue;// }}$scope.server.update().then(function(response) {if (response.certHeader == 'false')spUtil.addErrorMessage($scope.data.certErrorMsg);else {});}$timeout(function() {$rootScope.$broadcast('finishedChanged', {profile: $scope.data.teamData});});$scope.sysUserModelFields = $scope.getSysUserModelFields();function createCloseMFAModalHandler() {// This is a hack. Wait for the inner iframe to load, then mock// the GlideDialogWindow close function to do the right thing. If it's not ready// after a second, try again 9 more times.var retryCount = 0;var maxRetries = 10;tryOverrideGlideDialogWindowClose();function tryOverrideGlideDialogWindowClose() {$timeout(function() {var frameGlideDialogWindow = document.getElementById('mfa-config-window').contentWindow['GlideDialogWindow'];if (!frameGlideDialogWindow) {retryCount++;if (retryCount >= maxRetries)return;tryOverrideGlideDialogWindowClose();return;}frameGlideDialogWindow.get = function() {return {destroy: function() {$scope.dismissMFAConfigurationModal();}}};}, 1000);}}function createCloseCertAuthModalHandler() {// This is a hack. Wait for the inner iframe to load, then mock// the GlideDialogWindow close function to do the right thing. If it's not ready// after a second, try again 9 more times.var retryCount = 0;var maxRetries = 10;tryOverrideGlideDialogWindowClose();function tryOverrideGlideDialogWindowClose() {$timeout(function() {var frameGlideDialogWindow = document.getElementById('cert-auth-config-window').contentWindow['GlideDialogWindow'];if (!frameGlideDialogWindow) {retryCount++;if (retryCount >= maxRetries)return;tryOverrideGlideDialogWindowClose();return;}frameGlideDialogWindow.get = function() {return {destroy: function() {$scope.dismissCertAuthConfigurationModal();}}};}, 1000);}}}
Server side:if (input && input.action === "update_session_tracking_info") {gs.getSession().putProperty("usage_tracking_allowed_for_session", input.user_tracking);//return;}data.analytics_enabled = GlideProperties.getBoolean("glide.analytics.enabled");data.sp_analytics_plugin_active = GlidePluginManager.isActive('com.glide.service-portal.analytics');data.consent_popup_disabled = GlideProperties.getBoolean("glide.analytics.user.consent.popup.disabled");data.ucm_encountered_exception = gs.getSession().getProperty("ucm_encountered_exception") == true;// populate the 'data' object// e.g., data.table = $sp.getValue('table');data.sysUserID = $sp.getParameter("sys_id");if (!data.sysUserID)data.sysUserID = gs.getUser().getID();var sysUserGR = new GlideRecord("sys_user");data.userExists = sysUserGR.get(data.sysUserID) && sysUserGR.canRead();if (data.userExists) {sysUserGR = GlideScriptRecordUtil.get(sysUserGR).getRealRecord();data.table = sysUserGR.getRecordClassName();data.name = sysUserGR.getValue("name");var loggedInSysUserID = gs.getUser().getID();data.connectEnabled = GlidePluginManager().isActive('com.glide.connect');data.liveProfileID = "";data.dateTimeFormat = gs.getDateTimeFormat();//get live profile id for sending connect messagesif (GlidePluginManager().isActive('com.glideapp.live_common')) {var liveProfileGR = new GlideRecord("live_profile");liveProfileGR.addQuery("document", data.sysUserID);liveProfileGR.query();if (liveProfileGR.next()) {data.liveProfileID = liveProfileGR.getValue("sys_id");data.liveProfileModel = $sp.getForm("live_profile", data.liveProfileID)._fields;// live_profile short_description is shown here as "Bio", so popup label/hint must reflect thatif (data.liveProfileModel.short_description) {data.liveProfileModel.short_description.label = gs.getMessage("Bio");data.liveProfileModel.short_description.hint = gs.getMessage("Biography");}} elsedata.connectEnabled = false; //can't find a live profile for this user, so lets not integrate Connect}data.isLoggedInUsersProfile = loggedInSysUserID.equals(data.sysUserID);var sysUserForm = $sp.getForm(data.table, data.sysUserID);data.sysUserView = sysUserForm._view;data.sysUserModel = sysUserForm._fields;data.sysUserModelList = [];for (var i = 0; i < data.sysUserView.length; i++) {data.sysUserModelList.push(data.sysUserModel[data.sysUserView[i].name]);}data.directReports = [];data.teamData = {};data.teamData.direct_reports = [];data.teamData.members = [];if (!data.isLoggedInUsersProfile) {data.teamData.user = {sys_id: data.sysUserID}}//Calculate managervar managerGR = new GlideRecord("sys_user");if (managerGR.get(sysUserGR.getValue("manager"))) {data.teamData.manager = buildUser(managerGR);}//Calculate teamif (data.teamData.manager) {var teamGR = new GlideRecord("sys_user");teamGR.addActiveQuery();teamGR.orderBy("name");teamGR.addQuery("manager", data.teamData.manager.sys_id);teamGR.addQuery("sys_id", "!=", data.sysUserID);teamGR.query();while (teamGR.next())data.teamData.members.push(buildUser(teamGR));}//Calculate direct reportsvar directReportGR = new GlideRecord("sys_user");directReportGR.addActiveQuery();directReportGR.orderBy("name");directReportGR.addQuery("manager", data.sysUserID);directReportGR.query();while (directReportGR.next())data.teamData.direct_reports.push(buildUser(directReportGR));data.teamWidget = $sp.getWidget('sp-my-team', {glyph: 'user',color: 'primary'});//get state preferencesdata.preferencesEnabled = getPreferencesEnabled();//get the user Preferences of the userdata.userPreferences = getUserPreferences(data.sysUserID);//data.notificationPreferences = getNotificationPreferences();}//get the certificate headerif (input.action == "certRegister") {var request = GlideTransaction.get().getRequest();var certHeader = request.getHeader("X-Client-Cert");if (!certHeader) {data.certHeader = "false";data.certErrorMsg = gs.getMessage("Failed to register PIV/CAC certificate to the user account. Please close your browser, ensure your card is inserted and try again");}}function buildUser(userGR) {return {email: userGR.getValue("email") || "",first_name: userGR.getValue("first_name"),last_name: userGR.getValue("last_name"),name: userGR.getValue("name"),phone: userGR.getValue("phone") || "",sys_id: userGR.getValue("sys_id")}}// returns the user preferences from the platformfunction getUserPreferences(userID) {var user = GlideUser.getUserByID(userID);return {accessibility: {key: 'glide.ui.accessibility',value: user.getPreference('glide.ui.accessibility') == 'true'},analytics: {key: 'enable_analytics',value: user.getPreference('enable_analytics') == 'true'}}}function getNotificationPreferences() {if (gs.getProperty('fedramp.req2.enable_alerts_notifications') === 'false') {return false;}var groupsForNotification = ["Customer Admins","Customer Admins - No Supplies","Customer Basic Access","Customer Ordering","Customer Ordering Service Only","Customer Ordering Supplies Only"];var user = gs.getUser();for (var i = 0; i < groupsForNotification.length; i++) {if (user.isMemberOf(groupsForNotification[i])) {return true;}}return false;}// read the proper state so we can show/hide preferences in the preferences tablefunction getPreferencesEnabled() {var showEncryption = pm.isActive('com.glide.encryption') &&gs.getProperty('glide_encryption.cle_replatforming_with_kmf') !== 'opt_in' &&new SNC.ConcoursePickerGenerator().hasMultipleEncryptionChoices();//Enabling certificate based authentication per portalvar portalRecord = $sp.getPortalRecord();if (portalRecord && (portalRecord.getValue('enable_certificate_based_authentication') == 1))var cert_based_auth = gs.getProperty('glide.authenticate.mutual.enabled', 'false') == 'true';return {$sp.getParameter('sys_id') == gs.getUserID(),//certain properties are visible in some caseslanguageEnabled: pm.isActive('com.glide.i18n') && gs.getProperty('glide.ui.language_picker.enabled', 'true') == 'true',timezoneEnabled: true,encryptionEnabled: showEncryption,mfaEnabled: gs.getProperty('glide.authenticate.multifactor', "false") == "true",certAuthEnabled: cert_based_auth}}
