Sunday, September 22, 2013

How to use SOAP to integrate SharePoint 2010 list data with jVectorMap

jVectorMap Series 
How to Build a Simple jVectorMap Display
How to integrate data with jVectorMap
How to customize jVectorMap region popups
How to add user interactivity to jVectorMap
How to add a popup modal to jVectorMap using Bootstrap
How to integrate jVectorMap with SharePoint 2010
How to use REST to integrate SharePoint 2010 list data with jVectorMap
How to use SOAP to integrate SharePoint 2010 list data with jVectorMap
Introduction

In the previous posting in this series, we explored how to use REST to integrate SharePoint 2010 list data with jVectorMap.  In this posting, we'll explore how to use SOAP to do the same thing.  This posting builds upon the previous posting, using the same site and file/folder structures.

Step 1: Preparation
  1. Add a new web part page to the SitePages folder.  For this posting, it is called map-soap.aspx.
  2. Add the quick launch to the page, as discussed here.
  3. Remove all the content in the PlaceHolderMain content placeholder.
  4. Add jQuery library version 1.9.0 to the site.  For this posting, it is placed in the jQuery folder located in the SitePages folder off the site root.
  5. Verify that a list is available for testing.  For this posting, the CountryData list is used.  This is the same list that was used in the previous posting to hold country data.
Step 2: Add SOAP template test script
  1. Copy and paste this template script in the PlaceHolderMain content placeholder:
    <script type="text/javascript" src="jQuery/jquery-1.9.0.js"></script>
    <script type="text/javascript">
     $(document).ready(function(){
       var soapEnv = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> \
        <soap:Body> \
         <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
          <listName>CountryData</listName> \
          <query> \
           <Query> \
            <Where> \
             <Eq> \
              <FieldRef Name='Title'/><Value Type='Text'>US</Value> \
             </Eq> \
            </Where> \
           </Query> \
          </query> \
          <viewFields> \
           <ViewFields> \
            <FieldRef Name='Title' /> \
            <FieldRef Name='Data' /> \
           </ViewFields> \
          </viewFields> \
          <rowLimit>99999</rowLimit> \
          <queryOptions xmlns:SOAPSDK9='http://schemas.microsoft.com/sharepoint/soap/' > \
           <QueryOptions/> \
          </queryOptions> \
         </GetListItems> \
        </soap:Body> \
        </soap:Envelope>";
       jQuery.ajax({
        url: "/jvectormap/_vti_bin/lists.asmx",
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        complete: ProcessListItems,
        contentType: "text/xml; charset=\"utf-8\""
       });
       function ProcessListItems(xData, status) {
        jQuery(xData.responseXML).find("z\\:row").each(function () {
         $("<li>" + $(this).attr("ows_Title") + " (" + $(this).attr("ows_Data") + ")</li>").appendTo("#CountryData");
        });
       };
     });
    </script>
    <ul id="CountryData"></ul>
    
Step: 3: Test template script
  • Open a browser and navigate to map-soap.aspx.  The item corresponding to US is displayed
Step 4: Modify script to retrieve all list items
  1. Review the script inserted above, and then find and remove this portion:
    <Where> \
      <Eq> \
        <FieldRef Name='Title'/><Value Type='Text'>US</Value> \
      </Eq> \
    </Where> \
    
  2. Refresh the browser connected to the map-soap.aspx page.  All of the list items are displayed
