Skip to main content

Service Portal: modified my profile widget with 'edit profile' widget

Have the profile fields read only but editable when 'edit profile' clicked



New widgets

 

·       new_user_profile (based on OOTB user_profile)

·       Edit Profile (as embedded widget)

 

new_user_profile

 

HTML:

<!--BASED ON COPY OF USER PROFILE-->

<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" width="1140px" height="822px">

        <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">${Change Photo}</button>

              </span>

            </div>

          </div>

          <div>

           

    <div>

         <div style="float:right;">

             <widget id="edit_profile"></widget>

         </div>

   </div>

           

</div>

         

           <!-- EDIT MODE:-->

           <div ng-if="data.editprofile" class="col-xs-12 col-sm-8">

              <h2 class="h2upr">{{data.name}}</h2>

              <h3 class="h3upr">{{data.title2}}</h3>

              <hr style="border: none; border-bottom: 1px solid #CED2DC;">

             <!-- <h4 class="h4upr" ng-if="::displayField('sys_user', 'company', true)">${Company}</h4><sp-editable-field editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.company"></sp-editable-field><br/><br/>

             -->

              <h4 class="h4upr" ng-if="::displayField('sys_user', 'department', true)">${Department}</h4><sp-editable-field editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.department"></sp-editable-field><br/><br/>

              <h4 class="h4upr" ng-if="::displayField('sys_user', 'location', true)">${Location}</h4><sp-editable-field editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.location"></sp-editable-field><br/><br/>

              <h4 class="h4upr" ng-if="::(data.liveProfileID && displayField('live_profile', 'short_description', true))">${Bio}</h4><sp-editable-field editable-by-user="data.isLoggedInUsersProfile" table="live_profile" table-id="data.liveProfileID" field-model="data.liveProfileModel.short_description"></sp-editable-field><br/><br/>

           </div>

          <!-- READ ONLY MODE:-->

          <div ng-if="!data.editprofile" class="col-xs-12 col-sm-8">

              <h2 class="h2upr">{{data.name}}</h2>

              <h3 class="h3upr">{{data.title2}}</h3>

              <hr style="border: none; border-bottom: 1px solid #CED2DC;">

              <!--<h4 class="h4upr" ng-if="::displayField('sys_user', 'company', true)">${Company}</h4>

                     <span>{{data.readonlycompany}}</span><br/><br/> -->

              <h4 class="h4upr" ng-if="::displayField('sys_user', 'department', true)">${Department}</h4>

                       <span class="ro-profile">{{data.readonlydepartment}}</span><br/><br/>

              <h4 class="h4upr" ng-if="::displayField('sys_user', 'location', true)">${Location}</h4>

                        <span class="ro-profile">{{data.readonlylocation}}</span><br/><br/>

              <h4 class="h4upr" ng-if="::(data.liveProfileID && displayField('live_profile', 'short_description', true))">${Bio}</h4>

                        <span class="ro-profile">{{data.bio}}</span><br/><br/>

         

           </div>

         

        </div>

       

       <!-- cc, lm, bp, mp, email -->

        <br/><br/>

       

       

        <div class="col-xs-12 col-sm-4 text-left" style="padding-left: 150px;">

             <div class="list-group-item" >

                  <div>

                   <p ng-if="::displayField('sys_user', 'cost_center', true)">

                     <span class="upr">${Cost center}</span><br/>

                     <!-- EDIT MODE:-->

                     <sp-editable-field ng-if="data.editprofile" editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.cost_center"></sp-editable-field>

                     <!-- READ ONLY MODE:-->

                     <span ng-if="!data.editprofile" class="ro-profile">{{data.readonlycc}}</span>

                    </p>

                  </div>

             </div>

        </div>

        <div class="col-xs-12 col-sm-4 text-left" style="padding-left: 100px;">

             <div class="list-group-item" >

                  <div>

                    <p ng-if="::displayField('sys_user', 'manager', true)">

                      <span class="upr">${Line manager}</span><br/>

                      <!-- EDIT MODE:-->

                      <sp-editable-field ng-if="data.editprofile" editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.line_manager"></sp-editable-field>

                      <!-- READ ONLY MODE:-->

                      <span ng-if="!data.editprofile" class="ro-profile">{{data.readonlylm}}</span>

                    </p>

                </div>

             </div>

        </div>

        <div class="col-xs-12 col-sm-4 text-left" style="padding-left: 50px;">

             <div class="list-group-item" >

                  <div>

                    <p ng-if="::displayField('sys_user', 'phone', true)">

                      <span class="upr">${Business phone}</span><br/>

                      <!-- EDIT MODE:-->

                      <sp-editable-field ng-if="data.editprofile" editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.phone"></sp-editable-field>

                      <!-- READ ONLY MODE:-->

                      <span ng-if="!data.editprofile" class="ro-profile">{{data.readonlyphone}}</span>

                    </p>

                </div>

             </div>

        </div>

        <div class="col-xs-12 col-sm-4 text-left" style="padding-left: 150px;">

            <div class="list-group-item" >

                  <div>

                    <p ng-if="::displayField('sys_user', 'mobile_phone', true)">

                      <span class="upr">${Mobile phone}</span><br/>

                      <!-- EDIT MODE:-->

                      <sp-editable-field ng-if="data.editprofile" editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.mobile_phone"></sp-editable-field>

                      <!-- READ ONLY MODE:-->

                      <span ng-if="!data.editprofile" class="ro-profile">{{data.readonlymobphone}}</span>

                    </p>

                </div>

             </div>

        </div>

        <div class="col-xs-12 col-sm-4 text-left" style="padding-left: 100px;">

            <div class="list-group-item" >

                  <div>

                    <p ng-if="::displayField('sys_user', 'email', true)">

                      <span class="upr">${Email}</span><br/>

                      <!-- EDIT MODE:-->

                      <sp-editable-field ng-if="data.editprofile" editable-by-user="data.isLoggedInUsersProfile" table="sys_user" table-id="data.sysUserID" field-model="data.sysUserModel.email"></sp-editable-field>

                      <!-- READ ONLY MODE:-->

                      <span ng-if="!data.editprofile" class="ro-profile">{{data.readonlyemail}}</span>

                    </p>

                 </div>

             </div>

        </div>

        <!-- end -->

     

    <br/><br/>

    </div>

     

        <!-- Accessibility -->

             <div style="padding-left: 175px;">

                <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>

                  <span class="span-accessibility">${Accessibility enabled} </span>

               </div><br/><br/>

            </div>

        <!-- end -->

     

    </div>

  </div>

