Showing posts with label jVectorMap. Show all posts
Showing posts with label jVectorMap. Show all posts

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.

Saturday, September 21, 2013

How to use REST 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 of this series, we explored how to migrate jVectorMap to the SharePoint 2010 platform.  In this posting, we will explore how to use REST to integrate SharePoint 2010 list data with jVectorMap.  The integration path involves: a SharePoint 2010 list, SharePoint 2010 REST services, jQuery, JSON, and jVectorMap.  By adding just a few lines of script to what has been developed thus far, we can extract list data into a JSON array and then pass this array into the series.region.values object in order to implement region coloration.   Building this integration path involves the following steps:
  1. Create the data list
  2. Identify REST svc URL
  3. Add data to the list
  4. Develop the script
  5. Test
The integration path presented here tested successfully using jQuery version 1.9.0. It did not test successfully with version 1.9.1.  Other versions have not yet been tested.

Step 1: Create the data list
  1. In SharePoint 2010, create a new list. Name the list without using spaces or non-CHARs so as to avoid HTML parsing changes. For this posting, the list is called CountryData. Leave the name of the Title field default. This field will contain the country digraph.
  2. Add a new field. Name the field without using spaces or non-CHARs in the name to avoid internal name conversion changes. For this posting, the new field is named Data.
Step 2: Identify REST service URL
  1. Open a browser, and then navigate to the site.
  2. Append the following to this URL: _vti_bin/listdata.svc, and then navigate to this URL
  3. Review the lists available via the REST interface. Append to the URL the name of the desired list. Note the capitalization.
  4. Append to this URL the querystring for selecting just the necessary fields from this list (note that meta information is still pulled even though its field, __metadata, (that's two underscores)is not specifically included):
    ?$select=Title,Data
  5. For this posting, the final URL is the following:
    ...[yoursite]/_vti_bin/ListData.svc/CountryData()?$select=Title,Data
    
Step 3: Add data to the list
  1. Add data to this list. For this posting, the same data used in previous postings is used for this one
  2. Open a browser and navigate to the URL obtained in the previous step. All of the list rows will appear:
Step 4: Develop the script
  1. First, modify the general jQuery function call so that script is executed after the DOM is ready. Change:
    (function () {
    
    to
    $(document).ready(function () {
    
  2. Define a variable for the REST service URL, and then enclose the script developed previously in a getJSON function
    var qryWCFUrl = "...yoursite/_vti_bin/ListData.svc/CountryData()?$select=Title,Data";
    $.getJSON(qryWCFUrl, function (results) {
    .
    .
    .
    });
    
  3. Add the script that:
    1. extracts the appropriate fields from the REST results,
    2. builds a key/value string from these results,
    3. parses the string into JSON format and
    4. loads it into an array.
    var mycdata;
    var myString = "{";
    $.each(results.d.results, function (i, item) {
     myString = myString + '"' + item.Title + '":"' + item.Data + '",';
    });
    myString = myString + '"ZZ":"1"}';
    mycdata = JSON.parse(myString);
    
  4. Change the variable used previously to pass data into the map, cdata, to the new variable, or mycdata, as used in this posting. Change:
    values: cdata
    to
    values: mycdata
  5. Optional: Add a click event handler that presents a popup of the stringified JSON data:
    $('#get-data').click(function(){
     alert(JSON.stringify(mycdata));
    });
  6. Optional: Add a button that the event handler binds to.
    <input id="get-data" name="Button4" type="button" value="Get Data" />
Step 5: Test
  1. Open a browser to the new page.  The results will appear identical
  2. Click on the new function button to see the stringified JSON data array
Final Script

Below is the final script that includes all of the modifications discussed above:

<script type="text/javascript" >    function showHelpDialog(){      var options = {        title: "jVectorMap help",        width: 400,        height: 600,        url: "helpDialog.aspx" };       SP.UI.ModalDialog.showModalDialog(options);    };    $(document).ready(function () {       var qryWCFUrl = "http://spdev12:4000/jVectorMap/_vti_bin/ListData.svc/CountryData()?$select=Title,Data"    $.getJSON(qryWCFUrl, function (results) {          var mycdata;     var myString = "{";     $.each(results.d.results, function (i, item) {      myString = myString + '"' + item.Title + '":"' + item.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 JSON      }) //closes jQuery function  </script>

Summary

In this posting, we have explored a simple method for extracting data from a SharePoint 2010 list,  and then ingesting this into the jVectorMap series.region object.  This integration path employed jQuery, JSON and REST services. Using this simple integration path, data in a SharePoint 2010 list can be used to support jVectorMap region coloration.  This method may also be used to support more complex integration, such as supporting region popups, marker placement and configuration and other solutions.

References
Notes
  • SharePoint Server 2010 Standard or Enterprise?  Either works for this.
  • REST vs. SOAP: the integration path presented here is much  simpler than that which would be necessary using SOAP methods.

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

Saturday, September 7, 2013

How to add a popup modal to jVectorMap using Bootstrap

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 integrate SharePoint 2010 list data with jVectorMap
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 post in this series, we explored adding some basic user interactivity to the jVectorMap display. In this post, we'll explore adding a popup modal dialog in which you can provide: an introduction to the map, help tips and other useful information to your users. We'll explore using the JavaScript-based Bootstrap modal dialog method to accomplish this, over the following five steps:
  1. Add New JavaScript Library References
  2. Modify Map Zoom Button CSS
  3. Add Custom Help Button CSS
  4. Add Help Button Image Container
  5. Add Popup Modal Dialog Container
Before we get started, let's first review the markup and script developed thus far through this series - this is what we'll be adding to in this posting:
<!DOCTYPE html> <html> <head> <title>jVectorMap demo</title> <!-- jQuery Library -->   <script src="js/jquery.min.js"></script> <!-- jvectormap --> <link href="css/jquery-jvectormap.css" rel="stylesheet" media="all" /> <script src="js/jquery-jvectormap.js"></script> <script src="js/jquery-mousewheel.js"></script> <script src="lib/jvectormap.js"></script> <script src="lib/abstract-element.js"></script> <script src="lib/abstract-canvas-element.js"></script> <script src="lib/abstract-shape-element.js"></script>   <script src="lib/svg-element.js"></script> <script src="lib/svg-group-element.js"></script> <script src="lib/svg-canvas-element.js"></script> <script src="lib/svg-shape-element.js"></script> <script src="lib/svg-path-element.js"></script> <script src="lib/svg-circle-element.js"></script>   <script src="lib/vml-element.js"></script> <script src="lib/vml-group-element.js"></script> <script src="lib/vml-canvas-element.js"></script> <script src="lib/vml-shape-element.js"></script> <script src="lib/vml-path-element.js"></script> <script src="lib/vml-circle-element.js"></script>   <script src="lib/vector-canvas.js"></script> <script src="lib/simple-scale.js"></script> <script src="lib/numeric-scale.js"></script> <script src="lib/ordinal-scale.js"></script> <script src="lib/color-scale.js"></script> <script src="lib/data-series.js"></script> <script src="lib/proj.js"></script> <script src="lib/world-map.js"></script> <script src="assets/jquery-jvectormap-world-mill-en.js"></script>   <!-- Script --> <script>   $.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> </head> <body> <!-- jVectorMap display 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> </body> </html>
And here's what the file/folder structure built looks like so far:
We'll need to get the following files:
  • bootstrap.min.js - Minified Bootstrap core JavaScript library
  • modals.js - Bootstrap modal dialog library
  • bootstrap.css - Bootstrap CSS
Additionally, you'll need to get a suitable icon for building the help dialog link and to create an empty CSS file, in which you'll build the custom help CSS.  The Bootstrap files can be downloaded from the Bootstrap site, noted below in the References section.

After getting these files, adding an image, and creating a blank CSS file, we'll have the following folder contents:
The help.css is our blank CSS file for containing our custom help CSS. 

Add New JavaScript Library References

First, we'll add the new JavaScript library and CSS references to the current project file.  These new references need to be added after the jQuery library reference, which should always come first.
<!-- help --> <link href="css/help.css" rel="stylesheet" type="text/css" media="all" > <link href="css/bootstrap.css" rel="stylesheet" type="text/css" media="all" > <script type="text/javascript" charset="utf-8" src="js/bootstrap.min.js"></script> <script type="text/javascript" charset="utf-8" src="js/modals.js"></script>
Modify Zoom Button CSS

Now, the image that we want to display is 48 pixels square.  We want to place it in the top left corner of the map.  To do this, we'll need to move the existing zoom help buttons to the right.  The help button CSS is located in jquery-jvectormap.css, which came with the original jVectorMap files.  Open this file and then look for the jvectormap-zoomin and jvectormap-zoomout selectors and change their left property declarations from 5px to 55px.  This should give enough space to allow the these  items to continue to appear. 

Add Custom CSS for New Help Button

Now we'll open the empty CSS file for our custom CSS and add some declarations to it that control the position and appearance of the new help button:
Add New Help Button Image Container
Then add a container for the image and its hyperlink to the body section of the HTML page, so that now the markup here looks like this (markup added is highlighted):
<body> <!-- jVectorMap display 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="img/help.png" alt="Help" /></a></div> </body>
Once this is completed, refreshing the HTML page will return this:
Add Popup Modal Dialog Container

For the final step, we need to add the container and markup for the popup modal dialog.
<!-- 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>Close me by clicking anywhere outside the window, or by clicking the blue button.</p> </div> <footer class="modal-footer"> <a href="#" class="btn" id="okwin01">Close</a> </footer> </div> <!-- @end @modalwin -->

After refreshing the HTML page, and clicking the new help button, we'll see this:
To customize the modal popup, refer to the Bootstrap documentation.

Summary

In this posting in the jVectorMap series, we explored adding a modal help dialog to the map display using the Bootstrap method.  This method is simple and easy to implement and requires no additional script development.  Just drop the library references in, add the markup and you are on your way.  In the next posting of this series, we'll explore how to migrate the jVectorMap project developed to date onto a SharePoint Server 2010 platform.

References
Notes
  • The Bootstrap approach is simple and easy to implement.  However, the CSS used with this approach conflicts in part with the SharePoint 2010 Core4.CSS, disrupting the appearance of the SharePoint 2010 ribbon and other UI features.  A new Bootstrap version specifically for SharePoint 2010 is available, however, the author has not yet tested this new version.  Instead, in a subsequent article, we'll explore using the SP.UI.ModalDialog.showModalDialog method to show popup help dialogs for SharePoint 2010 deployments of jVectorMap.