Step 5: Modify script to transform results into JSON array
  1. Add the following script library and CSS references just after the jQuery library reference added previously:
    <link href="jVectorMap/css/help.css" rel="stylesheet" type="text/css" media="all" />
    <script type="text/javascript" src="jVectorMap/js/jquery-jvectormap.js"></script>
    <script type="text/javascript" src="jVectorMap/js/jquery-mousewheel.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/jvectormap.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/abstract-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/abstract-canvas-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/abstract-shape-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-group-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-canvas-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-shape-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-path-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/svg-circle-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-group-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-canvas-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-shape-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-path-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vml-circle-element.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/vector-canvas.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/simple-scale.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/numeric-scale.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/ordinal-scale.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/color-scale.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/data-series.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/proj.js"></script>
    <script type="text/javascript" src="jVectorMap/lib/world-map.js"></script>
    <script type="text/javascript" src="jVectorMap/assets/jquery-jvectormap-world-mill-en.js"></script>
    <link href="jVectorMap/css/jquery-jvectormap.css" rel="stylesheet" media="all" />
    
  2. To the ProcessListItems function, add script to build JSON array from retrieved list data so that it looks like the following (additions highlighted):
    function ProcessListItems(xData, status) {
     var myString = "{";
     var mycdata;
     jQuery(xData.responseXML).find("z\\:row").each(function () {
      $("<li>" + $(this).attr("ows_Title") + " (" + $(this).attr("ows_Data") + ")</li>").appendTo("#CountryData");
      myString = myString + '"' + $(this).attr("ows_Title") + '":"' + $(this).attr("ows_Data") + '",';
     });
     myString = myString.substring(0, myString.length-1) + '}';
     mycdata = JSON.parse(myString);};
    
  3. Within the ProcessListItems function, just after the last statement in this function (in bold, below), add the jVectorMap script so that the entire function looks like the following:
    function ProcessListItems(xData, status) {
      
       var myString = "{";
       var mycdata;
       jQuery(xData.responseXML).find("z\\:row").each(function () {
        $("<li>" + $(this).attr("ows_Title") + " (" + $(this).attr("ows_Data") + ")</li>").appendTo("#CountryData");
        myString = myString + '"' + $(this).attr("ows_Title") + '":"' + $(this).attr("ows_Data") + '",';
       });
       myString = myString.substring(0, myString.length-1) + '}';
       mycdata = JSON.parse(myString);
       
       function chkValue(val){
         if (typeof val ==="undefined"){
           x = 0;
         }
         else{
           x = val;
         }
         return x;
       };
       $('#focus-single').click(function(){
         $('.map1').vectorMap('set', 'focus', 'SE');
       });
          
       //Reset focus
       $('#focus-init').click(function(){
         $('.map1').vectorMap('set', 'focus', 1, 0, 0);
       });
          
       //Clears all region colors
       $('#clear-map').click(function(){
         var map = $('.map1').vectorMap('get', 'mapObject');
         map.series.regions[0].clear();
       });
          
       $('#get-data').click(function(){
         alert(JSON.stringify(mycdata));
       });
       
       $('.map1').vectorMap({ 
         map: 'world_mill_en',
         //Set the initial focus to the center of the map
         //at the maximum zoom out
         focusOn: {
           x: 0.5,
           y: 0.5,
           scale: 1
         },
         series: {
           //this is the object for passing country/region data into
           regions: [{
             //define the range of color values
             scale: ['#DEEBF7', '#08519C'],
             //define the function that maps data to color range
             normalizeFunction: 'linear',
             //define the coloration method
             attribute: 'fill',
             //define the array of country data
             values: mycdata
           }]
         },
         onRegionLabelShow: function(event, label, code){
           label.html('<img src="/jVectorMap/CountryFlags/' + 
             code.toString() + '.png" /> ' + label.html() + 
             '<hr noshade="noshade" style="height: 1px"/>Count: ' + 
             chkValue(cdata[code]));
         }
       }); //closes jVectorMap
       
     }; //closes ProcessListItems
    
  4. Add the markup needed for the map container and interface elements:
    <!-- jVectorMap Container -->
    <div class="map1" style="width: 800px; height: 550px"></div>
    <!-- Set focus on Sweden  button -->
    <input id="focus-single" name="Button1" type="button" value="Focus on Sweden" />
    <!-- Reset map button -->
    <input id="focus-init" name="Button2" type="button" value="Reset Map" />
    <!-- Clear map button -->
    <input id="clear-map" name="Button3" type="button" value="Clear Map" />
    <input id="get-data" name="Button4" type="button" value="Get Data" />
    <!-- help button -->
    <div id="helpbtn"><a href="JavaScript:showHelpDialog();" class="helpDialog"><img src="jVectorMap/img/help.png" alt="Help" /></a></div>
    
  5. Save the page. 
  6. Open a browser and navigate to the page (or refresh).  The map is now displayed.  The same regions are colorized as in the previous posting:
  7. Add the script needed for the SharePoint modal popup.  Place it just above the JavaScript Ready function
    function showHelpDialog(){
      var options = {
        title: "jVectorMap help",
        width: 400,
        height: 600,
        url: "helpDialog.aspx" };
        SP.UI.ModalDialog.showModalDialog(options);
    };
    
  8. Lastly, remove the script and markup for generating the bulleted list.  Remove this script:
    $Query(xData.responseXML).find("z\\:row").each(function () {
      $("<li>" + $(this).attr("ows_Title") + " (" + $(this).attr("ows_Data") + ")</li>").appendTo("#CountryData");
      myString = myString = myString + '"' + $(this).attr("ows_Title") + '":"' + $(this).attr("ows_Data") + '",';
    });
    

    and then remove this markup:
    <ul id="CountryData"></ul>
    
  9. Save the page.
  10. Open a browser and connect (or refresh).  The markup no longer appears on the web page
Summary

In this posting, we have explored how to use SOAP methods to integrate SharePoint 2010 list data with jVectorMap.  This method uses the SharePoint 2010 SOAP service to retrieve data from a list.  For additional details on the topics discussed in this posting, see the references.

References
Notes
  • Has been tested successfully in this version.  Has been found not to work in version 1.9.1.  Other versions have not yet been tested.
  • Removing the CAML query causes the entire list to be retrieved.
  • The SharePoint modal popup will not work inside the jQuery Ready function.

No comments: