Monday, September 16, 2013

How to integrate jVectorMap with SharePoint 2010

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 of this series, we explored adding a modal popup to the jVectorMap display.   In this posting, we'll explore how to integrate a jVectorMap display with SharePoint Server 2010. We'll begin by reviewing the files and folders assembled to date.  Then,  using SharePoint Designer 2010, we'll migrate all of the various folders and script library files supporting this effort to a SharePoint Server 2010 site. Next, we'll create a new site page and migrate the markup and then test.  During testing, we'll discover a number of issues, and so we'll need to resolve these one by one.  At the conclusion of this exploration, we'll have migrated the markup and script base developed previously onto a SharePoint Server 2010 platform.

Step 1: Migrate
  1. Review the script library folder structure from the previous posting
  2. In SharePoint Designer 2010, select All Files, and then open the SitePages folder.  The All Files ribbon appears.
  3. From the All Files ribbon, click Import Files The Import dialog appears
  4. Click the Add Folder button.
  5. Navigate to the location of the jVectorMap folder created in the previous posting.
  6. Select this folder, and then click OK. The folder, it's subfolders and all contents are imported
  7. Continue to the next step
Step 2: Build
  1. Open a browser and connect to the website.  Create new page in the SitePages folder.  For this posting, it is named test.html.
  2. Close the edit page in the browser.
  3. Open test.aspx in SharePoint Designer 2010.
  4. In test.aspx, remove all script and markup in the content section having PlaceHolderId PlaceHolderMain.
  5. Open index.html imported previously.
  6. In index.html, copy all of the script library references and past these into the test.aspx content section having PlaceHolderId PlaceHolderMain.
  7. In index.html, copy the script block (leaving out the script tags) containing the jQuery script and past it into test.aspx, below the script library references.
  8. In index.html, copy all of the markup in the body section and past it below the script block.
  9. Once you complete these steps, the following markup and script will be in the PlaceHolderMain section of test.aspx:
    <!-- jQuery Library --> <script type="text/javascript" src="jVectorMap/js/jquery.min.js"></script> <!-- help --> <link href="jVectorMap/css/help.css" rel="stylesheet" type="text/css" media="all" /> <link href="jVectorMap/css/bootstrap.css" rel="stylesheet" type="text/css" media="all" /> <script type="text/javascript" charset="utf-8" src="jVectorMap/js/bootstrap.min.js"></script> <script type="text/javascript" charset="utf-8" src="jVectorMap/js/modals.js"></script> <!-- jvectormap --> <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> <!-- CSS --> <link href="jVectorMap/css/jquery-jvectormap.css" rel="stylesheet" media="all" /> <!-- Script --> <script type="text/javascript" > $.getJSON('data/cdata2.json', function(cdata){   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();    });    $('.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: cdata        }]      },      onRegionLabelShow: function(event, label, code){       label.html(label.html() +' (' + code.toString() +  ') <br>Count: '        + chkValue(cdata[code]));     },    });    setInterval(function(){     $.getJSON('data/cdata2.json', function(cdata){       var  map = $('.map1').vectorMap('get', 'mapObject');       map.series.regions[0].setValues(cdata);      })    }, 10000);  }) </script> <!-- jVectorMap Container --> <div class="map1" style="width: 800px; height: 550px"></div> <!-- Set focus on Sweden button --> <button id="focus-single">Focus on Sweden</button> <!-- Reset map button --> <button id="focus-init">Reset Map</button> <!-- Clear map button --> <button id="clear-map">Clear Map</button> <!-- help button --> <div id="helpbtn"><a href="#modalwin" data-toggle="modal"><img src="jVectorMap/img/help.png" alt="Help" /></a></div> <!-- modal window --> <div id="modalwin" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <header class="modal-header"> <a href="#" class="close" data-dismiss="modal">x</a> <h3>World Map Interface Help</h3> </header> <div class="modal-body"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque eget  augue porta, bibendum nisi in, sagittis urna. Cras placerat orci ac lectus consequat, sed porta tortor sollicitudin. Aenean lorem nibh, porta id neque  sit amet, fermentum dapibus turpis. Aliquam in sagittis arcu. Sed sit amet viverra enim. Sed ac elit feugiat, ultricies tortor sit amet, tincidunt lorem. Suspendisse condimentum mi eget massa euismod porttitor. In dictum arcu ac pellentesque imperdiet. </p> <p>In hac habitasse platea dictumst. Nullam metus neque, facilisis nec felis at, vehicula posuere ligula. Donec interdum consectetur mi eget facilisis.  Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer eget magna sed enim aliquet molestie a vel ligula. Quisque tellus odio, euismod in cursus id, semper at ipsum. Quisque non eros iaculis, consequat odio in, iaculis odio. Donec accumsan consequat risus, ut  dictum lorem volutpat ut. </p> <p>Sed euismod sollicitudin tortor quis adipiscing. Etiam sit amet fermentum  mi, id rutrum magna. Aliquam urna est, sagittis id sodales ut, convallis nec lorem. Cras ut blandit quam. Cras eget nisl nisi. Pellentesque feugiat luctus vestibulum. Donec ut nulla lorem.</p> <p>Vestibulum  at enim felis. Nullam cursus, nulla a dignissim mollis, turpis arcu aliquam urna, ut fermentum dolor ipsum sed lorem. Suspendisse euismod, odio sed consectetur pellentesque, elit lectus facilisis sem, vel ullamcorper ipsum sem porta dolor. Curabitur rhoncus urna sit amet euismod lobortis. Integer lobortis vitae arcu eget placerat. Duis varius feugiat dui sed commodo. Praesent pretium leo eget gravida ornare. Sed accumsan quam nunc, a lobortis arcu condimentum sed. In pulvinar mattis mi non egestas. Nulla venenatis rutrum placerat. Proin nec urna at nibh scelerisque dictum. Morbi eu nisi vitae dolor scelerisque rhoncus. Fusce sed erat tempor, interdum enim quis, convallis est. </p> <p>Close me by clicking anywhere outside the window, or by clicking the blue  button.</p> <p></p> </div> <footer class="modal-footer"> <a href="#" class="btn" id="okwin01">Close</a> </footer> </div> <!-- @end @modalwin --> -l
Step 3: Test
  1. Open a browser and connect to test.aspx.  It will have a URL something like: You will likely see something like this:
  2. This page will not display correctly and will present some of the following issues:
    1. Neither the map or the map background are displayed.
    2. The SharePoint 2010 ribbon tabs and page do not display correctly.
    3. Clicking a button also causes a page reload.
    4. The popup modal dialog appears different.
    Each of these issues will be fixed in the next step.
Step 4: Fix
  1. Neither the map nor the map background are displayed: The absence of the display is due SharePoint Server 2010 expected files ending in JSON to be handled as web services, and thus the function fails.  To resolve this:
    1. Remove the JSON line:
      $.getJSON('jVectorMap/data/cdata2.json',function(cdata){
    2. and replace it with a standard jQuery function statement:
      $(function(){
    3. Add JavaScript script library reference containing cdata array, as was explored in the second posting of this series:
      <script src="data/cdata.js"></script>
    4. Remove the setInterval function statement.
    5. Save the page, and then refresh the browser.  The map now displays
  2. The SharePoint 2010 ribbon tabs and page text do not display correctly: this is due to conflicts between the bootstrap CSS and SharePoint Server 2010 CSS. To resolve this, remove the following bootstrap CSS and JavaScript references:
    <link href="jVectorMap/css/bootstrap.css" rel="stylesheet" type="text/css" media="all" /> <script type="text/javascript" charset="utf-8" src="jVectorMap/js/bootstrap.min.js"></script> <script type="text/javascript" charset="utf-8" src= "jVectorMap/js/modals.js"> </script>
    Also remove all of the modal popup markup between these two comments (and also include the comment markup itself for removal):
    <!-- modal window -->
     .
     .
     .
    < !-- @end @modalwin -->

    After making these changes, refresh the browser to see the improvement to the UI:
  3. Clicking a button also causes a page reload: this is due to how SharePoint Server 2010 handles this type of form element.  To resolve this, replace allbutton elements,
     <button id="focus-single">Focus on Sweden</button> 
    with input form elements:
    <input id="focus-single" name="Button1" type="button" value="Focus on Sweden" />
  4. The popup modal dialog appears different: this is due to conflicts between the bootstrap CSS and the SharePoint Server 2010 CSS.  A fix for this is available; however, it's simpler to use the native SharePoint Server 2010 ModalDialog object.  Add the following JavaScript to the same script block as the map script (but outside of the jQuery function):
    function showHelpDialog(){
      var options = {
        title: "jVectorMap help",
        width: 400,
         height: 600,
         url: "helpDialog.aspx" };
      SP.UI.ModalDialog.showModalDialog(options);
     };
    
    Most of the bootstrap markup has been removed. Now remove this statement:
    <div id="helpbtn"><a href="#modalwin" data-toggle="modal"><img src="img/help.png" alt="Help" /></a></div>
    
    and replace with this one:
    <div id="helpbtn"><a href="JavaScript:showHelpDialog();" class="helpDialog"> <img src="jVectorMap/img/help.png" alt="Help" /></a> </div>
     
    Now test. Click the Help button.  A modal popup will appear.

Optional: remove the status bar message
  1. This status bar message appears due to the fact that the page has been modified from its original template:
    The status bar message can be removed for this page by inserting CSS that hides it.  The CSS to hide this message bar can be inserted into the page using the Content Editor web part.
  2. Launch SharePoint Designer 2010.
  3. Connect to the site
  4. Check out and then open the page.  Switch to Code view.
  5. Add the following markup just prior to the closing <asp:content>. This isn't necessary, but it will support more easily adding Content Editor web parts in the future
  6. Switch to Design view.  Select the Insert ribbon, click the Web Part button.  The Web Parts Picker dialog appears.  Enter Content as a search keyword.  The Content Editor web part will appear in the listing.
  7. Select this web part, and then click OK.  The web part is inserted into the page
  8. On the SharePoint Designer 2010 UI, select the File tab at top, select Add item, and then click More Pages.
  9. On the More Page Template pane, select Text File, and then click the Create button.  The New Text File dialog appears
  10. On this dialog, enter a new name for the file, and then click OK.  The new page will appear in Code view.  On this page, enter the CSS style markup as shown below
  11. Save this file and close it.  Go back to the jVectorMap file (named Map.aspx in this procedure).
  12. Double-click on the Content Editor web part.  The Content Editor (properties) dialog appears.  On this dialog, enable the Layout Hidden property
  13. Click on the small icon next to the Content Link text box.  The Edit Hyperlink dialog appears.  In this dialog, navigate to the text file you created above, and then select it.
  14. Click OK.  The dialog closes.  Save and close the map file.
  15. Open a browser and navigate to the map page.  The message status bar no longer appears
Optional: Hide the Recently Modified group in Quick Launch
  1. This can be hidden using the same approach as previous.  Re-open the custom CSS file you created previously.  In this file, add the additional CSS as shown in the image below
  2. Save and close the file.  Refresh the browser connect to the map page.  The Recently Modified quick launch group no longer appears
Summary

In this posting, we have explored the mechanics of migrating the jVectorMap display to the SharePoint Server 2010 platform.  In the next posting, we will explore how to use REST to integrate SharePoint 2010 list data with jVectorMap.

References

2 comments:

Terri Pilares-Magno said...

Does this also work with SharePoint 2013 as well? I tried the above steps but unfortunately the map just won't appear on the page.

Al said...

I haven't implemented this on 2013, so, I can't say yes or no, but I'm not aware of any immediate reason why it shouldn't. When troubleshooting, I use the incremental approach: start with a blank page on your desktop (jVectorMap doesn't need a web server to work), then add a line of script, and then test; add a line of script, then test; and so on, until you find the source of the problem. THen, once you get it working on your desktop, migrate the script line-by-line to a SharePoint page. Start with a page that has everything cleared out between the PlaceHolderMain tags, and begin migrating it to this section. There can be many reasons preventing a map from being properly rendered on the page, from incorrect ordering of JavaScript references to incorrectly defining and using jVectorMap variables. You'll need to test carefully.