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.

Help displaying announcement name

Ryax1
Tera Guru

Hi,

I am trying to customise the OOB announcements widget so that I can display additional fields from the announcement table. OOB it displays the announcement title and summary by using ::a.summary however I have tried changing this to ::a.name (to display the announcement name) but nothing displays.

Please can you help how I can change the below OOB code to be able to display announcent name (or another field)?

<div ng-class="['panel', 'panel-{{::c.options.color}}', 'b', 'spw-announcements-root', '{{::c.wid}}', {'accessibility-off': c.accessibilityOff}]">
  <div class="panel-heading">
    <h3 class="h4 panel-title"><span ng-if="c.options.glyph"><fa name="{{::c.options.glyph}}"/></span>{{::c.options.title}}</h3>
  </div>
  <ul ng-if="::(c.totalAnnouncements > 0)" class="list-group" style="max-height: none; overflow-y: auto;">
    <li ng-class="['list-group-item', {'can-expand': a.canExpand, expanded: a.expanded}, cssId]" ng-repeat="a in c.announcements" ng-init="::(cssId = 'announcement-' + a.id + '-' + c.wid)">
      <style ng-if="::c.options.use_display_style" ng-init="::(ds = c.getDisplayStyle(a))">
        li.{{::cssId}} {
          background-color: {{::ds.backgroundColor}};
          text-align: {{::ds.alignment.toLowerCase()}};
        }
        
        li.{{::cssId}},
        li.{{::cssId}} .details div.title div,
        li.{{::cssId}} .details div.title a,
        li.{{::cssId}} .details a.info-link {
          color: {{::ds.foregroundColor}} !important;
        }
        
        li.{{::cssId}} .details p {
          font-weight: 100;
        }
        
        li.{{::cssId}}:hover .details div.title a,
        li.{{::cssId}} .details a.info-link {
          text-decoration: underline;
        }
      </style>
      <div class="details" ng-init="c.linkSetup(a)">
        
        <div ng-if="a.canExpand" class="title" ng-class="{'expanded': !a.expanded}" data-aid="{{::a.id}}" ng-click="c.toggleDetails(a)" tabindex="0" role="button" aria-expanded="{{a.expanded}}" ng-attr-aria-controls="{{a.canExpand ? c.wid+'-'+a.id+'-summary' : undefined}}">
          <div ng-if="a.linkType !== 'title'" ng-bind="::a.title" id="{{::c.wid}}-{{::a.id}}-title"></div>
        	<a ng-if="a.linkType === 'title'" ng-bind="::a.title" ng-href="{{::a.targetLink}}" target="{{::a.linkTarget}}" id="{{::c.wid}}-{{::a.id}}-title" tabindex="0"></a>
          <span ng-if="a.canExpand" class="glyphicon glyphicon-menu-down" aria-label="{{a.expanded ? '${Hide details}' : '${Show details}'}}"></span>
        </div>

        <div ng-if="!a.canExpand" class="title" data-aid="{{::a.id}}">
          <div ng-if="a.linkType !== 'title'" ng-bind="::a.title" id="{{::c.wid}}-{{::a.id}}-title"></div>
        	<a ng-if="a.linkType === 'title'" ng-bind="::a.title" ng-href="{{::a.targetLink}}" target="{{::a.linkTarget}}" id="{{::c.wid}}-{{::a.id}}-title" tabindex="0"></a>
        </div>

        <div ng-if="a.canExpand" id="{{::c.wid}}-{{::a.id}}-summary" aria-labelledby="{{::c.wid}}-{{::a.id}}-title" role="region">
          <p ng-if="::a.summary" ng-bind="::a.summary"></p>
          <a class="info-link" ng-if="a.linkType === 'normal'" ng-bind="::a.targetLinkText" ng-href="{{::a.targetLink}}" target="{{a.linkTarget}}" aria-label="{{a.targetLinkText}}" tabindex="{{a.expanded ? 0 : -1}}"></a>
        </div>
        
      </div>
    </li>
  </ul>
  <div ng-if="::(c.totalAnnouncements === 0)" class="empty-state-content panel-body">
    <p>${No information available}</p>
  </div>
  <div class="panel-footer" ng-if="c.totalPages > 1">
    <div ng-if="::c.options.paginate" class="btn-toolbar m-r pull-left">
      <div class="btn-group">
        <a ng-disabled="c.currentPage === 1" href="javascript:void(0)" ng-click="c.currentPage === 1 ? null : c.goToPage(c.currentPage - 1)" class="btn btn-default"  aria-label="${Previous page}" role="button"><i class="fa fa-chevron-left"></i></a>
      </div>
      <div ng-if="c.totalPages > 1 && c.totalPages < 3" class="btn-group">
        <a ng-repeat="i in c.getNumArray(c.totalPages) track by $index" ng-click="c.goToPage($index + 1)" href="javascript:void(0)" ng-class="{active: ($index + 1) === c.currentPage}" type="button" class="btn btn-default" aria-label="${Page} {{$index + 1}}" role="button">{{$index + 1}}</a>
      </div>
      <div class="btn-group">
        <a ng-disabled="c.currentPage === c.totalPages" href="javascript:void(0)" ng-click="c.currentPage === c.totalPages ? null : c.goToPage(c.currentPage + 1)" class="btn btn-default" aria-label="${Next page}" role="button"><i class="fa fa-chevron-right"></i></a>
      </div>
    </div>
    <div ng-if="::c.options.paginate" class="m-t-xs panel-title pull-left">{{c.getPageInfo()}}</div>
    <div ng-if="::(!c.options.paginate)" class="m-t-xs panel-title pull-left no-margin">${First {{::c.totalAnnouncements}} of {{::c.totalRecords}}}</div>
    <a ng-if="::(c.options.view_all_page && !c.isViewAllPage())" ng-class="['pull-right', {'push-margin': c.options.paginate}]" ng-href="?id={{::c.options.view_all_page}}" role="link">${View all}</a>
    <span class="clearfix"></span>
  </div>
