Thursday, 25 June 2015

Nintex Form Reduce width of DateTime control

********************************
To reduce the width of DateTime control, go to Nintex Form Settings >> Custom CSS and add below 
.cu-date
{
width: 120px !important;
}

.cu-date input
{
width: 70px;
}

and add cu-date class to Date\Time control 

********************************

Nintex Forms show loading dialogue for required time

One of our Nintex Form has complex Javascript which queries web services and loads meta data. For this operation, the javascript runs for few seconds and we want user not
  1.  To start typing on any field of form or accessing the form before it loads all meta data
  2.  To complain that form is incomplete before it loads all meta data
For this we can add below Javascript to show loading animation to user so that user can wait without complaining. It gives better usability.

$(window).load(function () {

waitDialog = SP.UI.ModalDialog.showWaitScreenWithNoClose('   ', 'Please wait...', 110, 280);
   
setTimeout(function () {  
waitDialog.close();
    }, 5000);
});

JQuery has to be referenced in Nintex Form. It uses SharePoint's native modal dialog.

Nintex form is blank in browser

If Nintex form is not getting rendered, that is if browse shows white page instead of Nintex form, check for any javascript error using browser debugger.

Get Current Users Display name in ASP.Net Web application

To Get current user's display name without LDAP settings.


  public string HelloUser()
        {
            string dispName = "";
            Thread.GetDomain().SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
           
            using (System.Web.Hosting.HostingEnvironment.Impersonate())
            {
                WindowsPrincipal principal = (WindowsPrincipal)User;
                PrincipalContext pc = new PrincipalContext(ContextType.Domain); ;
                UserPrincipal up = UserPrincipal.FindByIdentity(pc, principal.Identity.Name);
                dispName = up.DisplayName;
                
            }            
            return "Hello - " + dispName + ", your login is " + HttpContext.Current.User.Identity.Name;
        }

Note: Make sure windows impersonation is turned on in IIS.

Saturday, 20 June 2015

SharePoint 2010 Visual WebPart gives 403 error to users

We have a Visual Webpart deployed to SharePoint 2010 with following key functionality
  1. Access SQL DB
  2. Access SP Groups to see if current user is part of few SP groups
This Web Part uses AJAX control toolkit.
Our SharePoint farms are scheduled to recycle App Pools over night.

Problem:
In the morning when a normal user access the page containing Visual Web Part, IE will show 403 error.
Once Site admin access the page the error will go away and normal users can access the page without any problem.

Solution:
·         Give Read permission for Everyone to \bin and \_app_bin folders
·         Copy AJAX Control toolkit dll to GAC
·         Add Authenticated users to group WSS_WPG

Friday, 19 June 2015

Prevent users from accessing All Items page of SharePoint 2010

In our SharePoint portal we show users only Nintex Forms (can be accessed by links in emails sent by Workflows) and few web part pages restricting access to default SharePoint pages like AllItems.aspx.

To achieve this 
1. Upload 
             jquery-1.8.3.min.js   and
             jquery.SPServices-0.7.2.min.js

to Site Assets library

2. Edit AllItems.aspx page (or any page you want to restrict access to normal users) and add below script. (Even if the user try to access the page with link, they will be redirected to home page).

<script type="text/javascript" src="/SiteAssets/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/SiteAssets/jquery.SPServices-0.7.2.min.js"></script>
<script type="text/javascript">
  $(document).ready(function() {$().SPServices({
      operation: "GetGroupCollectionFromUser",
      userLoginName: $().SPServices.SPGetCurrentUser(),
      async: false,
      completefunc: function(xData, Status) {
        if($(xData.responseXML).find("Group[Name='SiteAdmins']").length != 1) {
                                location.href = $().SPServices.SPGetCurrentSite();
                                 }
                      }
       });
});
</script>

After adding above script, only members of SiteAdmins can access that page, all other user will be redirected to home page.

Show 'Site Actions' ribbon menu only for SP Group members in SharePoint 2010

