Showing posts with label WebPart. Show all posts
Showing posts with label WebPart. Show all posts

December 2, 2020

How to clear Office UI Fabric multi-select dropdown in SPFx webpart with React Framework?

Scenario:

We implemented a webpart using SharePoint Framework (SPFx) that includes the filter functionality. As per the requirement, we have one dropdown that allows multiple options selection for filter functionality. Now when user clicks on the "Clear Filter" button, it should clear the selection of options from the dropdown.

Below is our dropdown control with multiple items selection:
 <Dropdown  
  multiSelect  
  className="multiSelectDrodpown"  
  options={currentObj.state.dropdownOptions}  
  defaultSelectedKeys={this.state.selectedOptions}  
  onChanged={(val) => currentObj.filterData(val)}           
 ></Dropdown>  

Note:
  • dropdownOptions state contains all the options which will be display in multi select dropdown control.
  • selectedOptions is the state which contains the options which are currently selected.


Problem Statement:

  • When we select the values from the multi-select dropdown control, we pass those values to defaultSelectedKeys parameter of the multi-dropdown control to show the selected values. 
  • But when we clear the value of the state which we are using in defaultSelectedKeys parameter(selectedOptions state in our scenario), it does not clear the selection of multi-select dropdown.


Solution:

  • To resolve this issue, we need to use the "key" parameter of the office fabric UI dropdown control and set the unique number as the value on click event of the "Clear Filter" button.
  • Using a new value for key parameter means, it renders fresh control each time.
  • Here, we use randomIndex state to set a new key value to generate a random number. Below is an example to use key attribute:
 <Dropdown  
  multiSelect  
  className="multiSelectDrodpown"  
  options={currentObj.state.dropdownOptions}  
  defaultSelectedKeys={this.state.selectedOptions}  
  onChanged={(val) => currentObj.filterData(val)}     
  key={this.state.randomIndex}        
 ></Dropdown>  
  • Now, when user clicks the "Clear Filter" button, it will update randomIndex state and set a new random number as its value.
  • Here, we are using Math.floor and Math.random()  function to generate random numbers.
 private async clearFields() {  
      await this.setState({    
          randomIndex: Math.floor(Math.random() * 6) + 1          
       });  
 }  


Conclusion:

This is how we can clear the value of multi-select dropdownlist in SharePoint Framework (SPFx).

If you have any questions you can reach out our SharePoint Consulting team here.

July 28, 2016

Add Listview webpart from one site to any other site within Site collection in SharePoint.

Introduction: 
To display content from any SharePoint List/Library in Site Page or Publishing Page within same site, we can use List View web part but has one limitation: both Site Page where web part will be added and SharePoint List must be on same site. What if, there is requirement to have List view web part to display content of SharePoint List to another site, is it possible?

Here is the solution to display data from SharePoint list as List View web part from the site to its parent site within same site collection.

Approach/Solution:
  1. Open SharePoint site in Microsoft SharePoint Designer 2010 where your document library/list exists.
  2. Click on "Lists and Libraries" sections.
  3. Open your document library.
  4. Select "All Documents" view from "Views" section.
  5. Select your document library list view web part in design mode.

  6. Select "Web Part" tab in Ribbon.
  7. Click on "To Site Gallery" in "Save Web Part" group.
  8. Give appropriate name and description to web part and press "ok".
  9. Now your document library is added as web part in web part gallery. 
  10. You can add this document library web part to parent site or any other site within same site collection by adding it as list view web part on page.
  11. Web part will be available under "Miscellaneous" web parts category.
If you have any questions you can reach out our SharePoint Consulting team here.

January 21, 2014

All CQWP web part appears as ErrorWebPart when fetching using object model in Console Application

In console application, while looping through all web parts in a page, if a page contains ContentByQueryWebpart, exception those web part will be rendered as ErrorWebParts
Because of the following code is called by the specific properties of the ContentByQueryWebpart
(actually its parent, the CmsDataFormWebpart):

   1:  internal static string MakeServerRelativeUrl(string url)
   2:  {
   3:      return concatenateUrls(SPContext.GetContext(HttpContext.Current).Site.ServerRelativeUrl, url);
   4:  }
The webpart will always call the SPContext, but from a console application there is no web-context. Therefore when initiating the
ContentByQueryWebpart, it will always thow an exception like:
"An error occured while setting the value of this property: Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart:MainXslLink - Exception has been thrown by the target of an invocation."
Workaround for this would be to provide it with a context.


   1:  if (HttpContext.Current == null)
   2:              {
   3:           isContextNull = true;
   4:                  HttpRequest request = new HttpRequest("", myweb.Url, "");
   5:                  HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
   6:                  HttpContext.Current.Items["HttpHandlerSPWeb"] = myweb;
   7:               }

If you have any questions you can reach out our SharePoint Consulting team here.

September 4, 2013

Add webpart to existing pages and add custom property meta data values to webparts through utility

Webparts adding to existing page and their custom property values which are meta data.
What i have done here is created powershell script to get taxonomy values like term store. powershell script will ask for central admin URL and Termstore name.
   1:  Add-PSSnapin Microsoft.SharePoint.PowerShell
   2:  #read parameters from command line
   3:  $CurrentDir= Split-Path -parent $MyInvocation.MyCommand.Definition
   4:  $timeStamp = (Get-Date).ToString("yyyyMMddhhmmss")
   5:  $logFile = $CurrentDir+ "\install_" + $timeStamp + ".log"
   6:  start-transcript -path $logFile -noclobber
   7:  $url = Read-Host "Enter Central admin url" 
   8:  #$url = "http://br66:14209/"
   9:  #$site = Get-SPSite -Identity "http://br66:14209/"
  10:  $web = Get-SPWeb $url
  11:  $taxonomySession = Get-SPTaxonomySession -Site $web.Site
  12:  $termStoreName = Read-Host "Enter TermStore Name"
  13:  $termStore = $taxonomySession.TermStores[$termStoreName];
  14:  Write-Host $termStore.Name $termStore.Id

   1:  foreach($item in $termStore.Groups)
   2:  {
   3:  Write-Host $item.Name
   4:  foreach($term in $item.TermSets)
   5:  {   
   6:   if($term.Name -eq "Site Section")
   7:   {
   8:    Write-Host $term.Name
   9:    $group = $term
  10:   Write-Host ": " $group.Name $group.Id 
  11:   foreach($termSetUnit in $term.Terms)
  12:   {
  13:    if($termSetUnit.Name -eq "Test and Measurement")
  14:    {
  15:     Write-Host $termSetUnit.Name   
  16:     foreach($termset1 in $termSetUnit.Terms)
  17:     {
  18:      Write-Host $termset1.Name
  19:      $TermName = $termset1
  20:      Write-Host ": " $TermName.Name $TermName.Id
  21:     }
  22:    }
  23:   }
  24:   
  25:   }
  26:  }
  27:  }
With this one text file will generate and copy and paste values in config file

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <ContentDeploymentConfig  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   3:   <SourceSite>http://br66:50001</SourceSite>
   4:   <LastRunTime>2013-01-01T12:00:00Z</LastRunTime>
   5:   <FeatureId>6717c859-64c8-4f7a-bfc0-873256087ac8</FeatureId>
   6:   <TaxonomyStoreID>0ded38c7-c349-4638-8ce8-e564fdd44922</TaxonomyStoreID>
   7:   <TaxonomySetID>ddb6225b-471c-4a6c-853f-bf4686dc88e6</TaxonomySetID>
   8:   <TaxonomyProductGUID>Products|9b34e73d-d4c2-4680-bd8c-5343f4b66463</TaxonomyProductGUID>
   9:   <TaxonomyServiceGuid>Services|bc612c4e-3267-4c6f-9ff1-0e99726e802f</TaxonomyServiceGuid>
  10:   <Countries>
  11:    <Japan>ja-jp</Japan>
  12:    <China>zh-cn</China>
  13:    <poland>pl-pl</poland>
  14:    <Russia>ru-ru</Russia>
  15:    <Germany>de-de</Germany>
  16:    <Spain>es-es</Spain>
  17:    <Brazil>pt-pr</Brazil>
  18:    <UnitedStates>en-us</UnitedStates>
  19:   </Countries>
  20:  </ContentDeploymentConfig>