</div>

Thanks

Richard

6 REPLIES 6

SVimes
Kilo Sage

Making the following change worked for me.

<!--OLD-->
<p ng-if="::a.summary" ng-bind="::a.summary"></p>

<!--NEW-->
<p ng-if="::a.name" ng-bind="::a.name"></p>
Sable Vimes - CSA

Thanks for your reply, this is the exact change I'd tried making but when I change it to '::a.name' nothing appears. Would you be able to provide your full code?

 

<p ng-if="::a.summary" ng-bind="::a.summary"></p>

Screenshot with above code:

 

<p ng-if="::a.name" ng-bind="::a.name"></p>

Screenshot with above code:

This is with the OOB widget and just that one line of code changed.

Rich

Absolutely! I cloned the OOB Announcements widget and made the change in the HTML section.

Body HTML Template

<div ng-class="['panel', 'panel-{{::c.options.color}}', 'b', 'spw-announcements-root', '{{::c.wid}}', {'accessibility-off': c.accessibilityOff}]">
  <div class="panel-heading">
    <h3 class="h4 panel-title"><span ng-if="c.options.glyph"><fa name="{{::c.options.glyph}}"/></span>{{::c.options.title}}</h3>
  </div>
  <ul ng-if="::(c.totalAnnouncements > 0)" class="list-group" style="max-height: none; overflow-y: auto;">
    <li ng-class="['list-group-item', {'can-expand': a.canExpand, expanded: a.expanded}, cssId]" ng-repeat="a in c.announcements" ng-init="::(cssId = 'announcement-' + a.id + '-' + c.wid)">
      <style ng-if="::c.options.use_display_style" ng-init="::(ds = c.getDisplayStyle(a))">
        li.{{::cssId}} {
          background-color: {{::ds.backgroundColor}};
          text-align: {{::ds.alignment.toLowerCase()}};
        }
        
        li.{{::cssId}},
        li.{{::cssId}} .details div.title div,
        li.{{::cssId}} .details div.title a,
        li.{{::cssId}} .details a.info-link {
          color: {{::ds.foregroundColor}} !important;
        }
        
        li.{{::cssId}} .details p {
          font-weight: 100;
        }
        
        li.{{::cssId}}:hover .details div.title a,
        li.{{::cssId}} .details a.info-link {
          text-decoration: underline;
        }
      </style>
      <div class="details" ng-init="c.linkSetup(a)">
        
        <div ng-if="a.canExpand" class="title" ng-class="{'expanded': !a.expanded}" data-aid="{{::a.id}}" ng-click="c.toggleDetails(a)" tabindex="0" role="button" aria-expanded="{{a.expanded}}" ng-attr-aria-controls="{{a.canExpand ? c.wid+'-'+a.id+'-summary' : undefined}}">
          <div ng-if="a.linkType !== 'title'" ng-bind="::a.title" id="{{::c.wid}}-{{::a.id}}-title"></div>
        	<a ng-if="a.linkType === 'title'" ng-bind="::a.title" ng-href="{{::a.targetLink}}" target="{{::a.linkTarget}}" id="{{::c.wid}}-{{::a.id}}-title" tabindex="0"></a>
          <span ng-if="a.canExpand" class="glyphicon glyphicon-menu-down" aria-label="{{a.expanded ? '${Hide details}' : '${Show details}'}}"></span>
        </div>

        <div ng-if="!a.canExpand" class="title" data-aid="{{::a.id}}">
          <div ng-if="a.linkType !== 'title'" ng-bind="::a.title" id="{{::c.wid}}-{{::a.id}}-title"></div>
        	<a ng-if="a.linkType === 'title'" ng-bind="::a.title" ng-href="{{::a.targetLink}}" target="{{::a.linkTarget}}" id="{{::c.wid}}-{{::a.id}}-title" tabindex="0"></a>
        </div>

        <div ng-if="a.canExpand" id="{{::c.wid}}-{{::a.id}}-summary" aria-labelledby="{{::c.wid}}-{{::a.id}}-title" role="region">
          <p ng-if="::a.name" ng-bind="::a.name"></p>
          <a class="info-link" ng-if="a.linkType === 'normal'" ng-bind="::a.targetLinkText" ng-href="{{::a.targetLink}}" target="{{a.linkTarget}}" aria-label="{{a.targetLinkText}}" tabindex="{{a.expanded ? 0 : -1}}"></a>
        </div>
        
      </div>
    </li>
  </ul>
  <div ng-if="::(c.totalAnnouncements === 0)" class="empty-state-content panel-body">
    <p>${No information available}</p>
  </div>
  <div class="panel-footer" ng-if="c.totalPages > 1">
    <div ng-if="::c.options.paginate" class="btn-toolbar m-r pull-left">
      <div class="btn-group">
        <a ng-disabled="c.currentPage === 1" href="javascript:void(0)" ng-click="c.currentPage === 1 ? null : c.goToPage(c.currentPage - 1)" class="btn btn-default"  aria-label="${Previous page}" role="button"><i class="fa fa-chevron-left"></i></a>
      </div>
      <div ng-if="c.totalPages > 1 && c.totalPages < 3" class="btn-group">
        <a ng-repeat="i in c.getNumArray(c.totalPages) track by $index" ng-click="c.goToPage($index + 1)" href="javascript:void(0)" ng-class="{active: ($index + 1) === c.currentPage}" type="button" class="btn btn-default" aria-label="${Page} {{$index + 1}}" role="button">{{$index + 1}}</a>
      </div>
      <div class="btn-group">
        <a ng-disabled="c.currentPage === c.totalPages" href="javascript:void(0)" ng-click="c.currentPage === c.totalPages ? null : c.goToPage(c.currentPage + 1)" class="btn btn-default" aria-label="${Next page}" role="button"><i class="fa fa-chevron-right"></i></a>
      </div>
    </div>
    <div ng-if="::c.options.paginate" class="m-t-xs panel-title pull-left">{{c.getPageInfo()}}</div>
    <div ng-if="::(!c.options.paginate)" class="m-t-xs panel-title pull-left no-margin">${First {{::c.totalAnnouncements}} of {{::c.totalRecords}}}</div>
    <a ng-if="::(c.options.view_all_page && !c.isViewAllPage())" ng-class="['pull-right', {'push-margin': c.options.paginate}]" ng-href="?id={{::c.options.view_all_page}}" role="link">${View all}</a>
    <span class="clearfix"></span>
  </div>