Step 1:
Create a SharePoint group 'SiteAdmins' at Site Collection level with Design and Contribute access

Step 2:
Add\Upload below 2 JS files to SiteAssets of root site
  1. jquery.SPServices-0.7.2.min.js
  2. jquery-1.8.3.min.js
Step 3: 
Refer above 2 JS in Master file.
Edit default Master page, find ‘<asp:ScriptManager’ under Form tag and replace(or include the script references) to include JQuery and SPServices scripts

 <asp:ScriptManager id="ScriptManager" runat="server" EnablePageMethods="false" EnablePartialRendering="true" EnableScriptGlobalization="false" EnableScriptLocalization="true" >
  <Scripts>                             
                                <asp:ScriptReference Path="<%$SPUrl:~SiteCollection/SiteAssets/jquery-1.8.3.min.js%>"></asp:ScriptReference>                         
                                <asp:ScriptReference Path="<%$SPUrl:~SiteCollection/SiteAssets/jquery.SPServices-0.7.2.min.js%>"></asp:ScriptReference>                               
                </Scripts>             
</asp:ScriptManager>

Step 4:
Hide ‘Site Actions’ and top ribbon for all users by default.
<!--<div id="s4-ribbonrow" class="s4-pr s4-ribbonrowhidetitle">-->
<div id="s4-ribbonrow" style="display: none;">

Step 5:
Include below script block before between </Body> and </HTML> to check if current user is member of 'SiteAdmins' group and display if yes.

<script type="text/javascript">
$(document).ready(function() {$().SPServices({
      operation: "GetGroupCollectionFromUser",
      userLoginName: $().SPServices.SPGetCurrentUser(),
      async: false,
      completefunc: function(xData, Status) {
        if($(xData.responseXML).find("Group[Name='SiteAdmins']").length == 1) {
$('#s4-ribbonrow').show();
}
      }
   });  
   });
</script>

Step 6 (Optional): If you want to display 'Welcome <current user>',  add wssuc:Welcome control (copy & paste) to some other location other than ribbon. 

Thats all, the Ribbon will be hidden for all users except for 'SiteAdmins' members. They have access to 'Site Actions' menu.

Thursday, 29 March 2012

ASP.NET Ajax client-side framework failed to load And\Or 'Sys' is undefined

My ASP.NET application with AJAX controls suddenly started giving script errors in IE8, but it worked perfectly alright in Chrome and Firefox.

Microsoft JScript runtime error: ASP.NET Ajax client-side framework failed to load.
Microsoft JScript runtime error: 'Sys' is undefined


The error was as below in VS.


 In IE8, you can notice the error at left corner of status bar.

Spent 2 days, tried all different option including

a) Modifying web.config
b) Enabling Javascript in IE
c) Restoring IE default settings
d) Removing and adding AjaxControlToolkit.dll in VS2008.
e) Adding axd extension in IIS.

But no luck. I even created new web application with one page and one AJAX control, the same error appeared when i hit F5 in VS2008. But i browse the page in Chrome or Firefox it worked like charm. That concluded me there was nothing wrong in my app.
Exisiting applications hosted in different server showed script error in my IE8 window but worked on others machine.

Atlast, found the solution at http://stackoverflow.com/a/8522460, thanks to Chris Hammond.

Solution is, this could be a caching/compression issue and by putting in the following into Web.Config, resolves the issue.

  <system.web.extensions>
    <scripting>
      <scriptResourceHandler enableCaching="false" enableCompression="false" />
    </scripting>
  </system.web.extensions>
     

Monday, 21 March 2011

Adding instance of WebUserControl to ASP.Net website project

It can easily be done using namespaces. Here's an example:




WebControl1.ascx:



Notice that Inherits references the namespace (MyUserControls), and not just the class name (WebControl1)



WebControl1.ascx.cs:



namespace MyUserControls { public partial class WebControl1 : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) { } } } Notice that the class have been included in the namespace MyUserControls



