Friday, November 3, 2017

Events Summary listing for homepage- JavaScript-based





We often display key events in the Home page of SharePoint site. The source calendar may not from the same site and we may need to pull data from the different site. I wrote a simple JavaScript-based events summary listing below. It is a quick and easy solution.

OutPut




Script


<!--Author : Sutha Thavaratnarajah 01/09/2017
* You may need to refer jQuery reference if it is not exisit in your site.
 -->
<script  src="https://code.jquery.com/jquery-3.2.1.min.js"   integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
 

<style>
.st-event-Day{
border: 1px solid black;
float:left;
margin:5px;
}

.st-event-month{
font-size:14px;
padding:5px 10px 2px 10px;
}
.st-event-singleDay{
font-size:16px;
font-weight: bold;
padding:2px 10px 2px 10px;
}
.st-event-details{
margin:5px;
}
.st-event-card-title{

}
.st-event-dard-datetime{

}
</style>
<script type="text/javascript">

var siteUrl = 'https://infoleadsolution.sharepoint.com/sites/demo2';

varItemViewURL = 'https://infoleadsolution.sharepoint.com/sites/demo2/Lists/MyCalander/DispForm.aspx?ID=';

var month_name = function(dt){
mlist = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
  return mlist[dt.getMonth()];
};

$(document).ready(function() {

ExecuteOrDelayUntilScriptLoaded(retrieveListItems, "sp.js");
  
 } );
    
    
function retrieveListItems() {

    var clientContext = new SP.ClientContext(siteUrl);
    var oList = clientContext.get_web().get_lists().getByTitle('MyCalander');
        
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><OrderBy><FieldRef Name="Created" Ascending="false" /></OrderBy></Query><RowLimit>5</RowLimit></View>'); // change what ever filter you neeed.
    this.collListItem = oList.getItems(camlQuery);
        
     clientContext.load(collListItem, 'Include(ID,Title,EventDate)');
        
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));        
        
}
function onQuerySucceeded(sender, args) {

    var listItemEnumerator = collListItem.getEnumerator();
         var Title = "";
   var eventDate = new Date();
   var eventID = 0;
   var itemURL ="";
   var content ="";
   eventMonth = "";
   eventDay = "";
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
  
        eventID = oListItem.get_item('ID') ;
  Title = oListItem.get_item('Title') ;
  itemURL =varItemViewURL + eventID ;
  eventDate = (oListItem.get_item('EventDate')).toDateString('dd/MM/yyyy hh:mm'); //dateformating 
  //eventMonth=(oListItem.get_item('EventDate')).toDateString('MMM');
  eventMonth = month_name(new Date(oListItem.get_item('EventDate')));
  eventDay=oListItem.get_item('EventDate').getDate();
  //content += "<tr><td><b><a href='"+ itemURL + "'>" +  Title + "'</a></b><br>" +   eventDate + "<br><br></td></tr>";
  
  content +=  "<div style ='overflow: hidden;'>";
  content += "<div class='st-event-Day'>";
  content += "<div class='st-event-month'>"+ eventMonth +"</div>";
  content += "<div class='st-event-singleDay'>" + eventDay +"</div>";
  content += "</div>";
  content +=  "<div class='st-event-details'>";
  content += "<div  class='st-event-card-title'><a href='"+ itemURL + "'>" +  Title + "'</a></div>";
  content += "<div class='st-event-dard-datetime'>" +   eventDate + "</div>";
  content += "</div>";
  content += "</div>";
    
    }
     $(content).appendTo("#here_table");
}
function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
                       
</script>

<div>   
<div id="here_table"></div>
</div> 

Tuesday, September 19, 2017

Nintex Repeating Section Date/Time - Using in an email or a string builder





Problem

Date and Time often challenge in any development works, recently I experienced some challenges in Nintex repeating section.

Scenario:

I built a Nintex form with repeating sections which have a date and time field. The repeating section store the data in XML format.  A running workflow read the repeating section data to construct an email body.
 I queried the XML and try to store the values to workflow variables. Then I use a string builder to write the contents of my email. Everything went very well except the date. J

When I had a deeper look, I found-out Nintex write dates in MM/DD/YYYY format and my SharePoint environment in DD/MM/YYYY. Nintex has a detail explanation for that. You can find here. https://support.nintex.com/SharePoint/Forms/2016/Date_Format_in_XML_of_Repeating_Section_is_Always_MM%2F%2FDD%2F%2FYYYY_With_Query_XML_Workflow_Action

Solution

Query and store the date field value into text variable. Make sure return result as “Text”



Then, use “convert value” to another variable which is date time type variable.



You need to convert as follows.
Input-- > date-time variable – text type
Store in date time Variable – date time type
In advance – use the US culture. So that it will read the text field correctly. However, it will store as per your SharePoint regional settings.




Now, we can use the stored date time field in the string builder or in emails.