</div>

 

 

Server script:

// populate the 'data' object

// e.g., data.table = $sp.getValue('table');

 

var sMsgPadder = "*********************************** ";

 

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();

 

//--check the url param to see if the page was re-loaded in edit mode:

//var sURL_editparam = gs.action.getGlideURI().getMap().get('sysparm_editprofile');

data.editprofile = false;

var sURL_editparam = $sp.getParameter("sysparm_editprofile");

if (sURL_editparam == 'true') {

    data.editprofile = true;

    gs.addInfoMessage(sMsgPadder + gs.getMessage(‘portal.userprofile.edit'));

}

 

if (data.userExists) {

    data.name = sysUserGR.getValue("name");

    var loggedInSysUserID = gs.getUser().getID();

    data.connectEnabled = GlidePluginManager().isActive('com.glide.connect');

    data.liveProfileID = "";

    data.dateTimeFormat = gs.getDateTimeFormat();

   

    data.bio='';

 

    //get live profile id for sending connect messages

    if (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 that

            if (data.liveProfileModel.short_description) {

                data.liveProfileModel.short_description.label = gs.getMessage("Bio");

                data.liveProfileModel.short_description.hint = gs.getMessage("Biography");

               

                data.bio=liveProfileGR.getValue("short_description");

            }

        } else

            data.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("sys_user", 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 manager

    var managerGR = new GlideRecord("sys_user");

    if (managerGR.get(sysUserGR.getValue("manager"))) {

        data.teamData.manager = buildUser(managerGR);

    }

 

    //Calculate team

    if (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 reports

    var 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 preferences

    data.preferencesEnabled = getPreferencesEnabled();

 

    //get the user Preferences of the user

    data.userPreferences = getUserPreferences(data.sysUserID);

 

    //--some difficulty retrieving the title, look at this later...

    data.readonlycompany='';

    data.readonlydepartment='';

    data.readonlylocation='';

   

    data.title2 = 'no title-CHECK';

    var thisUserGR = new GlideRecord("sys_user");

    thisUserGR.addQuery('sys_id', loggedInSysUserID);

    thisUserGR.query();

    if (thisUserGR.next()) {

        data.title2 = thisUserGR.title.toString();

 

        if (data.editprofile != 'true') {

            data.readonlycompany = thisUserGR.getDisplayValue("company")+"";

            data.readonlydepartment = thisUserGR.getDisplayValue("department")+"";

            data.readonlylocation= thisUserGR.getDisplayValue("location")+"";

            data.readonlycc= thisUserGR.getDisplayValue("cost_center")+"";

            data.readonlylm= thisUserGR.getDisplayValue("line_manager")+"";

            data.readonlyemail= thisUserGR.getValue("email");

            data.readonlyphone= thisUserGR.getValue("phone");

            data.readonlymobphone= thisUserGR.getValue("mobile_phone");

        }

    }

    //-------------//

}

 

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 platform

function getUserPreferences(userID) {

    var user = GlideUser.getUserByID(userID);

    return {

        accessibility: {

            key: 'glide.ui.accessibility',

            value: user.getPreference('glide.ui.accessibility') == 'true'

        }

    }

}

 

// read the proper state so we can show/hide preferences in the preferences table

function getPreferencesEnabled() {

    return {

        // show preferences only if the sys_id of the url is the same user that is logged on

        preferencesPanelEnabled: GlideStringUtil.nil($sp.getParameter('sys_id')) || $sp.getParameter('sys_id') == gs.getUserID(),

 

        //certain properties are visible in some cases

        languageEnabled: pm.isActive('com.glide.i18n') && gs.getProperty('glide.ui.language_picker.enabled', 'true') == 'true',

        timezoneEnabled: gs.hasRole(gs.getProperty('glide.timezone_changer.roles')),

        mfaEnabled: gs.getProperty('glide.authenticate.multifactor', "false") == "true"

    }

}

 

 

 

CSS:

.list-group-item {

  border: none;

 

  .btn-link {

      padding-left: 0;

    padding-right: 0;

  }

}

 

button{

  background-color:#145896;

  color:white;

}

 

.select2-container.select2-allowclear .select2-choice .select2-chosen {

  margin-right: 60px;

}

 

.mia i {

  font-size: 6rem;

}

 

.mia {

  color: #808080;

}

 

.popover {

  z-index: 1049;

}

 

h2.h2upr{

  font-family:"Open Sans";

  font-size:25px;

  color:#145896

}

h3.h3upr{

  font-family:"Open Sans";

  font-size:20px;

  color:#145896

}

h4.h4upr{

  font-family:"Open Sans";

  font-size:16px;

  color:#145896

}

span.span-accessibility{

  font-family:"Open Sans";

  font-size:16px;

  vertical-align: 10px ;/*super*/

  color:#145896

}

span.upr{

  font-family:"Open Sans";

  font-size:16px;

  color:#145896

}

 

span.ro-profile{

  font-family:"Open Sans";

  font-size:14px;

  color:#2A363B

}

 

// *Force* chrome default focus outline

.default-focus-outline {

    :focus {

        outline: thin dotted;

 

        // a css property that is often overwritten but we don't want it to be overwritten

        // for focus

        outline: 3px solid $input-border-tab-focus !important; /* IE */

        outline: 5px auto $input-border-tab-focus !important; /* Webkit */;

        outline-offset: -2px;

 

        @-moz-document url-prefix() {

            outline: 3px solid $input-border-tab-focus !important; /* FF */

        }

    }

}

 

// accessible accessibility toggle

@media screen and (-ms-high-contrast: active) {

  .input-switch input.ng-not-empty+label.switch[for="accessibility-enabled"] {

    background-color: highlight;

    border: none;

 

    &:before {

      background-color: highlightText;

    }

  }

 

  .input-switch input.ng-empty+label[for="accessibility-enabled"] {

    background-color: window;

    border: 1px solid windowText;

 

    &:before {

      background-color: windowText;

    }

  }

}

 

edit_profile

 

HTML

<div>

  <a href="{{data.profile_url}}" class="h4 text-primary m-b-sm block">

    <span class="ng-binding">Edit Profile</span>&nbsp;

    <i class="fa fa-edit"></i>

  </a>

</div>

 

CSS

a.h4 text-primary m-b-sm block{

  text-align:right;

 

}

span.ng-binding{

  color:#145896;

  font-family:"Open Sans";

  font-size:14px;

}

i.fa fa-edit{

  color:#145896;

  font-size:14px;

}

 

Server script:

 

(function() {

    /* populate the 'data' object */

    /* e.g., data.table = $sp.getValue('table'); */

    data.sysUserID = gs.getUser().getID();

    var sURL = '?id=form&amp;sys_id={{data.sysUserID}}&amp;table=sys_user';

    sURL='sp?id=new_user_profile&sys_id='+data.sysUserID+'&sysparm_editprofile=true';

    data.profile_url = sURL;

})();

 

 


Comments

  1. I recently came upon your blog and wanted to express how much I liked reading your postings. I'm hoping you'll write again soon. Thank you very much for the excellent information. Indonesia Import Data

    ReplyDelete

Post a Comment

Popular posts from this blog

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){

Service Catalog: variable advanced reference qualifiers

Call a script include to apply a reference qualifier on a catalog item variable: - variable reference qualifier dependent on another variable selection, in this case a variable referencing sys_user (requested_for) On the catalog item form. variable name to apply ref qual filter : retail_equipment variable reference qualifier (on cmdb table ): javascript : new  refqual_functions (). lostStolen_getAssignedCIs (); client-callable script include ( refqual_functions)  function : lostStolen_getAssignedCIs : function (){         //--called from variable set client script, for lost/stolen request (service catalog)     gs . log ( current . variables . requested_for , 'retail_lostStolen_getAssignedCIs' );         return ( 'install_statusNOT IN8,7^owned_by=' + current . variables . requested_for );             //owned_by=1269b79937f1060041c5616043990e41^install_statusNOT IN8,7            },

Get URL Parameter - server side script (portal or classic UI)

Classic UI : var sURL_editparam = gs . action . getGlideURI (). getMap (). get ( ' sysparm_aparameter ' ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); } Portal : var sURL_editparam = $sp . getParameter ( " sysparm_aparameter " ); if ( sURL_editparam == 'true' ) { gs . addInfoMessage ( 'parameter passed ); }