Default.aspx.cs:



using MyUserControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var control = (WebControl1) Page.LoadControl("~/WebControl1.ascx"); } } This approach potentially allow you to redistribute your user controls (or keep them in a separate project) without the hassle of referencing them in your .aspx files.

Tuesday, 1 March 2011

ASP.Net AJAX CalendarExtender - Get selected date from ReadOnly TextBox

In this article I will explain a very common issue faced while using the ASP.Net AJAX Control Toolkit CalendarExtender control.
Issue
Whenever for the ASP.Net Textbox if the ReadOnly property of the Textbox is set to true, the selected data is not available in the Text property of the Textbox on PostBack.

Reason

The reason behind this issue is that whenever value of an ASP.Net Textbox is set to ReadOnly and the value of the textbox is set client side using client side script like JavaScript, in such cases the value of the Textbox is not available in the Text property of the ASP.Net Textbox. The ASP.Net AJAX Control Toolkit CalendarExtender makes use of JavaScript to set the selected date in the Textbox.

Solution

The solution to the issue is making use of Request.Form collections. As this collection has values of all fields that are posted back to the server and also it has the values that are set using client side scripts like JavaScript.

Thus we need to do a small change in the way we are fetching the value server side.

C#

protected void Submit(object sender, EventArgs e)
{
string date = Request.Form[txtDate.UniqueID];
}

As you can see above I am fetching the value of the Textbox from the Request.Form collection using the UniqueID property of the Textbox which is nothing but Client Side name of the ASP.Net TextBox control
The screenshot below describes that the selected date value is now available server side when fetched using the Request.Form collection

Friday, 20 August 2010

Read Text value from ReadOnly TextBox

Some time we need to make textbox read-only for showing data. If we make textbox read-only at the designer setting as below, then the textbox always returns blank in the code behind.



Here I am giving you an example of the issue and the solution.
For date picker I used ASP.NET AJAX 's Calendar extender that can be attached to any ASP.NET TextBox control only. And in the textbox I don't want that user directly write any text.
For achieving this, if I make textbox read-only then at the server side textbox.text will come as blank(empty).
Solution




In code behind add an attribute.

txtDate.Attributes.Add("readonly", "readonly");

By doing this we can retrieve read-only textbox's value in the code behind.

Friday, 21 May 2010

Color coding List item based on date

We had a need to maintain a set of books as library. I decided to go with SharePoint list with 'Issued Date' as DateTime column and 'Due Date' column as calculated column (Issued Date + 14 days).
The formula for 'Due Date' is =[Issued Date]+14

Added one more column of type 'Yes\No' with name 'Returned' to note if the book has been returned or not.

Ok, now i have to display the row in yellow(or light pink) if today's date is just 3 days or less away from 'Due Date', make it red if today's date is 'Due Date' or crossed. All other rows in green.
To do this on client side, CEWP had to be added to the page as the last WebPart.
The script to check for the date and change the row color was

<script type="text/javascript">
// Change these variables to suit your needs
var green = 3; // Items this many days out will be green
var yellow = 1; // Items that are this many days or more are yellow

var tbls = document.getElementsByTagName("TABLE");
var col = new Array();
for (var t in tbls) {
if (tbls[t].className == "ms-listviewtable") {
var rows = tbls[t].childNodes[0].childNodes;
var hRow = rows[0].getElementsByTagName("TH");
for (i=0;i<hRow.length;i++) {
col[i] = (hRow[i].innerText || hRow[i].textContent) + "";
col[i] = col[i].replace(/n/,"");
}
for (r=1;r<rows.length;r++) {
for (c=0;c<col.length;c++) {
if ((col[c] == 'Due Date') && (rows[r].childNodes[c+1].innerText == 'No')) {
colorIt(rows[r],rows[r].childNodes[c],green,yellow);
}
}
}
}
}