Thursday, July 27, 2017

locked for exclusive use- SharePoint file

In SharePoint Documents, sometimes we may experience the filed locked by error. In this post, I like to share my resolution for that.We might receive a message stating that file is locked for editing by another user, However, the locked by the user has no intention to lock the file. To release the document by scripting, I wrote the below script.

Please investigate the issue and then if it is appropriate, you shall use the script.

Script:

Release-FileLock


Wednesday, April 22, 2015

Timer Job to Start the workflow in a list

Recently, I had an interesting requirement. No of list contains items and they expire on certain dates and require to send reminders for each items.  Initially I thought to write a custom workflow and kick the workflow by the OOB expiration policy/information policy. However information policy check dates are above the specified date. Example: anything more than 7 years.  So if you set the workflow to kick, it’s going to kick again and again for any items which are more than 7 years. Especially you won’t prefer to send email more than once. So I come up with a timer job for that.
The timer job will read a central list, which has details of list that need to run the expire workflow, and then kick the workflow.
Here is the sample of that list.


Then I create a timer job.
Here is the code for that.

namespace SP.Sample.OnlineForms
{
    using System;
    using System.Collections.Generic;
    using System.Web;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Workflow;
    using Microsoft.SharePoint.WorkflowUtil;
    using Microsoft.SharePoint.Utilities;
    using System.Security.Permissions;
    using System.Text;
    using System.Collections.Specialized;

    public class SampleExpireAlertsTimerJob : SPJobDefinition
    {
        //SPWeb mySiteWeb;

        public SampleExpireAlertsTimerJob(SPWebApplication webApp)
            : base("Sample Expire Alerts", webApp, null, SPJobLockType.Job)
        {
            this.Title = "Sample Expire Alerts";
        }
        public SampleExpireAlertsTimerJob()
            : base()
        {
        }
        public override void Execute(Guid targetInstanceId)
        {
            string key = "TeamsRootSiteUrl";
            string TeamsRootSiteUrl = "";
            if (this.Properties.Contains(key))
            {
                TeamsRootSiteUrl = this.Properties[key].ToString();
               
            }

            if (!string.IsNullOrEmpty(TeamsRootSiteUrl))
            {

               

                using (SPSite site = new SPSite(TeamsRootSiteUrl))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPList list = web.Lists.TryGetList("SampleExpireAlerts");
                        SPQuery oQuery = new SPQuery();

                        oQuery.Query = string.Format(@"
                                                <OrderBy><FieldRef Name='ID' /></OrderBy>"
                                              );
                        SPListItemCollection collListItems = list.GetItems(oQuery);

                        foreach (SPListItem item in collListItems)
                        {
                            string weburl = item["WebURL"] as string;
                            string listName = item["ListName"] as string;
                            string dateFieldtoFilter = item["DateFieldtoFilter"] as string;
                            int daysToFilter = int.Parse(item["DaysToFilter"] as string);
                            string workflowName = item["WorkflowName"] as string;

                            StartAlertWorkFlow(weburl, listName, dateFieldtoFilter, daysToFilter, workflowName);

                        }
                    }
                }
            }
        }

        /// <summary>
        /// Send remainder and warning emails to the employees
        /// </summary>
        /// <param name="employeeName">Name of the employee ex: Sutha Thavaratnarajah</param>
        /// <param name="moduleName">Name of the module ex: conduct</param>
        /// <param name="TeamsRootSiteUrl"> Url retrived from the timer job property.</param>
        /// <param name="eid">email template ID.</param>
        public void StartAlertWorkFlow(string weburl, string listName, string dateFieldtoFilter, int daysToFilter, string workflowName)
        {
            using (SPSite SampleSite = new SPSite(weburl))
            {
                using (SPWeb SampleWeb = SampleSite.OpenWeb())
                {

                    SPList list = SampleWeb.Lists.TryGetList(listName);
                    SPQuery oQuery = new SPQuery();
                    //string userName = "Sutha Thavaratnarajah";
                    string datetofilter = System.DateTime.Today.AddDays(daysToFilter).ToString("yyyy-MM-dd");

                    oQuery.Query = string.Format(@"
                                                    <Where>
                                                      <Eq>
                                                         <FieldRef Name='{0}' />
                                                         <Value IncludeTimeValue='False' Type='DateTime'>{1}</Value>
                                                      </Eq>
                                                   </Where>", dateFieldtoFilter, datetofilter);
                    SPListItemCollection collListItems = list.GetItems(oQuery);
                    foreach (SPListItem item in collListItems)
                    {

                        item.Web.AllowUnsafeUpdates = true;
                        SPWorkflowManager workflowManager = item.Web.Site.WorkflowManager;
                        SPWorkflowAssociationCollection workflowAssociation = item.ContentType.WorkflowAssociations;
                        foreach (SPWorkflowAssociation Association in workflowAssociation)
                        {
                            if (Association.Name == workflowName)
                            {
                                workflowManager.StartWorkflow(item, Association, Association.AssociationData, true);
                                break;
                            }
                        }

                   

                    }
                  
                }
            }
        }
    }
}