</div>

 

CSS

@mixin transition($transition...) {
  -webkit-transition: $transition;
  -moz-transition:    $transition;
  -o-transition:      $transition;
  transition:         $transition;
}

@mixin transform($transform...) {
  -webkit-transform: $transform;
  -moz-transform:    $transform;
  -o-transform:      $transform;
  transform:         $transform;
}

.spw-announcements-root {
  p {
    margin: 0;
  }

  li {
    display: flex;
    overflow: hidden;
  }

  h3.panel-title {
    span {
      margin-right: 2px;
    }
  }

  .details {
    width: 100%;
    div.title {
      display: flex;
      width: 100%;
      div, a {
        width: 100%;
        flex-grow: 1;
        color: $primary;
        overflow: hidden;
        @include transition(max-height 0.1s ease-out);
      }
      a {
        &:hover {
          color: #023363;
        }
      }
      &.expanded {
	      div, a {
	        display: block;
	        display: -webkit-box;
	        -webkit-box-orient: vertical;
	        overflow: hidden;
	        text-overflow: ellipsis;
	        -webkit-line-clamp: 2;
	      }
	  }
    }

    p {
     	max-height: 0;
      overflow: hidden;
      @include transition(max-height 0.1s ease-out);
    }

    a.info-link {
      display: none;
    }
  }

  .glyphicon {
    cursor: pointer;
    visibility: hidden;
    height: 14px;
    margin-left: 10px;
    @include transition(transform 0.10s ease-out);
  }

  .can-expand {
    .glyphicon {
      visibility: visible;
    }
  }

  li.expanded {
    max-height: 1500px;

    .glyphicon {
      @include transform(rotate(-180deg));
      @include transition(transform 0.10s ease-in);
    }

    .details {

      a.info-link {
        display: inline-block;
      }

      p {
        margin: 7.5px 0;
        max-height: 1000px;
        @include transition(max-height 0.50s ease-in);
      }

      div.title {
        div, a {
          max-height: 500px;
          @include transition(max-height 0.15s ease-in);
        }
      }
    }
  }

  .no-margin {
    margin-top: 0 !important;
  }

  .panel-footer {
    a {
      color: inherit;
    }

    a.push-margin {
      margin-top: 6px;
    }
  }
}

 

