Screencast 8 – WebCenter Sites Document Library Gadget for WebCenter Content

Within a web experience, internal or external, it may make sense to expose highly interactive components that surface backend data. One way in which WebCenter Sites supports this capability is in the form of Gadgets. In our previous post, WebCenter Sites Gadget Development Concepts Quickstart, we took at look at some of the fundamentals of Gadget development.


View of the Gadget running in a dashboard in WebCenter Sites


Confirmation dialog after a user has clicked on the bell icon for a given content item to subscribe to updates

The foundation from our prior post can now be extended to illustrate how information from other systems, namely WebCenter Content, can easily be included within the WebCenter Sites via the Gadget paradigm. The screen shot above of the Gadget that we review in this episode illustrates how we ultimately expose a simple interface on top of WebCenter Content by way of its RESTful services.

WebCenter Sites Document Library Gadget for WebCenter Content Functions
Our sample Gadget will allow the following functionality to be exposed within WebCenter Sites

  • Display Folders and Content Items from WebCenter Content on the basis of our authenticated user
  • Allow a user to Subscribe / Unsubscribe to a Content Item from within the Gadget
  • Allow an administrator to set a start node for the document library
  • Allow an administrator to specify a server location for the WebCenter Content connection

Gadget Directory Structure & Code
For our sample we used a local Apache HTTP Server instance to host the Gadget. For development purposes we disabled browser security that checks for Cross Site Scripting attacks to allow us to mix host names for portions of the environment (without doing this some AJAX calls would not work). In order to get around this, simply launch your browser (in this case Chrome) using the command line and specifying arguments to disable the checking.

Running Google Chrome in Windows disabling some cross site scripting security


Directory structure for Gadget

doclib.xml