function colorIt(row,x,green,yellow) {
var strDate = x.innerText || x.textContent;
var dt1 = parseInt(strDate.substring(0,2),10);
var mon1 = parseInt(strDate.substring(3,5),10);
var yr1 = parseInt(strDate.substring(6,10),10);
mon1 = mon1 - 1;

var startDate = new Date(yr1, mon1, dt1);
var today = new Date();
var toDate = new Date(today.getFullYear(), today.getMonth() , today.getDate());
var dateDiff = (startDate - toDate )/86400000;;

if (dateDiff > green) {
row.style.backgroundColor='#66FF99';
} else if (dateDiff >= yellow) {
row.style.backgroundColor='Pink';
}
else
{
row.style.backgroundColor='#CC0066';
}
}
</script>

Color Coded SharePoint Calendar

Once i had to give different color for the Calendar items. Below are the steps i followed

1. Created one Calculated Column with title 'ColorTitle'
2. Added the formula
="<div style='border: 1px solid #009933; padding: 3px; margin: 0px; background-color: #FFFFB0; color: #009933'>"&Title&"</div>"
3. Edited the default view as below
     a. Chose 'ColorTitle' for Month View Title
     b. Chose 'ColorTitle' for Week View Title


Saved the view. Thats all :)

Note: You can change the color based on a field value by slightly modifiying the formula.

Hide fields of SharePoint Calendar

I wanted a Calendar in my team site without fields 'Recurrence' and 'Workspace'. Since it was production server, i cannot do any custom coding, installation or configuration and even i cannot use any tool to tweak the fields.
So, the solution is to do with JavaScript + CEWP.
Go to the Display.aspx form and EditForm.aspx through an  item in calendar and bring the page into edit more to include the CEWP.

One trick to bring the Displayform or editform to edit mode, just append "toolpaneview=2" after ".aspx" in the address bar of browser
.......DisplayForm.aspx?toolpaneview=2 or
-----EditForm.aspx?toolpaneview=2

Add CEWP to the bottom of page. Add the following script to the CEWP

<script type="text/javascript">
var trs = document.getElementsByTagName("TR");</P><p>
for (var r in trs) {
var row = (trs[r].innerText
trs[r].textContent)+"";
if (row.match(/^Workspace/)) { trs[r].style.display = "none"; }
if (row.match(/^Recurrence/)) { trs[r].style.display = "none";}
}
</script>

Tuesday, 6 April 2010

Show traffic lights in SP List based on Checkbox(Yes\No) column

I had to create a SharePoint list with traffic lights as shown below.


The decision for color of traffic light is from a Checkbox field.

One calculated field for each traffic light has to be created with formula like
="< d i v >< i m g src="http://www.blogger.com/_layouts/images/KPIDefault-%22&IF([Gate%201]=TRUE,"0.GIF","2.GIF")&"" /> < / d i v >"

 

The idea is to use the existing SharePoint KPI images.

Since the formula is based on Checkbox, the following IF condition will work.
="< d i v >< i m g src="http://www.blogger.com/_layouts/images/KPIDefault-%22&IF([Gate%201]=TRUE,"0.GIF","2.GIF")&"" /> < / d i v >"
"


Did NOT work:
="< d i v >< i m g src="http://www.blogger.com/_layouts/images/KPIDefault-%22&IF([Gate%201]=Yes,"0.GIF","2.GIF")&"" /> < / d i v >"

="< d i v >< i m g src="http://www.blogger.com/_layouts/images/KPIDefault-%22&IF([Gate%201]=1,"0.GIF","2.GIF")&"" /> < / d i v >"


It will just set the HTML tags to the calculated field based on the checkbox value.
How to make the browser to interpret the HTML tags and display the image.

Here comes the handy script from http://blog.pathtosharepoint.com/2008/09/01/apply-color-coding-to-your-sharepoint-lists/

A CEWP has to be added at bottom of the page and include the following script in the CEWP, thats all.
It does magic for you...