Above red marked values i got from script.
After getting this values add webparts to existing pages of site.
Your page should be checked out above spmgr else it will not do checked out if it is written inside.

   1:  if (pageCategory.CheckOutType == SPFile.SPCheckOutType.None)
   2:                              {
   3:                                  pageCategory.CheckOut();
   4:                              }
   5:  SPLimitedWebPartManager spmgr = sourceProductsWeb.GetLimitedWebPartManager(pageCategory.Url.ToString(), PersonalizationScope.Shared);
   6:                              string exportedWebPartXml = string.Empty;
   7:                              if (WebpartTitle == "EngagementProductLinks")
   8:                              {
   9:                                  exportedWebPartXml = new StringReader(sourceSite.RootWeb.GetFileAsString(sourceSite.RootWeb.Url + "/_catalogs/wp/EngagementProductLinks.webpart")).ReadToEnd();
  10:                              }
  11:                              else if (WebpartTitle == "RightColumnPromotions")
  12:                              {
  13:                                  exportedWebPartXml = new StringReader(sourceSite.RootWeb.GetFileAsString(sourceSite.RootWeb.Url + "/_catalogs/wp/RightColumnPromotions.webpart")).ReadToEnd();
  14:                              }
  15:                              XmlTextReader reader = new XmlTextReader(new StringReader(exportedWebPartXml));
  16:                              System.Web.UI.WebControls.WebParts.WebPart importedWp = spmgr.ImportWebPart(reader, out outmessage);
  17:                              String spmgrWebPartTitle = string.Empty;
  18:                              if (spmgr != null)
  19:                              {                                
  20:                                  for (int j = 0; j < spmgr.WebParts.Count; j++)
  21:                                  {
  22:                                      spmgrWebPartTitle = spmgr.WebParts[j].Title;
  23:                                      if (spmgrWebPartTitle != WebpartTitle)
  24:                                      {
  25:                                          if (spmgr.GetZoneID(spmgr.WebParts[j]) == "ContactsZone")
  26:                                          {
  27:                                              countwebparts++;
  28:                                          }
  29:                                      }
  30:                                      if (spmgrWebPartTitle == WebpartTitle)
  31:                                      {
  32:                                          if (spmgr.GetZoneID(spmgr.WebParts[j]) == "ContactsZone")
  33:                                          {
  34:                                              sourceProductsWeb.AllowUnsafeUpdates = true;
  35:                                              spmgr.DeleteWebPart(spmgr.WebParts[j]);
  36:                                              pageCategory.Update();
  37:                                              sourceProductsWeb.AllowUnsafeUpdates = false;                                            
  38:                                          }
  39:                                      }
  40:                                      
  41:                                      if (spmgrWebPartTitle.Equals("Promotion Right Column"))
  42:                                      {
  43:                                          if (spmgr.GetZoneID(spmgr.WebParts[j]) == "ContactsZone")
  44:                                          {
  45:                                              sourceProductsWeb.AllowUnsafeUpdates = true;
  46:                                              WriteLog("found");
  47:                                              spmgr.DeleteWebPart(spmgr.WebParts[j]);
  48:                                              pageCategory.Update();                                                                                      
  49:                                              sourceProductsWeb.AllowUnsafeUpdates = false;                                           
  50:                                          }                                        
  51:                                      }
  52:                                  }
  53:                              } 
  54:  sourceProductsWeb.AllowUnsafeUpdates = true;                             
  55:  try
  56:              {
  57:                  if (pageCategory.CheckOutType == SPFile.SPCheckOutType.None)
  58:                  {
  59:                      pageCategory.CheckOut();                }               
  60:                  
  61:                  importedWp.ChromeType = PartChromeType.None;
  62:                  spmgr.AddWebPart(importedWp, "ContactsZone", index);
  63:                  spmgr.SaveChanges(importedWp);
  64:                  PropertyInfo[] SiteSecitonProperty = importedWp.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
  65:                  foreach (PropertyInfo sitesection in SiteSecitonProperty)
  66:                  {
  67:                      if (sitesection.Name == "SiteSectionTaxonomy")
  68:                      {
  69:                          sitesection.SetValue(importedWp, GUID, null);
  70:                          spmgr.SaveChanges(importedWp);
  71:                      }
  72:                      else if (sitesection.Name == "TermStoreID")
  73:                      {
  74:                          string TermStoreguid = ContentDeploymentConfigObj.TaxonomyStoreID;
  75:                          System.Guid guid = new Guid(TermStoreguid);
  76:                          sitesection.SetValue(importedWp, guid, null);
  77:                          spmgr.SaveChanges(importedWp);
  78:                      }
  79:                      else if (sitesection.Name == "TermSetID")
  80:                      {
  81:                          string TermSetguid = ContentDeploymentConfigObj.TaxonomySetID;
  82:                          System.Guid guid = new Guid(TermSetguid);
  83:                          sitesection.SetValue(importedWp, guid, null);
  84:                          spmgr.SaveChanges(importedWp);
  85:                      }
  86:                      else if (sitesection.Name == "Text")
  87:                      {
  88:                          sitesection.SetValue(importedWp, GUID, null);
  89:                          spmgr.SaveChanges(importedWp);
  90:                      }
  91:                  }                
  92:                  pageCategory.CheckIn(" Added Web Part " + importedWp.Title);                               
  93:              }
  94:              catch (Exception ex)
  95:              {
  96:                  WriteLog("Error " + ex.Message + "Page is " + pageCategory.Title);
  97:                  WriteLogFile(false, ex.Message + sourceProductsWeb.Url.ToString() + "/" + pageCategory.Url.ToString() + " giving error in site ");
  98:                  if (pageCategory.CheckOutType == SPFile.SPCheckOutType.Online)
  99:                  {                    
 100:                      pageCategory.CheckIn("Checkin");
 101:                  }               
 102:              }
 103:                              sourceProductsWeb.AllowUnsafeUpdates = false;

