ウィジェットSC Category Pagesの編集方法

ServiceNow Japan Communityの質問
[ウィジェットSC Category Pagesの編集方法について教えてください。
](https://community.servicenow.com/community?id=community_question&sys_id=a1a0b3bddb82fc90fa192183ca96190b)について、回答を作成したものの、なぜかRepryボタンが消えているため、コミュニティにて回答ができない。もし、Koheiさんがこの記事を見ていればいいのだが...という供養的な記事。
（というか、ServiceNow MVPの方の回答が見当違いでわら...）

### 元記事(QA)転載
Service Portal DesignerからウィジェットSC Category PagesのGrid Vewにした場合に表示される
Item/Description/PriceのフィールドのうちPriceの削除したいのですが方法がわかりません。
初心者なのでご存じの方いましたらお知恵をお貸しください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/a333b357-70cd-9cff-b57e-daf9373d98cd.png)

### 現象の再現手順
まずは問題のスクリーンショットにたどり着くための導線...
1.platformのナビゲーションでService Portal > Service Portal HomeでPortalを開く
2.Portal右上のCatalogを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/cd6e405e-9ddf-59ef-d999-4febc081ecbb.png)
3.検索バー下のBrowse by Categoriesを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/16e7cfcd-9fb8-6150-6c45-22476e369f35.png)
4.CategoryのHardwareを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/3a2bfcf6-48c4-19ec-1866-3c38474cb972.png)
5.ListileをCard View　-> List Viewに変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/b4917638-0de6-979a-3f58-fa1028eba33c.png)
6.CatalogのListViewでHardwareのItem/description/priceが表示される(QA時点再現)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/b22fea25-dc27-05b0-5d8a-98f47f784d03.png)


### 現象の解決(priceを消したい)
1.使用Widgetを特定し、表示する
パーツをCtrl + 右クリックで表示リストの「Widget in Editor」を押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/214f45ee-6646-8a70-f769-3cd59ec977b0.png)
2.使用Widget(今回はSC Category Page)のソースが表示される。なので、これをクローンしてからソースを改変する。(Clone "SC Category Page"をクリック)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/98b4238d-2ff1-bcbc-2ab6-fab56ac1527f.png)
2.2 名前をつける。私はClone SC Category Pageと命名。適当につけてOK
2.3 左上のプルダウンでクローンしたWidgetを選択(Clone SC Category Page)して表示変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/05077ec0-1f45-fcda-b6ac-810fefd3c628.png)
3.クローンのHTMLを変更する
下記にHTMLのソースを表示

