Modal window in Portal widget

Dhushanth1
Giga Contributor

Hello, I have a requirement to display modal window along with catalog Name and Description whenever user clicks View Details in Recent & Popular items widget. I have created a modal window with static title and body. Can anyone  guide me to pass Catalog name in title and description in modal window body.

 

Thanks,

4 REPLIES 4

Community Alums
Not applicable

Can you please post your current code? There are a couple of different ways to instantiate modals.

You should have access to the 'data' object in the widget. Depending on which widget you are calling the modal from, and what is already available in the 'data' object, you should be able to just reference those values in the modal instantiation. 

Thanks for your response @timmo Below is my current code:

HTML:

<div class="recent-widget" ng-if="!c.hideWidget">
  <div class="panel panel-default">
    <div class="panel-heading pad-bottom">
        <ul class="nav nav-tabs" style="border-bottom : 0px" role="tablist">
          <li class="item" id="tab-popular-items" ng-if="data.popularItems.length > 0" ng-keydown="c.switchTab($event, 'popular')" ng-click="c.changePanel('popular')" role="presentation">
            <a ng-class="{'sc-tab-a' : !c.show_recent}" href="#tab-popular-items" class="popular" ng-attr-tabindex="{{c.show_recent ? '-1': undefined}}" ng-attr-aria-controls="{{!c.show_recent ? 'tabpanel-popular-items' : undefined}}" aria-selected="{{!c.show_recent}}" role="tab">
              <span > ${Popular Items} </span>
            </a>
          </li>  
          <li class="item" id="tab-recent-items" ng-if="data.recentItems.length > 0" ng-click="c.changePanel('recent')" ng-keydown="c.switchTab($event, 'recent')" role="presentation">
            <a ng-class="{'sc-tab-a' : c.show_recent}" href="#tab-recent-items" class="recent" ng-attr-tabindex="{{!c.show_recent ? '-1': undefined}}" ng-attr-aria-controls="{{c.show_recent ? 'tabpanel-recent-items' : undefined}}" aria-selected="{{c.show_recent}}" role="tab">
              <span> ${My Recent Items} </span>
            </a>
          </li>  
        </ul>
    </div>
 <div id="tabpanel-popular-items" class="table table-striped item-table" ng-if="!c.show_recent" role="tabpanel" aria-labelledby="tab-popular-items">
   <span class="sr-only" role="heading" aria-level="2"> ${Popular Items} </span>
   <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-popular-items">
     <li class="item-card-column" ng-repeat="item in data.popularItems | orderBy: 'order' | limitTo: data.limit track by item.sys_id" role="listitem">
       <div class="panel-default item-card b">
         <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=popular_items" class="panel-body block height-100" onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Popular Item", "Item Clicked");' 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}}" id="sc_cat_item_{{::item.sys_id}}">{{::item.name}}</h3>
             <img ng-src="{{::item.picture}}" ng-if="::item.picture" class="m-r-sm m-b-sm item-image pull-left" alt="" 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 href = "" class="pull-left text-muted" aria-label="${View Details}" ng-click="c.openModal()">${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 id="tabpanel-recent-items" class="panels-container" ng-if="c.show_recent" role="tabpanel" aria-labelledby="tab-recent-items">
    <span class="sr-only" role="heading" aria-level="2"> ${My Recent Items} </span>
   <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-recent-items">
     <li class="item-card-column" ng-repeat="item in data.recentItems track by item.sys_id" role="listitem">
       <div class="panel-default item-card b">
         <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=recent_items" class="panel-body block height-100" onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");' 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}}" id="sc_cat_item_{{::item.sys_id}}">{{::item.name}}</h3>
             <img ng-src="{{::item.picture}}" ng-if="::item.picture" class="m-r-sm m-b-sm item-image pull-left" alt="" 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 href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=recent_items" class="pull-left text-muted" aria-label="${View Details} {{::item.name}}" onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");'>${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>
      <script type="text/ng-template" id="modalTemplate">
       <div class="panel panel-default">
 <div class="panel-heading">
 <h4 class="panel-title">{{::c.data.name}}</h4>
   </div>
 <div class="panel-body wrapper-xl">{{::c.data.description}}></div>
 
   
 <div class="panel-footer text-right">
 <button class="btn btn-primary" ng-click="c.closeModal()">Close Modal</button>
 </div>
 </div>
</script>
  </div>

 

Server Script:

 