Above code is to add webparts and properties value to webparts.
If you have any questions you can reach out our SharePoint Consulting team here.

June 13, 2013

Export any web part any where in the site

http://server/_vti_bin/exportwp.aspx?pageurl=absolutePageUrl&guidstring=webPartGuid​
If you have any questions you can reach out our SharePoint Consulting team here.

XSLT Debugging with Altova XSLT Spy

​Debugging XSLT with Altova XMLSpy
Testing and perfecting XSLT stylesheets can be a complicated, time-consuming process. With the XMLSpy XSLT debugger, you can step through and debug even the most intricate stylesheets quickly and easily. You can even debug stylesheets that contain program code in Java, C#, JavaScript, or VBScript. When debugging complex XSLT stylesheets, it is useful to be able to understand exactly what output is produced by each instruction. In the XSLT debugger, you can define breakpoints in the XML and XSLT files, and tracepoints in the XSLT document.

Setting Breakpoints & Tracepoints
Breakpoints halt the XSLT debugger when a particular node, element, or attribute is accessed by an XSLT instruction, allowing you to view the output to that particular point in the transformation. When you start the debugger, the XSLT processor stops at the first breakpoint and displays all data relevant to the node in the debugger info windows.
In contrast to breakpoints, tracepoints do not halt the XSLT debugger. When a tracepoint is hit during an XSLT debugging session, the instruction is executed, and information is written to the Trace window. Once the transformation is complete, the trace window displays the list of tracepoints as well as the output produced by each. This allows you to view exactly how each XSLT instruction is executed.

steps:
  • Open the XSLT File in Altova XMLSpy Edito
  • Specify the output XML file
  • Insert break point/Trace point at desired node, attribute or element
  • Review the output in output window
Eg. Search Core Result Web part XSLT Debugging
  • To debug the XSLT, you will need the output XML file. So edit the search core result web part
  • Click on XSL Editor under ‘Display Properties’
  • Copy-Paste following code in editor:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
    <xmp><xsl:copy-of select="*"/></xmp>
    </xsl:template>
    </xsl:stylesheet>
  • Copy the output and save it in an XML File say output.xml
  • Open the XSLT file with Altova XMLSpy editor
  • Set breakpoint/trace point to attribute/node/element
  • Click on XSL/Query menu and select Start Debugger/Go
  • Specify the output.xml file location
  • Start debugging!!!!

If you have any questions you can reach out our SharePoint Consulting team here.

April 16, 2013

How to programmatically order web parts in a publishing page

