Wednesday, December 17, 2014

How to remove language filter and Searh tip from an Advance Search Webpart of SharePoint 2010.

By default UI of a SharePoint Advance search Webpart is as follows :

However in so many scenarios we are not using other criteria except our Custom Manged Metadata properties. So in order to hide all these unwanted criteria, just add a content editor Webpart into this page and add below scripts :

<style type="text/css">

.ms-advsrchtips{
display:none;
}
TD.ms-advsrchText-v2 > SELECT[title='Result Type'] {
DISPLAY: none
}
TD.ms-advsrchText-v1 > LABEL[for*='_ASB_SS_rtlb'] {
DISPLAY: none
}
.bottom {
BORDER-BOTTOM: gray 2px solid; BORDER-LEFT: gray 2px solid; BORDER-TOP: gray 2px solid; BORDER-RIGHT: gray 2px solid
}
.box {
BORDER-BOTTOM: medium none; BORDER-LEFT: gray 2px solid; BORDER-TOP: gray 2px solid; BORDER-RIGHT: gray 2px solid
}
.box H2 {
PADDING-BOTTOM: 10px; BACKGROUND-COLOR: gray; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; COLOR: white; PADDING-TOP: 10px
}
.box DIV {
COLOR: #333
}
.box {
-moz-border-radius-topright: 5px; -moz-border-radius-topleft: 5px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px
}</style><script language="javascript" src="/sites/IAIC/Style%20Library/CPA/jquery-1.8.1.min.js"></script><script language="javascript" type="text/javascript">

ExecuteOrDelayUntilScriptLoaded(function () {

$(".srch-advancedtable").wrap("<div class='content'></div>");$(".content").wrap("<div class='box'></div>").before($('content'), "<h2>Search Client Data Here</h2>");;$(".content").after('<div class="bottom"></div>'); 
    }, 'sp.js');</script>

After adding above script. Advance Search Webpart will look like below :



Thursday, November 27, 2014

Linq to filter items based on different conditions from your own custom class in C#

This is a demo that how can we store and process a set of records using Linq and our custom class. Here I have created a class for storing information. Then processed it using Linq. Here is the code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqLearning
{
    class Program
    {
        static void Main(string[] args)
        {

            IANameAndID obj1 = new IANameAndID("Maah", 1, "exit");
            IANameAndID obj2 = new IANameAndID("Krishna", 2, "exit");
            IANameAndID obj3 = new IANameAndID("Krishna", 3, "reduced");
            IANameAndID obj4 = new IANameAndID("Pawan", 4, "exit");
            IANameAndID obj5 = new IANameAndID("Pawan", 5, "exit");
            List<IANameAndID> col = new List<IANameAndID>();
            col.Add(obj1);
            col.Add(obj2);
            col.Add(obj3);
            col.Add(obj4);
            col.Add(obj5);

            Console.WriteLine(GetAgentDetailsFromCollection("Karan"," ", col));
            Console.WriteLine(GetAgentDetailsFromCollection("Krishna", "exit", col));
            Console.WriteLine(GetAgentDetailsFromCollection("Krishna", "ghbfjsevbjh", col));

            Console.ReadLine();
        }
        
        

        private static string GetAgentDetailsFromCollection(string strIAName, string strDataResponsibility, List<IANameAndID> objCol)
        {
            string objAgentLookup = null;

            IEnumerable<IANameAndID> selectedCollection = new List<IANameAndID>();

            if (objCol != null && objCol.Count > 0)
            {
                
                if (strIAName.Equals("Karan"))
                {
                    selectedCollection = from item in objCol
                                         where item.IAName.Equals("Maah")
                                         select item;
                    if (selectedCollection.Count() == 1)
                    {
                        objAgentLookup = selectedCollection.FirstOrDefault().ID + selectedCollection.FirstOrDefault().IAName;
                    }

                }
                else
                {

                    selectedCollection = from item in objCol
                                         where item.IAName.Equals(strIAName)
                                         select item;
                    int Count = selectedCollection.Count();
                    if (selectedCollection.Count() == 1)
                    {
                       objAgentLookup  = selectedCollection.FirstOrDefault().ID + selectedCollection.FirstOrDefault().IAName;
                    }
                    else if (selectedCollection.Count() == 2)
                    {
                        var subselectedCollection = from item in selectedCollection
                                                    where item.TypeofProject.ToLower().Contains("exit") && strDataResponsibility.ToLower().Contains("exit")
                                                    select item;
                        if (subselectedCollection.Count() == 1)
                        {
                            objAgentLookup = subselectedCollection.FirstOrDefault().ID + subselectedCollection.FirstOrDefault().IAName;
                        }
                        else
                        {
                            objAgentLookup = selectedCollection.LastOrDefault().ID + selectedCollection.LastOrDefault().IAName;
                        }
                    }
                    else
                    {
                        var innerselectedCollection = from item in objCol
                                                      where item.IAName.Equals("No Agent Assinged")
                                                      select item;
                        if (innerselectedCollection.Count() == 1)
                        {
                            objAgentLookup = innerselectedCollection.FirstOrDefault().ID + innerselectedCollection.FirstOrDefault().IAName;
                        }
                    }
                }

                
            }

            return objAgentLookup;

        }

        public class IANameAndID
        {
            public string IAName { get; set; }

            public int ID { get; set; }

            public string TypeofProject { get; set; }

            public IANameAndID(string strName, int intID, string strTypeofProject)
            {
                IAName = strName;
                ID = intID;
                TypeofProject = strTypeofProject;

            }
        }
    
    }
}