Server Script

(function() {
	options.title = gs.getMessage('{0}', options.title || 'Announcements');
	options.max_records = options.max_records ? options.max_records : 20;
	options.paginate = options.paginate === 'true' && options.max_records;
	options.use_display_style = options.use_display_style === 'true';
	data.rowsMessage = gs.getMessage('Rows {0} - {1} of {2}');

	if (options.view_all_page) {
		var gr = new GlideRecord('sp_page');
		gr.get(options.view_all_page);
		options.view_all_page = gr.getValue('id');
	}

	if (options.type) {
		var types = [];

		options.type.split(',').forEach(function(type) {
			var gr = new GlideRecord('announcement_consumer_type');
			gr.get(type);
			types.push(gr.getDisplayValue('name'));
		});

		options.type = types.join(',');
	}
})();

 

Client Controller

function($scope, $timeout, $location, spAnnouncement, spUtil, spAriaUtil) {
  var c = this;

	c.wid = 'spw-announcements-' + new Date().getTime();
	c.accessibilityOff = spAriaUtil.g_accessibility === 'false';
	c.announcements = [];
	c.totalAnnouncements = 0;

	c.toggleDetails = function(announcement) {
		announcement.expanded = !announcement.expanded;
	};

	c.isViewAllPage = function() {
		return $location.search().id === c.options.view_all_page;
	};

	c.getNumArray = function(number) {
		return new Array(number);
	};

	c.getPageInfo = function() {
		var limit = parseInt(c.options.max_records, 10);
		var offset = (c.currentPage - 1) * limit;
		var end = offset + limit;

		return spUtil.format(c.data.rowsMessage, {
			'0': offset + 1,
			'1': end < c.totalRecords ? end : c.totalRecords,
			'2': c.totalRecords
		});
	};

	c.goToPage = function(page, firstLoad) {
		var result = spAnnouncement.get(spAnnouncement.filterOnType(c.options.type), c.options.max_records, page);

		c.currentPage = page;
		c.totalPages = result.totalPages;
		c.totalRecords = result.totalRecords;

		c.announcements = result.data;
		c.totalAnnouncements = result.data.length;
		
		c.announcements.forEach(function(a) {
			a.canExpand = a.summary || a.targetLinkText;
			a.expanded = false;
		});

		$(document).ready(function() {
			if (!firstLoad)
				setFocus();
		});
	};

	c.linkSetup = function(a) {
    a.linkTarget = '_self';

    if ('urlNew' === a.clickTarget) {
      a.linkTarget = '_blank';
    }

    a.linkType = !a.targetLink ? 'none' : a.targetLinkText ? 'normal' : 'title';
  };
	
	c.getDisplayStyle = function(announcement) {
		return announcement.displayStyle || {
			backgroundColor: '#006ed5',
			foregroundColor: '#ffffff',
			alignment: 'LEFT'
		};
	};

	function setFocus() {
		var ul = $('.' + c.wid).find('ul');

		if (!ul.length) {
			$timeout(setFocus);
			return;
		}

		$timeout(function() {
			ul.first().focus();
		}, 20);
	}

	c.goToPage(1, true);
}
Sable Vimes - CSA

How strange, I've just cloned the OOB announcement widget, copied your exact code into it and the name doesn't show for me 😕

Rich