If web parts are already deployed on the site collection web part gallery and if want to add web part on the web part page programmatically, following is the code. If want to add the Web Part to a Web Part , from Web Part manager in which zone to add the web part and in which order we have to Addwebpart property of webpart taking index of webpart in which order we have to place our webpart.
Suppose in a zone there are two webparts indexing 1 and 2 and now we have to add a new webpart programmatically in between these two webparts then we have to give index value 2 to new value and previous 2 will automatically become 3.
CODE:
   1:  foreach (PublishingPage pubpge in publishingPages)
   2:   
   3:                  {
   4:   
   5:                      SPFile pageCategory = pubpge.ListItem.File;
   6:   
   7:  SPLimitedWebPartManager spmgr = sourceProductsWeb.GetLimitedWebPartManager(pageCategory.Url.ToString(), PersonalizationScope.Shared);
   8:   
   9:                              string exportedWebPartXml = string.Empty;
  10:   
  11:  exportedWebPartXml = new StringReader(sourceSite.RootWeb.GetFileAsString(sourceSite.RootWeb.Url + "/_catalogs/wp/EngagementProductLinks.webpart")).ReadToEnd();
  12:   
  13:  XmlTextReader reader = new XmlTextReader(new StringReader(exportedWebPartXml));
  14:   
  15:                              System.Web.UI.WebControls.WebParts.WebPart importedWp = spmgr.ImportWebPart(reader, out outmessage);
  16:   
  17:  sourceProductsWeb.AllowUnsafeUpdates = true;
  18:   
  19:  if (pageCategory.CheckOutType == SPFile.SPCheckOutType.None)
  20:   
  21:                  {
  22:   
  23:                      pageCategory.CheckOut();
  24:   
  25:                  }
  26:   
  27:                  importedWp.ChromeType = PartChromeType.None;
  28:   
  29:                  spmgr.AddWebPart(importedWp, "ContactsZone", 1);
  30:   
  31:                  spmgr.SaveChanges(importedWp);
  32:   
  33:                  pageCategory.CheckIn(" Added Web Part " + importedWp.Title);
  34:   
  35:                  pageCategory.Publish(" Added Web Part " + importedWp.Title);
  36:   
  37:  if (pubpge.ListItem.ModerationInformation != null &&  (pubpge.ListItem.ModerationInformation.Status == SPModerationStatusType.Draft || pubpge.ListItem.ModerationInformation.Status == SPModerationStatusType.Pending))
  38:   
  39:                              {
  40:   
  41:                                  pageCategory.Approve("Programmatically Approve");
  42:   
  43:                              }
  44:   
  45:                              sourceProductsWeb.AllowUnsafeUpdates = false;
Note: Sharepoint has a limitation of ordering webparts in a single zone.
If there are already three webparts and we have to fourth webpart then increment of webpart index will be 1. Now zone has four webpart and want to add fifth webpart it will be added at correct place but index of webpart will not be increased by one. They will increase by multiple of index like if 2 then it will increase by 4.
Reference for Limitation : http://blogs.msdn.com/b/jjameson/archive/2009/06/05/splimitedwebpartmanager-addwebpart-mysteriously-increments-zoneindex.aspx
http://www.technologytoolbox.com/blog/jjameson/archive/2009/06/05/splimitedwebpartmanager-addwebpart-mysteriously-increments-zoneindex.aspx
Reference for ordering webpart: http://nikspatel.wordpress.com/2010/11/09/programmatically-add-the-web-part-on-the-sharepoint-web-part-page/
Also we can add property value programmatically.
Like i have added custom property(Taxonomy field) value while adding webparts on page.
By using "SetValue" property. CODE:

   1:  foreach (PropertyInfo sitesection in SiteSecitonProperty)
   2:   
   3:                  {
   4:   
   5:                      if (sitesection.Name == "SiteSectionTaxonomy")
   6:   
   7:                      {
   8:   
   9:                          sitesection.SetValue(importedWp, GUID, null);
  10:   
  11:                          spmgr.SaveChanges(importedWp);
  12:   
  13:                      }
  14:   
  15:                      else if (sitesection.Name == "TermStoreID")
  16:   
  17:                      {
  18:   
  19:                          string TermStoreguid = ContentDeploymentConfigObj.TaxonomyStoreID;
  20:   
  21:                          System.Guid guid = new Guid(TermStoreguid);
  22:   
  23:                          sitesection.SetValue(importedWp, guid, null);
  24:   
  25:                          spmgr.SaveChanges(importedWp);
  26:   
  27:                      }
  28:   
  29:                      else if (sitesection.Name == "TermSetID")
  30:   
  31:                      {
  32:   
  33:                          string TermSetguid = ContentDeploymentConfigObj.TaxonomySetID;
  34:   
  35:                          System.Guid guid = new Guid(TermSetguid);
  36:   
  37:                          sitesection.SetValue(importedWp, guid, null);
  38:   
  39:                          spmgr.SaveChanges(importedWp);
  40:   
  41:                      }
  42:   
  43:                      else if (sitesection.Name == "Text")
  44:   
  45:                      {
  46:   
  47:                          sitesection.SetValue(importedWp, GUID, null);
  48:   
  49:                          spmgr.SaveChanges(importedWp);
  50:   
  51:                      }
  52:   
  53:                  }
(SiteSectionTaxonomy GUID,TermStoreguid,TermSetguid ) I have added these properties.
If you have any questions you can reach out our SharePoint Consulting team here.

January 7, 2013

Introduction to Content Query Webpart (Part 2)

  • Last week I have a blog post on the CQWP Add and configure in SharePoint 2010.
  • In this post I will provide you some basic idea about customizing the Item Style templates for the CQWP (Content Query Webpart).
  • Microsoft SharePoint Server 2010 includes three Extensible Style Language (XSL) files that you can modify to render fields in styles that the Content By Query Web Part uses to display the content it aggregates.
  • This topic identifies the three XSL files the Content By Query Web Part uses and describes how they work; identifies the templates and variables that you can modify; and describes how to modify the files so that the Content By Query Web Part renders data with the look and feel that you specify.
  • The following table lists and describes the three XSL files that describe the Content By Query Web Part.
File Location Description
ContentQueryMain.xsl \Style Library\XSL Style Sheets\ContentQueryMain.xsl
  • Contains logic that generates the appropriate calls to the Header and Item templates for each item.
  • Contains functions that help designers modify the Item and Header XSLT transforms.
  • Receives all the content, parses it, and sends appropriate pieces to the ItemStyle and Header templates.
  • Maintains the structure of the Content By Query Web Part.
  • Stores data retrieved when querying content in the path /dsQueryResponse/Rows/Row.
ItemStyle.xsl \Style Library\XSL Style Sheets\ItemStyle.xsl Contains templates that define how to display an item. These templates receive and process one row of data at a time, ensuring that the style and data in the item rows is consistent.
You can retrieve data about a row by using the @Property directive.
Header.xsl \Style Library\XSL Style Sheets\Header.xsl Contains templates that define how to display a header and ensure the consistency of group headers.
Templates specified in Header.xsl receive the next item row to process, usually the first row in a group unless there are multiple columns. If there are multiple columns, the templates receive the first row of the column.
You can retrieve data about the next item row by using the @Property directive. You can use the $Groupparameter that contains the groupby column name and the $GroupType that represents the column type of thegroupby column.
Now we need to customize the ItemStyle.xsl to include additional properties.
  • Open your root site in SharePoint Designer 2010. In the Navigation pane, go to All Files > XSL Style Sheets > ItemStyle.xsl. Right-click on ItemStyle.xsl and choose Edit File in Advanced Mode. Click yes at the prompt.
  • Make a backup of ItemStyle.xsl BEFORE you modify.
  • Since I'll likely want to modify the Calendar date field format, I've added the ddwrt namespace to the top of the stylesheet.
Here is Code : xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime
Here is a screen shot:

Now I need to create a template in ItemStyle.xsl which corresponds to the Item Style dropdown in the Web Part editor
1.To do so, copy the template style that most closely matches the style you're looking for e.g. "TitleOnly".
2.Paste this just above the "Hidden Slots" template (You can paste is anywhere in xsl).
3.Rename "TitleOnly" in both the template name and match="Row…" to a custom template name. In my case, I chose "Calendar".
4.Once again, this template name corresponds to the Item Style dropdown in the Web Part editor.
Here is my custom Calendar template:
In order for this style to show up in the options available to the CQWP, save and check in the ItemStyle. (I usually check in minor versions until I have completely finished creating the style template).

Apply the custom ItemStyle template


Go back to the page where you added the CQWP and make sure you're in Edit Page mode.
  • From the Web part menu, choose Edit Web Part.
  • Under Presentation > Styles, click the drop-down and select the new style you have created. Click Apply.
  • You should now see empty slots for Location and StartDate.
  • In the screen shots below, I verify the columns names: Location and Start Time from View Calendar Item (but you could find these other ways) and then add the SharePoint column names to the CQWP.

  • Notice how the Title slot needs Title [Custom Columns]; I still haven't quite figured out why that is, but I've run into the same situation with a few other fields so I just let SharePoint be SharePoint and continue on my merry way.
  • Once you completed these steps, click Apply and/or OK to save your web part modifications.
  • If you get a message "Unable to display this Web Part…." along with Correlation ID when you save the web part, something is wrong with the XSL that you've created. You will need to tweak it or remove it altogether and start over.

Apply the Filters in Content Query Web Part

  • By default, Content Query Web part comes with three filters
  • Once you've hit that limit – then you almost need to start all over again – using SharePoint Designer
  • BUT – there is a way you can include MORE filter criteria – and you don't have to change the other settings within the CQWP you've got in place – often important with regard to style/layout/etc.
Here are the steps to do it:
1.Edit Page > Export WebPart
2.Save it somewhere you'll remember – eg. SPR1.webpart
3.Open the file in Notepad – or within Visual Studio (easier to see/read)
You'll see the FILTER fields within there:
FilterField1, FilterField2, FilterField3
FilterDisplayValue1, FilterDisplayValue2, FilterDisplayValue3
FilterValue1, FilterValue2, FilterValue3
These will be populated depending on what you've chosen in the CQWP user interface (as above)
  • There is another property in there entitled: QueryOverride
  • This can be used to add MORE filters (where clause) and will be used instead of the 1,2,3 filters.
  • You just need to define the CAML to put inside the property – and then save the WEBPART.
  • Here's an example that I pieced together:
  •     <property name="QueryOverride" type="string"> 
           <![CDATA[<Where> 
                        <And> 
                          <And> 
                            <And> 
                              <Or Group="true"> 
                                <Leq> 
                                  <FieldRef Name="PublishingStartDate"/> 
                                  <Value Type="DateTime"> 
                                    <Today/> 
                                  </Value> 
                                </Leq> 
                                <IsNull> 
                                  <FieldRef Name="PublishingStartDate"/> 
                                </IsNull> 
                              </Or> 
                              <Or Group="true"> 
                                <Gt> 
                                  <FieldRef Name="PublishingExpirationDate"/> 
                                  <Value Type="DateTime"> 
                                    <Today/> 
                                  </Value> 
                                </Gt> 
                                <IsNull> 
                                  <FieldRef Name="PublishingExpirationDate"/> 
                                </IsNull> 
                              </Or> 
                            </And> 
                            <Eq> 
                              <FieldRef Name="Document_x0020_Type" /> 
                              <Value Type="Text">Notice</Value> 
                            </Eq> 
                          </And> 
                          <Eq> 
                            <FieldRef Name="Meeting_x0020_Category" /> 
                            <Value Type="Text">Board Meeting</Value> 
                          </Eq> 
                        </And> 
                    </Where> 
                    <OrderBy> 
                        <FieldRef Name='Created' Ascending='FALSE' /> 
                    </OrderBy> 
              ]]> 
        </property>
    It looks like a LOT – but it essentially does this:
    WHERE (PublishDate < TODAY or PublishDate = NULL) 
     
              AND (ExpiryDate > TODAY or ExpiryDate = NULL) 
     
                AND (Document Type = Notice) 
     
               AND (Meeting Category = Board Meeting) 
     
              ORDER BY Created DESC 
  • So – we can use that XML (CAML) within the CQWP webpart – by replacing the "QueryOverride" tag.
  • Next step is to copy that piece of XML into the .WEBPART file – and save it.
  • ** Note: Remember to include the CDATA tags – and also – ditch the original "QueryOverride" tag. Also – remember that the 1,2,3 filter values are now IGNORED – so you'll have to do it ALL in the CAML query.
  • 1.Edit Page
    2.Add WebPart
    3.Import WebPart > Browse
    4.Choose the file (.WEBPART)
    5.Click Upload
  • THEN – have to re-click the "Add WebPart" button and then you'll see it listed in the "Imported Web Parts"
    And – that's it – hopefully, it should be working OK.
    You can Filter CQWP Using Page Field value, Query String as Shown in Figure below:

    The key thing is to understand the token format:
    [PageFieldValue: ]
    PageFieldValue token will filter the items based on a current page's field value. The query above will fetch me all the items whose Staff Department is Photography (in this example) and adding Titlenot equal to current page's Title vale will eliminate the current item appearing in the results.
    If you want to use query string to filter the data then just use the PageQueryString instead

    Apply the Grouping and Sorting in Content Query Web Part


    In the Presentation tab you can Group and Sort items by the column name and also assign the sort order as Ascending or Descending. You can also limit the number of items to display for content query web p​art.

If you have any questions you can reach out our SharePoint Consulting team here.

October 22, 2012

How to use ASMX services in visual web part development

Use case:
Visual web part needs to fetch data from aspx web service. WSDL url is provided.
Service reference vs Code generation:
There are two ways to add reference to asmx services. You can directly right click the web part project and click on add service reference, click on advance and then choose asmx service reference.
Adding service reference will hard code the service url. So it is suggested that we use WSDL.exe available in .net framework tools to generate a client proxy.
How to use WSDL.exe to generate service proxy?
  1. Go to .net command prompt
  2. type wsdl /language:csharp /out:c\csfilename.cs
This will automatically generate the cs file provided in out paramter. Add the class to your web part folder and adjust the namespace.
Further Considerations:
  1. Url of the service should not be hard coded, it should be coming from web part property.
  2. To imlpement this, add a custom property in web part to store service url
  3. Add another paramterized constructor to the first class. See example below:
    Default constructor:
     public Spotlight()
            {
                this.Url = "web service url";
            }
    New constructor:
     public Spotlight(string _url)
    {
      this.Url = _url;
    }
  4. Generally the first class in wsdl generated proxy cs will be the one where you need to add the new constructor.
  5. You can confirm this by looking at the first class and it will be inheriting from
          "System.Web.Services.Protocols.SoapHttpClientProtocol" class.
  6. When web part property for service url is blank, use default constructor
  7. When web part property for service url is not blank use parameterized constructor.
  8. When your service will change, you have to repeat the process to generate proxy and add additional parameterized constructor
Other best practices:
  1. Always use proper error handling to make sure exceptions are not visible to end users
  2. Always show appropriate message in case of no data to users
  3. Always show appropriate message in case of error getting data from service
  4. Always use best practice to parse xml data.
  5. If possible use xml deserializers to convert xml data into List
Conclusion:
We find it very useful to use WSDL.exe to generate asmx proxy and using constructor injection to initialize the service url from web part property.

If you have any questions you can reach out our SharePoint Consulting team here.

Printing InfoPath Forms

Print option is normally not available as an option on Ribbon in InfoPath templates. So if one wants an option to “Print” InfoPath form then they can use the following steps below. Before starting off the InfoPath should be published as a Content type and a Page with InfoPath form Web Part must be created.
  • Open the Display Form web part page (make sure to select the correct content types if you have more than one....). You can do this by clicking Form Web Parts > (Content Type if you have several) Display Form
  • Edit the InfoPath Form Web Part. Set the Chrome to include just the Title.
  • Add a Content Editor Web part to the page. Set it to Hidden.
  • Add the JS from below link in the HTML source of the Content Editor Web part.
    https://www.nothingbutsharepoint.com/sites/eusp/Pages/jquery-for-everyone-print-any-web-part.aspx
  • Save the page.
You can now click the little icon (or you can modify the JS to insert a button to say 'Print Form') and the Print Preview of the Info Path web part gets opened, along with popup for setting printer options.
In the above JS script, the function “printWebPart” can be modified and replaced by the below script function

  printWebPart(tagid)
        {
            if (tagid)
                {
                    this.print();
                }
        }
 

This will directly open up the popup for setting printer options without showing the Print Preview.

If you have any questions you can reach out our SharePoint Consulting team here.

May 23, 2012

PowerGUI script editor: powershell debugging and intellisense

​​​In this post I am going to show you how to use PowerGUI script editor for executing sharepont2010 powershell. There are two main advantages of using PowerGUI:
  • Dubugging of powershell script
  • Intellisense support
So, let's start setting up PowerGUI to use with sharepoint 2010:
  • Download and install latest version of PowerGUI.
  • Download PowerGUI PowerPack for sharepoint.
  • Start PowerGUI script editor​ and go to File > Powershell Libraries
  • Click on "Add Module" and add downloaded "PowerPack for sharepoint" library here
  • That will add another entry "Microsoft.Sharepoint.PowerShell" into the listing. Check the library to make it enable
  • Restart PowerGUI script editor and you are ready to get started.
If you have any questions you can reach out our SharePoint Consulting team here.

April 30, 2012

Using HttpContext.GetGlobalResourceObject in webpart development

We found interesting issue during working with global resource files this week.

Problem:
Event if we are using HttpContext.GetGlobalResourceObject, web part was rendering data in English even if site language is other than English!

If we switch to edit mode, it was working sometime, but most of the time it was showing English text.

Root cause:
We tried creating a new application page and placed a webpart there, it was strange that it was working properly in the application page.

We finally found that at the time of reading resources through  HttpContext.GetGlobalResourceObject web part was not aware of the current UICulture

Solution:
Before:

   1:  var strLinkText = HttpContext.GetGlobalResourceObject("file", "key");
After:​

   1:  var strLinkText = HttpContext.GetGlobalResourceObject("file", "key",SPContext.Current.Web.UICulture);

Conclusion
Finally after passing third argument from SPContext.Current.Web.UICulture it worked properly
If you have any questions you can reach out our SharePoint Consulting team here.

April 9, 2012

Console application - accessing all webparts of a publishing page

Introduction:

Recently, we have been working on a sharepoint console app that finds invalid metadata terms assigned to web part properties. To get started we were trying to get all web parts on a publishing page.

Problem​:

There were several CQWP on page which were showing as error webparts when you get them using LimitedWebPartManager.

Solution:

Since CQWP and other publishing site web parts uses HttpContext.Current, we have to create a fake object in order to get it working properly. Here is the code that was included before GetLimitedWebPart call:


   1:  if (HttpContext.Current == null)
   2:  {
   3:  HttpRequest request = new HttpRequest("", web.Url, "");
   4:  HttpContext.Current = new HttpContext(request,
   5:  new HttpResponse(new StringWriter()));
   6:  HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
   7:  WindowsPrincipal wP = new WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent());
   8:  HttpContext.Current.User = Thread.CurrentPrincipal = wP;
   9:  }​
If you have any questions you can reach out our SharePoint Consulting team here.
Thanks​

April 6, 2012

Powershell: Get all web parts on a publishing page

There are lots of scripts available on web already for this. You must be wondering why am I posting this one?


When I tried various scripts on net to find web part on page, it gave me all content editor web parts on publishing page as error web part type.


After searching so much on internet I come through this link​ through which I was able to inspect correct type of web part. Here is the script:


[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("System.Xml")
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Taxonomy")


$site = new-object Microsoft.SharePoint.SPSite "http://br41:19685/products/a-z-product-list"
$web = $site.OpenWeb()
$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$pages = $pWeb.PagesList
$file=$web.GetFile("Pages/sas-pm.aspx")
if($file.Exists)
{
$manager = $file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);
$wps = $manager.webparts
$wps | select-object @{Expression={$pWeb.Url};Label=”Web URL”},@{Expression={$fileUrl};Label=”Page URL”}, DisplayTitle, IsVisible, @{Expression={$_.RepresentedWebPartType.Name};Label=”Type”}
}
else
{
Write-Host "page not found"
}


Happy powershell scripting

If you have any questions you can reach out our SharePoint Consulting team here.