```HTML:CloneSCCategoryPage.HTML
<div class="m-t-sm " ng-class="{'hidden-xs' : hideItemWidget, 'm-l-sm': !isMobile}">
  <h4 ng-if="data.error">{{data.error}}</h4>
  <div ng-init="spSearch.targetCatalog()">
    <div class="row">
      <div class="col-xs-9">
        	<a ng-click="showCategories()" class="visible-xs m-b-sm pointer" aria-label="${All Categories}" role="button" tabindex="0" id="all-categories-link">
            <i class="fa fa-chevron-left m-r-xs"></i> ${All Categories}
        	</a>
          <h2 class="h4 m-t-none break-word">{{data.category.title}}</h2>
        	<p class="hidden-xs break-word">
            {{data.category.description}}
          </p>
      </div>
      <div class="col-xs-3" ng-if="!isMobile">
        <div role="tablist" class="pull-right padder-t-sm text-lg toggle" ng-show="!data.error && data.items.length > 0">
          <i id="tab-card" 
             role="tab"
             class="fa fa-th tab-card-padding" ng-click="changeView('card')" 
             ng-keydown="switchTab($event)" aria-label="${Card View}" 
             ng-class="{'active' : view == 'card'}"
             title="${Card View}"
             data-toggle="{{!isTouchDevice() ? 'tooltip' : undefined}}"
 	         data-placement="top"
             data-container="body"
             aria-selected="{{view == 'card'}}" 
             aria-label="${Card View}"
             ng-attr-aria-controls="{{view == 'card' ? 'tabpanel-card-' + (data.category_id ? data.category_id : '') : undefined}}" 
             tabindex="{{view == 'card' ? '0' : '-1'}}"></i>
          <span class="m-l-sm m-r-sm " aria-hidden="true"> | </span>
          <i id="tab-grid" 
             role="tab"
             class="fa fa-list-ul tab-card-padding" 
             ng-click="changeView('grid')" 
             ng-keydown="switchTab($event)" 
             ng-class="{'active' : view == 'grid'}"
             title="${Table View}"
             data-toggle="{{!isTouchDevice() ? 'tooltip' : undefined}}"
 	           data-placement="top"
             data-container="body"
             aria-selected="{{view == 'grid'}}"
             aria-label="${Table View}" 
             ng-attr-aria-controls="{{view == 'grid' ? 'tabpanel-grid-' + (data.category_id ? data.category_id : '') : undefined}}" 
             tabindex="{{view == 'grid' ? '0' : '-1'}}"></i>
        </div>
       </div>
    </div>
    <div class="row">
    	<div class="text-a-c" ng-if="showTopLoader">
      		<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
			<span class="sr-only">${Loading...}</span>
    	</div>
      <div class="col-sm-6 col-md-4" ng-if="!showTopLoader && !data.items.length && !data.error">
        ${No items in category}
      </div>
      <div id="tabpanel-grid-{{::data.category_id}}" role="tabpanel" aria-labelledby="{{'tab-grid'}}" ng-if="view == 'grid' && data.items.length > 0">
        <table class="table table-striped item-table" aria-label="{{::data.category.title}}" aria-describedby="id-caption-category">
        	<caption id="id-caption-category"><span class="sr-only">{{::data.category.title}}</span></caption>
          <thead>
            <tr>
              <th id="id-header-item" scope="col">${Item}</th>
              <th id="id-header-description" scope="col">${Description}</th>
            	  <th id="id-header-price" scope="col" ng-if="data.showPrices">${Price}</th>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="item in data.items | orderBy: 'order' | limitTo: data.limit track by item.sys_id" ng-init="startItemList()">
              <th id="id-item-{{item.sys_id}}" headers="id-header-item" scope="row" class="th-row-data">
                <a sn-focus="{{::item.highlight}}" href="javascript:void(0);" ng-click="onClick($event, item)"> 
                	<div>
                    <img ng-src="{{::item.picture}}?t=small" ng-if="item.picture" alt="" class="m-r-sm m-b-sm item-image pull-left"/>
                    <span class="catalog-text-wrap">{{::item.name}}</span>
                    <span ng-if="item.content_type == 'external'"><span class="sr-only">${External Link}</span> ➚</span>
                  </div>
                </a>
            	  </th>
            	  <td headers="id-header-description id-item-{{item.sys_id}}" class="catalog-text-wrap">{{::item.short_description}}</td>
            	  <td headers="id-header-price id-item-{{item.sys_id}}" ng-if="data.showPrices">{{::item.price}}</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div id="tabpanel-card-{{::data.category_id}}" ng-if="view == 'card' && data.items.length > 0" role="tabpanel" aria-labelledby="{{'tab-card'}}">
      	<ul class="item-list-style-type-none item-card-row" role="list" aria-label="{{data.category.title}} ${items}">
      		<li class="item-card-column" ng-repeat="item in data.items | orderBy: 'order' | limitTo: data.limit track by item.sys_id" ng-init="startItemList()" role="listitem">
            <div class="panel-{{::options.color}} item-card b">
              <a href="javascript:void(0);" ng-click="onClick($event, item)" class="panel-body block height-100" sn-focus="{{::item.highlight}}" aria-labelledby="sc_cat_item_{{::item.sys_id}}" aria-describedby="sc_cat_item_short_desc_{{::item.sys_id}}">
                <div>
                  <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis" title="{{::item.name}}" style="padding-bottom:1px" id="sc_cat_item_{{::item.sys_id}}">{{::item.name}}<span ng-if="item.content_type == 'external'"><span class="sr-only">${External Link}</span> ➚</span></h3>
                  <img ng-src="{{::item.picture}}?t=small" ng-if="item.picture" alt="" class="m-r-sm m-b-sm item-image pull-left" aria-hidden="true"/>
                  <div class="text-muted item-short-desc catalog-text-wrap" id="sc_cat_item_short_desc_{{::item.sys_id}}">{{::item.short_description}}</div>
                </div>
              </a>
            </div>
            <div class="panel-footer b">
              <a aria-label="${View Details} {{::item.name}}" href="javascript:void(0);" ng-click="onClick($event, item)" class="pull-left text-muted">${View Details}</a>
              <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span> &nbsp;
            </div>
      		</li>
      	</ul>  
      </div>
    </div>
    <div class="text-a-c" ng-if="!stopLoader && data.items.length > 0 && !data.error">
      <i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
			<span class="sr-only">${Loading...}</span>
    </div>
    <div ng-if="data.show_more && !show_popular_item">
      	<div class="text-a-c">
          {{data.more_msg}}
      	</div>
        <button class="m-t-xs btn btn-default btn-loadmore" ng-click="loadMore()">
          ${Show More Items}
        </button>
      </div>
  </div>
</div>
<now-message key="Catalogs" value="${Catalogs}"/>
```