< s c r i p t type="text/javascript">
//
// Text to HTML
// Feedback and questions: Christophe@PathToSharePoint.com
//
var theTDs = document.getElementsByTagName("TD");
var i=0;
var TDContent = " ";
while (i < theTDs.length) { try { TDContent = theTDs[i].innerText || theTDs[i].textContent; if ((TDContent.indexOf("") >= 0)) {
theTDs[i].innerHTML = TDContent;
}
}
catch(err){}
i=i+1;
}
//
// ExpGroupRenderData overwrites the default SharePoint function
// This part is needed for collapsed groupings
//
function ExpGroupRenderData(htmlToRender, groupName, isLoaded) {
var tbody=document.getElementById("tbod"+groupName+"_");
var wrapDiv=document.createElement("DIV");
wrapDiv.innerHTML="
<><><><>"+htmlToRender+"
";
var theTBODYTDs = wrapDiv.getElementsByTagName("TD"); var j=0; var TDContent = " ";
while (j < theTBODYTDs.length) { try { TDContent = theTBODYTDs[j].innerText || theTBODYTDs[j].textContent; if ((TDContent.indexOf("") >= 0)) {
theTBODYTDs[j].innerHTML = TDContent;
}
}
catch(err){}
j=j+1;
}
tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
}
< / s c r i p t >

Monday, 4 January 2010

ReportViewer in WebPart (SharePoint)

Using ReportViewer control inside SharePoint Webpart is bit tricky and challenging.
Below are the steps to make it happen.

1. web.config (of SharePoint) changes (Extra space has been included after > and < to make it appear in blog)

add below line to < httpHandlers > section

< add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" / >


and below line to < assemblies >

< add assembly="Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" / >

2. Add Report (.rdlc) and DataSet (.xsd) files to Solution


Sample Code

------------------------------------------------------------
using System;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.Reporting.WebForms;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;

namespace ReportWebpart
{
public class ReportsWP : WebPart
{
Label lblTime;
ReportViewer ReportViewer1;
TextBox tb1;
Button btn;

protected override void CreateChildControls()
{
base.CreateChildControls();
try
{
lblTime = new Label();
lblTime.Text = "Enter Plant No.";

tb1 = new TextBox();

btn = new Button();
btn.Text = "Refresh Report";
btn.Click += new EventHandler(btn_Click);

ReportViewer1 = new ReportViewer();
ReportViewer1.Width = Unit.Percentage(80);
ReportViewer1.EnableViewState = true;
ReportViewer1.LocalReport.ReportPath = @".\Report1.rdlc"; // Copy the rdlc file to root of IIS
ReportViewer1.ProcessingMode = ProcessingMode.Local;
ReportViewer1.ID = "rprtViewer1";

this.Controls.Add(lblTime);
this.Controls.Add(tb1);
this.Controls.Add(btn);
this.Controls.Add(ReportViewer1);
}
catch (Exception ex)
{
string k = ex.Message;
}
}

void btn_Click(object sender, EventArgs e)
{
DataTable newDT = GetTable();
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1_Employee", newDT));//Name of Dataset (.xsd file)+ '_' + table name
ReportViewer1.ID = "rprtViewer1";
ReportViewer1.DocumentMapCollapsed = true;
ReportViewer1.LocalReport.Refresh();
}

private DataTable GetTable()
{
//FRAME THE QUERY AS NEEDED. THE FIELDS RETURN SHOULD MATCH WITH REPORT'S DESIGN TIME FIELDS
}
}
}
----------------------------------------------------------

NOTE: If you are getting following error while accessing the WebPart page containing ReportViewer

Microsoft.SharePoint.Portal.Analytics.UI.ReportViewerMessages, Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c does not implement IReportViewerMessages or could not be found


Try either of following to fix it

1In web.config of SharePoint, comment the following line under
1. <appsettings >
< ! -- < add key="ReportViewerMessages" value="Microsoft.SharePoint.Portal.Analytics...... / > -- >

or

2.  Add  following to < appsettings >
< remove key="ReportViewerMessages" >