Friday, November 14, 2014

How to programmatically change value of a People Picker field or any other field through C# code in Infopath Form Library.

For Simple we can do it without using any namespace just with filed names :

private static void WithoutNameSpace(SPListItem objSPListItem)
        {
                            XmlDocument xml = new XmlDocument();

                            //Open XML file and load it into XML document
                            using (Stream s = objSPListItem.File.OpenBinaryStream())
                            {
                                xml.Load(s);
                            }

                            //Do your stuff with xml here. This is just an example of setting a field
                            Console.WriteLine(xml.InnerXml);

                            
                            XmlNodeList nodes = xml.GetElementsByTagName("my:IPCountry");
                            foreach (XmlNode node in nodes)
                            {
                                Console.WriteLine("Got value.." + node.InnerText);
                                node.InnerText = "Ireland";
                            }
                                
                            //Get binary data for new XML
                            byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xml.OuterXml);

                            using (MemoryStream ms = new MemoryStream(xmlData))
                            {
                                //Write data to SharePoint XML file
                                objSPListItem.File.SaveBinary(ms);
                            }
                            Console.WriteLine("Changes Saved");
                            Console.Read();
        }

For special type of fields like people picker first get the namespace that field and then set each attribute inside that field.

private static void WithNameSpaceApproach(SPList objSPListParent)
        {
            SPFile spf;
            XmlDocument doc;
            XmlNamespaceManager nsm;
            SPListItem itm = objSPListParent.GetItemById(6);
            spf = itm.File;
            try
            {

                doc = new XmlDocument();
                doc.Load(spf.OpenBinaryStream());
                nsm = new XmlNamespaceManager(doc.NameTable);
                foreach (XmlAttribute att in doc.DocumentElement.Attributes)
                {
                    if (att.Prefix == "xmlns")
                    {
                        nsm.AddNamespace(att.LocalName, att.Value);
                    }
                }
//Print all the old values..
                Console.WriteLine(doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:AccountId", nsm).InnerText.ToString());
                Console.WriteLine(doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:DisplayName", nsm).InnerText.ToString());
                Console.WriteLine(doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:AccountType", nsm).InnerText.ToString());
                spf.CheckOut();
                doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:AccountId", nsm).InnerText = @"INT\IJohnson";
                doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:DisplayName", nsm).InnerText = "Ian Johnson";
                doc.SelectSingleNode("//my:ResponsiblePerson" + "/pc:Person/pc:AccountType", nsm).InnerText = "User";
                spf.SaveBinary(new MemoryStream(Encoding.UTF8.GetBytes(doc.OuterXml)));
                spf.CheckIn("Updated by the UpdateInfoPathItems utility!");
                Console.WriteLine("Updated...");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                spf.CheckIn("Updated by the UpdateInfoPathItems utility!");

            }
        }

Wednesday, November 5, 2014

Breaking Item level Permission on ItemAdded and Add a Specific Group (Permission) for item

Here is the code for breaking permission for an item, whenever Items get added. And you can also add any group or permission as per your need. It can be very useful at times :

using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;

namespace DemoByKrishna.BreakItemLevelPermisiion
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class DocReadAccessEventReceiver : SPItemEventReceiver
    {
        /// <summary>
        /// An item was added.
        /// </summary>
        public override void ItemAdded(SPItemEventProperties properties)
        {
            this.EventFiringEnabled = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                try
                {
                    using (SPSite site = new SPSite(properties.SiteId))
                    {
                        using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))
                        {
                            //SPList list = properties.List;
                            //SPListItem item = properties.ListItem;
                            SPListItem item = web.Lists[properties.ListId].GetItemById(properties.ListItem.ID);


                            web.AllowUnsafeUpdates = true;

                            item.BreakRoleInheritance(false);
                            string Group = "Viewers";
                            SPPrincipal cxosGroupUserGroup = FindUserOrSiteGroup(site, Group);
                            SPRoleDefinitionCollection GroupRole = web.RoleDefinitions;
                            SPRoleAssignment GroupRoleAssign = new SPRoleAssignment(cxosGroupUserGroup); 
                            cxosGroupRoleAssign.RoleDefinitionBindings.Add(cxosGroupRole["Read"]);
                            item.RoleAssignments.Add(GroupRoleAssign);

                            item.Update();
                        }
                    }
                }
                catch (Exception ex)
                {
                    properties.Status = SPEventReceiverStatus.CancelWithError;
                    properties.ErrorMessage = ex.Message;
                    properties.Cancel = true;
                }
            });
            this.EventFiringEnabled = true;

        }

        private static SPPrincipal FindUserOrSiteGroup(SPSite site, string userOrGroup)
        {
            SPPrincipal myUser = null;


            if (SPUtility.IsLoginValid(site, userOrGroup))
            {
                myUser = site.RootWeb.EnsureUser(userOrGroup);
            }
            else
            {
                foreach (SPGroup g in site.RootWeb.SiteGroups)
                {
                    if (g.Name.ToUpper(System.Globalization.CultureInfo.InvariantCulture) == userOrGroup.ToUpper(System.Globalization.CultureInfo.InvariantCulture))
                    {
                        myUser = g;
                        break;
                    }
                }
            }
            return myUser;


        }

    }
}

Monday, July 14, 2014

Logging in SharePoint 2010 Custom Applications using SharePoint SPDiagnosticsServiceBase Class.

In SharePoint 2010 we have a very easy way to log errors in default SharePoint Log at "14\Log" folder by default. However if you are not able to view it here you can check Central Administrator --> Monitoring -->
Configure Diagonistic Logging -->Trace Log. Here is the code for :

Add  a class file into your project and then paste below code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Runtime.InteropServices;


namespace LoggingServiceExample
{
    public class LoggingService : SPDiagnosticsServiceBase
    {
        public static string vsDiagnosticAreaName = "SharePoint Logging Service";
        public static string CategoryName = "SharePointProject";
        public static uint uintEventID = 700; // Event ID
        private static LoggingService _Current;
        public static LoggingService Current
        {
            get
            {
                if (_Current == null)
                {
                    _Current = new LoggingService();
                }
                return _Current;
            }
        }
        private LoggingService()
            : base("SharePoint Logging Service", SPFarm.Local)
        { }
        protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
        {
            List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>
                 {
                  new SPDiagnosticsArea(vsDiagnosticAreaName, new List<SPDiagnosticsCategory>
                   {
                    new SPDiagnosticsCategory(CategoryName, TraceSeverity.Medium, EventSeverity.Error)
                   })
                  };
            return areas;
        }
        public static string LogErrorInULS(string errorMessage)
        {
            string strExecutionResult = "Message Not Logged in ULS. ";
            try
            {
                SPDiagnosticsCategory category = LoggingService.Current.Areas[vsDiagnosticAreaName].Categories[CategoryName];
                LoggingService.Current.WriteTrace(uintEventID, category, TraceSeverity.Unexpected, errorMessage);
                strExecutionResult = "Message Logged";
            }
            catch (Exception ex)
            {
                strExecutionResult += ex.Message;
            }
            return strExecutionResult;
        }
        public static string LogErrorInULS(string errorMessage, TraceSeverity tsSeverity)
        {
            string strExecutionResult = "Message Not Logged in ULS. ";
            try
            {
                SPDiagnosticsCategory category = LoggingService.Current.Areas[vsDiagnosticAreaName].Categories[CategoryName];
                LoggingService.Current.WriteTrace(uintEventID, category, tsSeverity, errorMessage);
                strExecutionResult = "Message Logged";
            }
            catch (Exception ex)
            {
                strExecutionResult += ex.Message;
            }
            return strExecutionResult;
        }
    }
}

You just need to call following code on each entry points for any custom component :

try
{
            
}
catch(Exception ex)
 {
LoggingService.LogErrorInULS("Custom SharePoint Application exception at " + System.DateTime.Now + "Exception Message : "+ ex.Message.ToString() +" Exception Stacktrace : "+ ex.StackTrace.ToString());
}

Hope it helps..!!

Wednesday, July 9, 2014

How to create cascaded drop down using Client Side Object Model in SharePoint 2010 or above.

When we are trying to cascade drop-downs usually we use server side cascading which causes Post back and reload of controls View-state. Which leads to reset of fields to avoid it we used to use update panel. So instead of doing it we can use client side ECMA Script to get these values. It will make it more user friendly.

Here I am considering we have drop-down list bound from a list which works as a Parent List for second drop-down with a look-up column. We will call these methods on the first  drop-down change event :

function getDocumentType(index, sourceColumn, listName) {
        // get the list by it's name from the root site level
        var Query = '<View><Query><Where><Eq><FieldRef Name="' + sourceColumn + '" LookupId="TRUE"/><Value Type="Lookup">' + index + '</Value></Eq></Where></Query></View>';
        // Get the current client context to start. Most things run from the client context.
        clientContext = new SP.ClientContext.get_current();
        var myList = clientContext.get_site().get_rootWeb().get_lists().getByTitle(listName);
        // use a standard syntax CAML query to filter your results and the fields returned if required, by adding the following, or passing parameters to the load command below
        var query = new SP.CamlQuery();
        // You can leave out this line if you just want to return the entire list.
        query.set_viewXml(Query);
        // add your query to the getItems command for your list
        this.collListItems = myList.getItems(query);
        // issue the load command, these can be batched for multiple operations
        clientContext.load(collListItems);
        // execute the actual query against the server, and pass the objects we have created to either a success or failure function
        clientContext.executeQueryAsync(Function.createDelegate(this, this.mySuccessFunction), Function.createDelegate(this, this.myFailFunction));
    }


    function mySuccessFunction() {
        var destDropDown= this.document.getElementById('<%=ddChild.ClientID%>');
        destDropDown.options.length = 0;
        var listItemEnumerator = this.collListItems.getEnumerator();
        var count = this.collListItems.get_count();
        destDropDown.options[destDropDown.options.length] = new Option("-Select-", "0");
        if (count != 0) {
            while (listItemEnumerator.moveNext()) {
                var currentItem = listItemEnumerator.get_current();
                destDropDown.options[destDropDown.options.length] = new Option(currentItem.get_item(destColumn).get_lookupValue(), currentItem.get_item(destColumn).get_lookupId());

            }
        }
    }

    function myFailFunction() {
        alert("Error: Failed to fetch items. Please contact your Administrator.");
        // do something to alert the user as to the error here.
    } 

We can make these function generic for multiple level of cascading.

Thursday, February 6, 2014

How can you use PortalSiteMapProvider to query SharePoint List Items. Through Console or Webparts.

Sometimes we need to query some Items from a SharePoint List which data is not changing so frequently. In this case we need to add values of these list Items into cache. For that we need to add it manually to our cache. And also need to add an event receiver in case of any change in data to refresh cache. However SharePoint provides  "PortalSiteMapProvider" class to load this set of queried items in cache and refresh in case of changes. Here is the way to use this, hope it helps :

For a console application as we will not get HttpContext. So we need to create one as highlighted part otherwise you will get PortalWebSiteMapNode object null :

public static void GetConfigListItemsThroughConsole(string strValue1, string strValue2)
        {
            try
            {
                // Get the current SPWeb object. 
                using (SPSite objSPSite = new SPSite("http://servername:portno/sites/sitename"))
                {
                    using (SPWeb curWeb = objSPSite.OpenWeb())
                    {

                        // Create the query. 
                        SPQuery curQry = new SPQuery();
                        curQry.Query = string.Format("<Where><And><Eq><FieldRef Name='Column1' /><Value Type='Text'>{0}</Value></Eq><Eq><FieldRef Name='Column2' /><Value Type='Text'>{1}</Value></Eq></And></Where>", strValue1, strValue2);

                        // Create an instance of PortalSiteMapProvider. 
                        PortalSiteMapProvider ps = PortalSiteMapProvider.WebSiteMapProvider;

                        if (HttpContext.Current == null)
                        {
                            HttpRequest request = new HttpRequest("", curWeb.Url, "");
                            HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
                            HttpContext.Current.Items["HttpHandlerSPWeb"] = curWeb;
                        }
                        SPWeb curWeb2 = SPControl.GetContextWeb(HttpContext.Current);

                        PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb2.ServerRelativeUrl) as PortalWebSiteMapNode;
                       
                        // Retrieve the items. 

                        SiteMapNodeCollection pItems = ps.GetCachedListItemsByQuery(pNode, "ListName", curQry, curWeb);

                        // Enumerate through all of the matches. 
                        foreach (PortalListItemSiteMapNode pItem in pItems)
                        {
                            Console.WriteLine(Convert.ToString(pItem["Title"]));
                            Console.ReadLine();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occured :" + ex.Message.ToString());
                Console.ReadLine();
            }

        }
Just call this method from any windows or console application event.

Now, For a SharePoint as we will have HttpContext here :

public static string GetConfigListItemsThroughWP(string strValue1, string strValue2)
       {
           string resultValue = string.Empty;
           try
           {
              
               // Get the current SPWeb object. 
               SPWeb curWeb = SPControl.GetContextWeb(HttpContext.Current); 


                       // Create the query. 
                       SPQuery curQry = new SPQuery();
                       curQry.Query = string.Format("<Where><And><Eq><FieldRef Name='Column1' /><Value Type='Text'>{0}</Value></Eq><Eq><FieldRef Name='Column2' /><Value Type='Text'>{1}</Value></Eq></And></Where>", strValue1, strValue2);

                       // Create an instance of PortalSiteMapProvider. 
                       PortalSiteMapProvider ps = PortalSiteMapProvider.WebSiteMapProvider;

                       //PortalSiteMapProvider ps = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode;

                      
                       PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb.ServerRelativeUrl) as PortalWebSiteMapNode;
                       //PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb.Url) as PortalWebSiteMapNode;
                       // Retrieve the items. 

                       System.Web.SiteMapNodeCollection pItems = ps.GetCachedListItemsByQuery(pNode, "ListName", curQry, curWeb);

                       // Enumerate through all of the matches. 
                       foreach (PortalListItemSiteMapNode pItem in pItems)
                           {
                              resultValue =  Convert.ToString(pItem["Title"]);
                           
                           }
                       }
                       catch (Exception ex)
                       {
               
                       }
           return resultValue;

       }

Here we do not need to create a HttpContext, all we need to do to call this method from any webpart/SharePoint event. 

Friday, January 10, 2014

Easiest way to get query string parameters value in JavaScript in Sharepoint.

As a developer we need to get QueryString parameter values so many times. For this simple requirement we end up using some JQuery Library only for this purpose or writing lot of code in JavaScript. Here is good news for SharePoint developer. "JSRequest" class is available in SharePoint to get QueryString parameter value without any fuss.

Here is the way to use it :

/*Call EnsureSetup method to initialize JavaScript*/
JSRequest.EnsureSetup();
/*Suppose your site url is <siteurl>?param1=value1&param2=value2*/
var param1Value = JSRequest.QueryString["param1"];
var param2Value = JSRequest.QueryString["param2"];

I am not 100% that it will work in all the version on SharePoint or not. But It will definitely work in SharePoint 2010 / 2013. This approach will save your effort, and time. Also it will reduce the chance of bug injection.