(function() {
    /* populate the 'data' object */
    data.limit = options.limit || 8;
    
    var recent_by = options.recent_by || 'view';
    var recent = new GlideRecord('sp_log');
    if (recent_by === 'view')
        recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item View^sys_created_onONThis quarter@javascript:gs.beginningOfThisQuarter()@javascript:gs.endOfThisQuarter()');
    else
        recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item Request^sys_created_onONThis quarter@javascript:gs.beginningOfThisQuarter()@javascript:gs.endOfThisQuarter()');
    recent.orderByDesc('sys_created_on');
    recent.query();
    var recentItems = [];
    var catalogArr = ($sp.getCatalogs().value + "").split(",");
    data.showPrices = $sp.showCatalogPrices();

    while (recent.next() && recentItems.length < data.limit) {
        if (isAlreadyAdded(recent.getValue('id')))
            continue;
        var catalogItemJS = new sn_sc.CatItem(recent.getValue('id'));
        if (!catalogItemJS.canView(gs.isMobile()) || !catalogItemJS.isVisibleServicePortal())
            continue;
        var item = {};
        var catItemDetails = catalogItemJS.getItemSummary(true);
        if (!catItemDetails.visible_standalone)
            continue;
        var inCatalog = false;
        for (var i = 0; i < catItemDetails.catalogs.length; i++) {
            if (catalogArr.indexOf(catItemDetails.catalogs[i].sys_id + "") >= 0) {
                inCatalog = true;
                break;
            }
        }
        if (inCatalog) {
            item.name = catItemDetails.name;
            item.short_description = catItemDetails.short_description;
            item.description = catItemDetails.description;
            item.u_preview_ = catItemDetails.u_preview_details;
            item.picture = catItemDetails.picture;
            item.price = catItemDetails.price;
            item.sys_id = catItemDetails.sys_id;
            item.category = catItemDetails.category;
            item.hasPrice = item.price != 0;
            item.page = catItemDetails.type == 'order_guide' ? 'sc_cat_item_guide' : 'sc_cat_item';
            recentItems.push(item);
        }
    }
    data.name = item.name;
    data.description = item.description;

    function isAlreadyAdded(catItemSysId) {
        for (var i = 0; i < recentItems.length; i++) {
            if (catItemSysId == recentItems[i].sys_id)
                return true;
        }
        return false;
    }

    data.recentItems = recentItems;
    data.popularItems = getPopularItems();

    function getPopularItems() {
        return new SCPopularItems().useOptimisedQuery(gs.getProperty('glide.sc.portal.popular_items.optimize', true) + '' == 'true')
            .baseQuery(options.popular_items_created + '')
            .allowedItems($sp.getAllowedItems())
            .visibleStandalone(true)
            .visibleServicePortal(true)
            .itemsLimit(options.limit || 😎
            .restrictedItemTypes(['sc_cat_item_guide', 'sc_cat_item_wizard', 'sc_cat_item_content', 'sc_cat_item_producer'])
            .itemValidator(function(item, itemDetails) {
                if (!item.canView(gs.isMobile()) || !item.isVisibleServicePortal())
                    return false;

                return true;
            })
            .responseObjectFormatter(function(item, itemType, itemCount) {
                return {
                    order: 0 - itemCount,
                    name: item.name,
                    short_description: item.short_description,
                    description: item.description,
                    preview: item.u_preview_details,
                    picture: item.picture,
                    price: item.price,
                    sys_id: item.sys_id,
                    category: item.category,
                    hasPrice: item.price != 0,
                    page: itemType == 'sc_cat_item_guide' ? 'sc_cat_item_guide' : 'sc_cat_item'
                };
            })
            .generate();
    }
   

   
})();

 

Client Controller:

 

function($uibModal, $scope) {
  /* widget controller */
  var c = this;
    
    
    c.show_recent = false;
    
    c.KEYS = {
                        DOWN:40,
                        LEFT:37,
                        RIGHT:39,
                        TAB:9,
                        UP:38
                     }
    
    //if (c.data.recentItems.length > 0)
        //c.show_recent = true;
    c.changePanel = function(panel_name) {
        if (c.show_recent) {
            if (panel_name == 'popular')
                c.show_recent = false;
        } else {
            if (panel_name == 'recent')
                c.show_recent = true;
        }
    };
    
    c.switchTab = function($event, tab) {
        var key = null;
        if (event.keyCode === c.KEYS.LEFT || event.keyCode === c.KEYS.UP)
            key = c.KEYS.LEFT;
        else if (event.keyCode === c.KEYS.RIGHT || event.keyCode === c.KEYS.DOWN)
            key = c.KEYS.RIGHT;
        else if (event.keyCode === c.KEYS.TAB) {
            return;
        }
        if (key === null)
            return;
        c.show_recent = !c.show_recent;
        if (c.show_recent)
            $('a.recent').focus();
        else
            $('a.popular').focus();
    }
    api.controller=function($scope) {
    /* widget controller */
    var c = this;

    $scope.toolTip2=$scope.greeting;
};

    c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0);
    
 c.openModal = function() {
    
 c.modalInstance = $uibModal.open({
 templateUrl: 'modalTemplate',
 scope: $scope
     
 });
 }

 
 c.closeModal = function() {
 c.modalInstance.close();
 }
 

}


  

Community Alums
Not applicable

So, looks like you're using $uibModal, and passing a template, and $scope.

In the template, you can access the 'data' object:

{c.data.name}
{c.data.description}

Thanks @timmo Now I can pass the values to Modal window. But its only showing only one item title and description. How to make it as dynamic.

 

Thanks,