上記ソースのうち、priceのListHeaderとListContentの生成部分が三箇所あるので、そこをコメントアウトする

```HTML:CloneSCCategoryPage.HTML
<div class="m-t-sm " ng-class="{'hidden-xs' : hideItemWidget, 'm-l-sm': !isMobile}">
  <h4 ng-if="data.error">{{data.error}}</h4>
  <div ng-init="spSearch.targetCatalog()">
    <div class="row">
      <div class="col-xs-9">
        	<a ng-click="showCategories()" class="visible-xs m-b-sm pointer" aria-label="${All Categories}" role="button" tabindex="0" id="all-categories-link">
            <i class="fa fa-chevron-left m-r-xs"></i> ${All Categories}
        	</a>
          <h2 class="h4 m-t-none break-word">{{data.category.title}}</h2>
        	<p class="hidden-xs break-word">
            {{data.category.description}}
          </p>
      </div>
      <div class="col-xs-3" ng-if="!isMobile">
        <div role="tablist" class="pull-right padder-t-sm text-lg toggle" ng-show="!data.error && data.items.length > 0">
          <i id="tab-card" 
             role="tab"
             class="fa fa-th tab-card-padding" ng-click="changeView('card')" 
             ng-keydown="switchTab($event)" aria-label="${Card View}" 
             ng-class="{'active' : view == 'card'}"
             title="${Card View}"
             data-toggle="{{!isTouchDevice() ? 'tooltip' : undefined}}"
 	         data-placement="top"
             data-container="body"
             aria-selected="{{view == 'card'}}" 
             aria-label="${Card View}"
             ng-attr-aria-controls="{{view == 'card' ? 'tabpanel-card-' + (data.category_id ? data.category_id : '') : undefined}}" 
             tabindex="{{view == 'card' ? '0' : '-1'}}"></i>
          <span class="m-l-sm m-r-sm " aria-hidden="true"> | </span>
          <i id="tab-grid" 
             role="tab"
             class="fa fa-list-ul tab-card-padding" 
             ng-click="changeView('grid')" 
             ng-keydown="switchTab($event)" 
             ng-class="{'active' : view == 'grid'}"
             title="${Table View}"
             data-toggle="{{!isTouchDevice() ? 'tooltip' : undefined}}"
 	           data-placement="top"
             data-container="body"
             aria-selected="{{view == 'grid'}}"
             aria-label="${Table View}" 
             ng-attr-aria-controls="{{view == 'grid' ? 'tabpanel-grid-' + (data.category_id ? data.category_id : '') : undefined}}" 
             tabindex="{{view == 'grid' ? '0' : '-1'}}"></i>
        </div>
       </div>
    </div>
    <div class="row">
    	<div class="text-a-c" ng-if="showTopLoader">
      		<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
			<span class="sr-only">${Loading...}</span>
    	</div>
      <div class="col-sm-6 col-md-4" ng-if="!showTopLoader && !data.items.length && !data.error">
        ${No items in category}
      </div>
      <div id="tabpanel-grid-{{::data.category_id}}" role="tabpanel" aria-labelledby="{{'tab-grid'}}" ng-if="view == 'grid' && data.items.length > 0">
        <table class="table table-striped item-table" aria-label="{{::data.category.title}}" aria-describedby="id-caption-category">
        	<caption id="id-caption-category"><span class="sr-only">{{::data.category.title}}</span></caption>
          <thead>
            <tr>
              <th id="id-header-item" scope="col">${Item}</th>
              <th id="id-header-description" scope="col">${Description}</th>
            	 <!--<th id="id-header-price" scope="col" ng-if="data.showPrices">${Price}</th> -->
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="item in data.items | orderBy: 'order' | limitTo: data.limit track by item.sys_id" ng-init="startItemList()">
              <th id="id-item-{{item.sys_id}}" headers="id-header-item" scope="row" class="th-row-data">
                <a sn-focus="{{::item.highlight}}" href="javascript:void(0);" ng-click="onClick($event, item)"> 
                	<div>
                    <img ng-src="{{::item.picture}}?t=small" ng-if="item.picture" alt="" class="m-r-sm m-b-sm item-image pull-left"/>
                    <span class="catalog-text-wrap">{{::item.name}}</span>
                    <span ng-if="item.content_type == 'external'"><span class="sr-only">${External Link}</span> ➚</span>
                  </div>
                </a>
            	  </th>
            	  <td headers="id-header-description id-item-{{item.sys_id}}" class="catalog-text-wrap">{{::item.short_description}}</td>
            	  <!--<td headers="id-header-price id-item-{{item.sys_id}}" ng-if="data.showPrices">{{::item.price}}</td> -->
            </tr>
          </tbody>
        </table>
      </div>
      <div id="tabpanel-card-{{::data.category_id}}" ng-if="view == 'card' && data.items.length > 0" role="tabpanel" aria-labelledby="{{'tab-card'}}">
      	<ul class="item-list-style-type-none item-card-row" role="list" aria-label="{{data.category.title}} ${items}">
      		<li class="item-card-column" ng-repeat="item in data.items | orderBy: 'order' | limitTo: data.limit track by item.sys_id" ng-init="startItemList()" role="listitem">
            <div class="panel-{{::options.color}} item-card b">
              <a href="javascript:void(0);" ng-click="onClick($event, item)" class="panel-body block height-100" sn-focus="{{::item.highlight}}" aria-labelledby="sc_cat_item_{{::item.sys_id}}" aria-describedby="sc_cat_item_short_desc_{{::item.sys_id}}">
                <div>
                  <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis" title="{{::item.name}}" style="padding-bottom:1px" id="sc_cat_item_{{::item.sys_id}}">{{::item.name}}<span ng-if="item.content_type == 'external'"><span class="sr-only">${External Link}</span> ➚</span></h3>
                  <img ng-src="{{::item.picture}}?t=small" ng-if="item.picture" alt="" class="m-r-sm m-b-sm item-image pull-left" aria-hidden="true"/>
                  <div class="text-muted item-short-desc catalog-text-wrap" id="sc_cat_item_short_desc_{{::item.sys_id}}">{{::item.short_description}}</div>
                </div>
              </a>
            </div>
            <!--
            <div class="panel-footer b">
              <a aria-label="${View Details} {{::item.name}}" href="javascript:void(0);" ng-click="onClick($event, item)" class="pull-left text-muted">${View Details}</a>
              <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span> &nbsp;
            </div>
        		-->
      		</li>
      	</ul>  
      </div>
    </div>
    <div class="text-a-c" ng-if="!stopLoader && data.items.length > 0 && !data.error">
      <i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
			<span class="sr-only">${Loading...}</span>
    </div>
    <div ng-if="data.show_more && !show_popular_item">
      	<div class="text-a-c">
          {{data.more_msg}}
      	</div>
        <button class="m-t-xs btn btn-default btn-loadmore" ng-click="loadMore()">
          ${Show More Items}
        </button>
      </div>
  </div>
</div>
<now-message key="Catalogs" value="${Catalogs}"/>
```

変更後は忘れずSaveする

4.変更Widgetを現状Widgetと差し替える
Portalを　Ctrl+右クリックでPage in Designerを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/e6aa984f-ff61-954c-4f0e-12d2f0c1cf75.png)

4.2 Widgetをfilterして見つける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/970c29d5-e49f-083f-93fa-3eb1297f6ef2.png)
4.3 Widgetをドラッグ&ドロップで挿入する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/8bfbc751-5f38-7cdf-9c2c-0c14cb791f6c.png)

4.4 前のSC Category Pageをゴミ箱で削除する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/9c263a38-c50b-0942-c7f7-8c62209abc92.png)

5.画面を確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/54c3c1c4-fbbd-9973-a29b-bce8ef4a37ae.png)

priceが削除されている！

#### Appendix Descriptionカラムを右側において2Grid表示にしたい
上記のHTMLの部分をいくつかいじれば修正可能なはずです。未検証ですが、表示部分はWidgetのHTMLです。

上記、参考になれば幸いです。