The doclib.xml file is what is registered within WebCenter Sites. It can contain all of the logic for the Gadget, but in our case we have isolated some of the code in an external file to make it more manageable.



  
    
    
    
    
  
  
    
    
  
  
  
  
    
    
  
  











    ]]>

    wc.doclib.js

    For our Gadget we have chosen to place most of the processing logic within the wc.doclib.js file to make it more manageable. The browseFolder function is the cornerstone of the Gadget and handles all of the content rendering within the Gadget by making RESTful calls into to WebCenter Content to retrieve folder and content item listings.

    function setItemSubscription(dIDValue, tokenValue, dDocTitleValue, collectionIDValue)
    {
      $.ucm.setSubscription(dIDValue, tokenValue, dDocTitleValue, function (ucmResponse) {
          $('#notification').html(' You have subscribed to '+dDocTitleValue);
          $('#notification').fadeIn('slow').slideDown('slow').delay(4000).fadeOut('slow');
          browseFolder(collectionIDValue);
         });
         return false;
    }
    
    function removeItemSubscription(dIDValue, tokenValue, dDocTitleValue, dDocNameValue, collectionIDValue)
    {
      $.ucm.removeSubscription(dIDValue, tokenValue, dDocTitleValue, dDocNameValue, function (ucmResponse) {
          $('#notification').html(' You have unsubscribed to '+dDocTitleValue);
          $('#notification').fadeIn('slow').delay(4000).fadeOut('slow');
          browseFolder(collectionIDValue);
         });
         return false;
    }
    
    function browseFolder(collectionID) {
    
         // Clear the current document display, folder description and back link
         $('#searchResults').html('');
         $('#folderDescription').html('');
         $('#backLink').html('');
    
         // Get subscription items before getting the item list for a given folder
         $.ucm.getSubscriptions(function (ucmResponse) {
    
            // Grab subscriptions for the current user and place into array
            var subscribeResults = ucmResponse.ResultSets.SUBSCRIPTION_LIST.rows;
            var subscribeArray = [];
    
            for (var rowIndex in subscribeResults) {
              subscribeArray.push(subscribeResults[rowIndex][3]);
            }
    
         $.ucm.collectionDisplay(collectionID, function (ucmResponse) {
              var sessionToken = ucmResponse.LocalData.idcToken;
    
              // Render the results on page
              var resultHtml = "";
              var searchResults = ucmResponse.ResultSets.COLLECTIONS.rows;
    
              for (var rowIndex in searchResults) {
                    // Build HTML for the folders
                    resultHtml += '
  • ' + searchResults[rowIndex][3] + '
  • '; } // Get the docs based on the collectionID var docResults = ucmResponse.ResultSets.CONTENTS.rows; for (var rowIndex in docResults) { // Check to see if the row has a description if (docResults[rowIndex][11] != "") { itemDescription = '
    ' + docResults[rowIndex][11] + '
    '; } else { itemDescription = ''; } // Check if the item is already subscribed to - rowIndex must be same as what is placed into subscription array var activeSubscription = $.inArray(docResults[rowIndex][53], subscribeArray); // Start the build of the content item list HTML resultHtml += "
  • "; // Item is not subscribed to if(activeSubscription == -1) { resultHtml += ''; } // Item is currently subscribed else { resultHtml += ' ' + docResults[rowIndex][54] + '' + itemDescription + '
  • '; } // Get the title for the folder that is currently being browsed breadCrumbs = '
  •  ' + ucmResponse.LocalData.collectionName + '
  • '; // Check to make sure that we are not at the root node and only show Previous Folder link if not if (ucmResponse.LocalData.dParentCollectionID == docLibRoot) { backLink = "
  • Previous Folder
  • "; } else { backLink = ''; } $('#folderDescription').html(ucmResponse.LocalData.xComments); $('#backLink').html(backLink); $("#breadCrumbs").html(breadCrumbs); $("#searchResults").html(resultHtml); // Resize the gadget as needed gadgets.window.adjustHeight(); }); return false; }); return false; }

    jquery.oracle-ucm.1.0.js (modified)

    The following lines have been added to the Oracle UCM JQuery plugin to add additional functionality required for our document library.

    ...
    
    		// Get folders for a given ID
    		collectionDisplay : function(collectionID, callback) {
    			var collectionData = {
    				IdcService: "COLLECTION_DISPLAY",
    				hasCollectionID : "1",
    				dCollectionID : collectionID,
    				IsJson : "1"
    			}
    			$.ucm.executeService(collectionData, callback);
    		},
    
    		// Get subscriptions for the logged in user
    		getSubscriptions : function(callback) {
    			var collectionData = {
    				IdcService: "SUBSCRIPTION_LIST",
    				IsJson : "1"
    			}
    			$.ucm.executeService(collectionData, callback);
    		},
    
    		// Subscribe to a content item
    		setSubscription : function(dIDValue, tokenValue, dDocTitleValue, callback) {
    			var collectionData = {
    				IdcService: "SUBSCRIBE",
    				dID: dIDValue,
    				idcToken : tokenValue,
    				dDocTitle: dDocTitleValue,
    				dSubscriptionEmail : '',
    				dSubscriptionType: 'Basic',
    				unsubscribeService: 'UNSUBSCRIBE',
    				subscribeService: 'SUBSCRIBE'
    			}
    			$.ucm.executeService(collectionData, callback);
    		},
    
    		// Unsubscribe to a content item
    		removeSubscription : function(dIDValue, tokenValue, dDocTitleValue, dDocNameValue, callback) {
    			var collectionData = {
    				IdcService: "UNSUBSCRIBE",
    				dID: dIDValue,
    				idcToken : tokenValue,
    				dDocTitle: dDocTitleValue,
    				dSubscriptionID : dDocNameValue,
    				dSubscriptionEmail : '',
    				dSubscriptionType: 'Basic',
    				unsubscribeService: 'UNSUBSCRIBE',
    				subscribeService: 'SUBSCRIBE'
    			}
    			$.ucm.executeService(collectionData, callback);
    		},
    
    ...
    

    style.css

    The following plain old CSS styles the contents within our Gadget.

    a:visited, a.folder:visited
    {
    	color: #0000FF;
    }
    
    #docLib
    {
    	font-size: .8em;
    }
    
    ul
    {
         list-style-type: none;
    	margin-left: -40px;
    }
    
    ul a
    {
    	text-decoration: none;
    }
    
    ul#breadCrumbs li
    {
    	float: left;
    	margin-bottom: 20px;
    	font-weight: bold;
    	font-size: 1.2em;
    }
    
    ul#breadCrumbs li img
    {
    	vertical-align: middle;
    	margin-top: -3px;
    }
    
    ul#searchResults
    {
    	clear: both;
    	margin-top: 30px;
    }
    
    ul#searchResults li
    {
    	margin-bottom: 5px;
    	margin-left: 20px;
    	border-top: 1px dotted #ddd;
    	padding-top: 5px;
    }
    
    ul#searchResults li:first-child
    {
    	border-top: none;
    }
    
    div.itemdesc
    {
    	padding-left: 20px;
    	margin-right: 30px;
    }
    
    a.backlink
    {
    	padding-left: 20px;
    	margin-top: 12px;
    	margin-bottom: 12px;
    	float: left;
    }
    
    a.backlink img
    {
    	vertical-align: middle;
    	margin-top: -3px;
    }
    
    a.folder
    {
    	background: url(http://localhost/gadget/img/blue-folder-horizontal.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.pdf
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-pdf.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.doc
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-word.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.txt
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.ppt
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-powerpoint.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.mp3
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-music.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.mp4, a.mov, a.mpg, a.mpeg, a.avi, a.divx, a.wmv, a.flv
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-film.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.jpg, a.gif, a.png, a.jpeg
    {
    	background: url(http://localhost/gadget/img/doctypes/blue-document-image.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.html, a.htm, a.css, a.js
    {
    	background: url(http://localhost/gadget/img/doctypes/document-globe.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.zip, a.rar, a.7z
    {
    	background: url(http://localhost/gadget/img/doctypes/document-zipper.png) no-repeat;
    	padding-left: 20px;
    }
    
    a.subscribeicon
    {
    	float: right;
    }
    
    #folderDescription
    {
    	clear: both;
    }
    
    div#notification img
    {
    	vertical-align: middle;
    	margin-top: -3px;
    }
    
    #notification
    {
    	display: none;
        padding: 10px;
        text-align: center;
        margin-bottom: -15px;
        margin-top: 10px;
        border-radius: 5px;
        box-shadow:
            0 1px 1px rgba(0,0,0,0.1),
            inset 0 1px 0 rgba(255,255,255,0.6);
        cursor: default;
    	border: 1px solid #69C0CA;
    	color: #3D8D98;
    	background-color: #8ACED6;
    	background-image: -webkit-gradient(linear,50% 0%,50% 100%,color-stop(0%,#99E2EB),color-stop(100%,#79C6CD));
    	background-image: -webkit-linear-gradient(#99E2EB,#79C6CD);
    	background-image: -moz-linear-gradient(#99E2EB,#79C6CD);
    	background-image: -o-linear-gradient(#99E2EB,#79C6CD);
    	background-image: linear-gradient(#99E2EB,#79C6CD);
    	-moz-text-shadow: 0px 1px rgba(255,255,255,0.2);
    	text-shadow: 0px 1px rgba(255, 255, 255, 0.2);
    }
    

    Special Thanks to Third Party Components

    • Icons – The excellent set of icons used within the Gadget have been designed by Yusuke Kamiyamane
    • JQuery UCM Plugin – A great piece of work supplied by Bex Huff

    Gadget Code Download
    Download a copy of the WebCenter Sites Document Library Gadget for WebCenter Content

    2 Comments
    • leandrolb
      Reply
      October 8, 2015

      awesome!

    Leave a comment