So, this timer job will kick the specified workflow in specified List with the given criteria.


Note: you need to create the workflow in the target lists.

Thursday, January 8, 2015

Save site as template -SharePoint 2013

A small script to save as template for SharePoint 2013 sites. This script also handle publishing feature enabled sites. I wrote this script to save some time. Instead of click few places , just run the script. :)


param(
    [string] $url = $(throw "No URL! Usage: Save-SP13Template.ps1 [webURL] [FileName]"),
[string] $templateName = $(throw "No Template Name! Usage: Save-SP13Template.ps1 [webURL] [TemplateName]")
)

#-------------------------------------------------------------


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
function Save-SiteTemplate {

$Web=Get-SPWeb $url
$Web.SaveSiteAsTemplateEnabled = $true
$Web.Update()
$fileName =$templateName +".wsp"
$Web.SaveAsTemplate($fileName,$templateName,"Template Description",1)
}

Save-SiteTemplate

Office Integration with SharePoint 2010 in a virtualized environment




1 Office Integration required settings.

Office integration with SharePoint in a virtualized environment required few settings in the client computer. The settings natively configured by the office product such as MS word and excel. However, in a virtualized environment it may not exactly configured as in a normal client computer. Following settings can be verified if any issue with your office integration.

1.1 MS Office Trusted location

In office products such as word and excel, add the trusted locations.

http://*.yourcompany.com
https://*.yourcompany.com

1.2 AuthForwardServerList.

Set the SharePoint URLs to AuthForwardServerList.

1. Using RegEdit, navigate to the following key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters
2. Add a New Multi-String Vlaue (Edit > New).
3. Name it AuthForwardServerList and press Enter.
4. Set the value (Edit > Modify) to your FQDN. Or you can do something more comprehensive like http://*.yourcompany.com
https://*.yourcompany.com

1.3 Portal URL
This may change depend on the office version/Windows Client you are using. Pls translate to equivalent for the client windows OS and office suite.
HKEY_CURRENT_USER\Software\AppDataLow\Microsoft\Office\14.0\Common\Portal


1.4 SharePoint Shortcuts
SharePoint Shortcuts store in following location.
C:\Users\%user% \SharePoint Sites
Ex: C:\Users\sutha.thavaratnaraja\SharePoint Sites
If you use a virtualized (ex citirx) the profile location similar to this except “C:\users”
1.5 Outlook .pst File locaiton
Sharepoint .pst files store in following location.
C:\Users\%user% \AppData\Local\Microsoft\Outlook
Example:
C:\Users\myFirstName.LastName \AppData\Local\Microsoft\Outlook


We may need to configure the virtual environment to giving similar mechanism to store this file, so that outlook can connect SharePoint.

Monday, May 19, 2014

How to display survey questions directly links in another page.. (New, Resume)

I had a requirement to provide survey links in another page. It is difficult as it is requiring validating whether they already complete the survey or not. I have achieved this by creating an application page.
Here is a code for the application page 

protected void Page_Load(object sender, EventArgs e)
        {

            string siteURL = Request.QueryString["webURL"];  // the url 
            string listName = Request.QueryString["ListName"]; // name simlar to "1";
            string thankYouURL = Request.QueryString["thankYouURL"];

            using (SPSite site = new SPSite(siteURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    string userName = web.CurrentUser.Name;

                    SPList list = web.Lists.TryGetList(listName);
                    SPQuery query = new SPQuery();
                    query.Query = string.Format(
                                    @"<Where>
                                        <And>   
                                            <Eq><FieldRef Name='Completed' /><Value Type='Computed'>255</Value></Eq>
                                            <Eq><FieldRef Name='Author' /><Value Type='User'>{0}</Value></Eq>
                                        </And>
                                    </Where>", userName); // CAML Query 
                    SPListItemCollection listItems = list.GetItems(query);
                    if (listItems.Count > 0)
                    {
                        redirectionURL = list.DefaultEditFormUrl + "?ID=" + listItems[0].ID + "&IsDlg=1&Source=" + thankYouURL;
                    }
                    else
                    {
                        redirectionURL = list.DefaultNewFormUrl +  "&IsDlg=1&Source=" + thankYouURL;
                    }

                }

            }
            SPUtility.Redirect(redirectionURL, SPRedirectFlags.Default, System.Web.HttpContext.Current);
            //Response.Redirect(redirectionURL);

        }

Add the application page link on your page with appropriate query String, then job done.

ex:: http://yourSP/mdle1/_layouts/myApplication/SurveyRedirector.aspx?webURL=http://yourSP/sites/sample/myList&ListName=MyList&thankYouURL=welcome.aspx