------------------------------------------------------

Tuesday, 22 December 2009

LinkButton in SharePoint - Not firing Click Event

I had a sitution to stream a file from SQL Server.
ASP.Net LinkButton was used in the ITemplate to use in GridView and Click event was defined with statements like

response.AddHeader("Content-Disposition", "attachment; filename=" + fileName );
response.AddHeader("Content-Length", blob.Length.ToString());
response.ContentType = "Application/x-msexcel";
response.BinaryWrite(blob);



Everything was working perfect in WebApplication. When the webpart was deployed to SharePoint, the server side click event fired only once. After that the link became irresponsive. If the page is refreshed, the link worked once again for 1st time.

After several googling, found that SharePoint stores time-stamp on client side for security reasons and avoids multiple post-backs for the same control.

There are 2 ways to over-come this issue. Just add an appropriate line as below

1. Generic way

imageButton.OnClientClick = "this.form.onsubmit = function() {return true;}";
or
hyperLink.OnClientClick = "this.form.onsubmit = function() {return true;}";
or
linkButton.OnClientClick = "document.getElementsByTagName(\'form\')[0].onsubmit = function() {return true;}";



2.Specific to SharePoint

linkButton.OnClientClick = "_spFormOnSubmitCalled = false;_spSuppressFormOnSubmitWrapper=true;";

After adding single line (one of the above), the webpart worked like a charm.

Friday, 18 September 2009

Read RSS and Atom feed in C#

I had a requirement to read RSS/Atom feeds from blogs and store in SharePoint List.
I remember we had to go for separate framework to read the feeds and parse it. In that case we need to refer the framework in our project and install that assembly in Bin or GAC.

Now with .Net 3.5, life has become much easier.

Yes, with the namespace 'System.ServiceModel.Syndication' it is just few lines of code to read and parse the feeds either RSS or Atom.

Just add reference to 'System.ServiceModel.Web' to your project and include above namespace in your class, thats it.

Below is the code i used.
XmlReader reader = XmlReader.Create(curUrl);
SyndicationFeed feed = SyndicationFeed.Load(reader);
string title = String.Empty;
string link = String.Emplty;
DateTime dateTime = null;
foreach (var feeditem in feed.Items)
{
title = feeditem.Title.Text;
dateTime = feeditem.PublishDate.LocalDateTime;
link = feeditem.Links[feeditem.Links.Count -1].Uri.OriginalString;

//Do your tasks here
}

Easy to deploy and maintain too.
Happy Coding
வாழ்க வளமுடன் :)

Useful SharePoint Links

Some Useful SharePoint links


Accessing Data from Workflow Association and Initiation Forms in Windows SharePoint Services 3.0
Best Practices: Common Coding Issues When Using the SharePoint Object Model
Best Practices: Using Disposable Windows SharePoint Services Objects
Checklist for Creating SharePoint Web Parts
Creating Custom Timer Jobs in Windows SharePoint Services 3.0
Creating a Windows SharePoint Services 3.0 Custom Field by Using the EntityPicker
Creating a Windows SharePoint Services 3.0 Web Part Using Visual Studio 2005 Extensions
Development Tools and Techniques for Working with Code in Windows SharePoint Services 3.0 (Part 1 of 2)
Development Tools and Techniques for Working with Code in Windows SharePoint Services 3.0 (Part 2 of 2)
Securing Application Pages in Windows SharePoint Services 3.0
Selective Content Migration in Windows SharePoint Services 3.0
Understanding and Creating Customized and Uncustomized Files in Windows SharePoint Services 3.0
Understanding the Administrative Object Model of Windows SharePoint Services 3.0
Usage Event Logging in Windows SharePoint Services 3.0
Using Solution Packages to Deploy Features and Content in Windows SharePoint Services 3.0
Workflow Scalability and Performance in Windows SharePoint Services 3.0
Working with ASP.NET 2.0 Web Parts and Windows SharePoint Services 3.0