Friday 25 June 2010

Open all anchor links in new window

I believe this post is going to be very interesting to many people who read this post. Because the first question is what is the need to open links in new window? Is it a big deal to open links in new window? What are the advantages? Why we need to implement this in our sites or blogs?

Take my blog for example.  I have write big posts some times and place more links. I want the user to see the links to be opened in new windows as they are still reading my pages. If the link opened in the same page, then it will be a problem to go and come back and start reading from the position they were. That won't give good experience. I want them to be stayed on my blog page and open all the links in new window. So that user is always on my blog page and if they wants then they can move across pages. It's not bad at all.

How many ways are there to implement this?
1. Make all links in web page open in new window.
2. Only some part of the web page links will be opened in new window.

I have two options: Number 1,
Open all links on the web page in new window: Default HTML supports this.
Work around:
Add this line in the <head> tag of your HTML:  <base target='_blank' />

If I make all links needs to be opened in new window then home link, navigation links, search everything will opened in new window and it will frustrate user that whatever you click on the link it will open in new window. Dozens of windows in user system if you click 10-12 links. Not a good idea.

Option 2: Only specific region anchor links open in new window. This looks promising and good. But, how to. For example, in my blog, I like to open the content links only in new window.
I have a parent for all content inside a div with id='content'. Now, my goal is to add some logic to open all links in new window which are under content only.
Work around:
Add the below javascript to the <head> tag of the HTML.
<script type='text/javascript'>
//<![CDATA[  
window.onload = function () {
        var links = document.getElementById('content').getElementsByTagName('a');
        for (var i = 0; i < links.length; i++) {
            links[i].setAttribute('target', '_blank');
        }
    }
//]]>
</script>

This small function will do the trick. So, on window load, we are finding all the links in the particular division then adding the target='_blank' attribute to it. So, I found this is the only best solution to achieve this.
Once you add this to your page, then you will see all links inside content will open in new window and all others in the same window. This working perfectly to me. Try it on my blog by clicking on some link in the content.

If you are Jquery lover, then this is JQuery version,
$('#content a[href^="http://"]').attr("target", "_blank");

Great advantage is for blogs. All blogs needs this as there are lot of external links and other links in content. This will be the best and suitable solution.

Wednesday 23 June 2010

ULS Viewer - SharePoint Log Viewer - A nice SharePoint Tool

In SharePoint, I know the big pain in development is if we get any exceptions or errors in the code we have implemented, then go back to log files and scroll or search to the exception or error details and try to solve it. The notepad file size could be in MB's. It's difficult to maintain and see what was caused the problem very easily. Most of times it frustrates to search and find the corresponding problem as notepad is very slow if log file size is huge. I am always think like, is there any better way to see and find the details without struggling a lot. One way I found was my previous post "How to see actual exception and errors directly on SharePoint web page". But, that won't help always to find the problem.

That is the reason I started to find a good solution for it. Luckily Microsoft understand this and developed a nice tool for us. That is called ULS Viewer. This is the windows application which takes the ULS log file as input and loads the log files very faster than notepad and shows us as grid of columns. You can do plenty of customization to it by sorting, filtering, searching, highlighting etc... You can find the problems in your code in very less time. I find this is one of great and superb tools every SharePoint developer should use. It surely decrease the analysis time on finding exception or error details.

For more details about the ULS Viewer: http://code.msdn.microsoft.com/ULSViewer
For free download: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=ULSViewer&DownloadId=7482

For complete documentation: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=ULSViewer&DownloadId=7483

So, use it and make your life more comfortable. Subscribe to all my posts and stay with me. I always try to share and help the devs to make development faster with the already existing tools. But, the things is we need to know about them, I will do that part for you. Happy SharePoint development.

Tuesday 22 June 2010

SharePoint 2010 ECMAScript Intellisense in Visual Studio 2010

This post is a very big help to the SharePoint 2010 developers. We need the intellisense help to write code fast in our SharePoint applications. But, in SP2010 BETA I faced so many problems to find what methods a java script object has. After written a long post on how to get the java script intellisense working in Visual Studio 2008 this is now an easy for me to do the same on Visual Studio 2010. I just tried the same implementation in VS 2010 and that worked great. So, there I started and started using it in ECMAScript development. When I first see the intellisense working in VS 2010 felt very very happy and jumped into the air. Because, before to find the same methods in the ECMAScript object, I had wasted hours and hours. One of the example is this post "How to know all methods in SP object".

Solution:
By using reference tag everything possible.

  1. Create a js file in VS2010.
  2. Add the below script as the first line. /// <reference name="MicrosoftAjax.js" />
  3. The MicrosoftAjax.js reference should be in the first line. What is it? why it is needed? I know the question are always in mind... This is the default js files which comes with visual studio. It has all the default methods for Sys.* available. More details here. "Make sure any dependencies are taken into account in the order of declarations. Most of the time, you will want "MicrosoftAjax.js" to be on the top." Some of the SP objects depends on this file.
  4. Now, it's time to link SharePoint ECMAScript java script files linking. We need to add only debug.js files to the reference files to get intellisense working.
  5. /// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
    /// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
  6. SP.Core.Debug.Js and SP.Debug.Js files are the primary files needed to develop the ECMAscript. So, these two are the main and should be added to the js file after MicrosoftAjax.js reference.
  7. Like this, you can add whatever debug.js files available in the SharePoint 14 hive layouts folder. For example, if you are developing on Ribbon then the reference will be 
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.Ribbon.debug.js" />

All at once:
/// <reference name="MicrosoftAjax.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.core.debug.js" />
/// <reference path="file://C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/14/TEMPLATE/LAYOUTS/SP.debug.js" />
Note: Add all other debug.js files depends on your requirements right after the 3 reference tags.

Once add the reference tags, write something and see the intellisense loads all the methods in the specific SP object as shown below.

Hope this helps you a ton and make your development on ECMAScript more faster and faster than ever.

Monday 21 June 2010

detect request is from iPhone in ASP.NET

The usage of mobiles is growing and growing day to day and most of the users are browsing from their mobiles and do the stuff. So, it is becoming important to support the mobile phones the web sites we are developing. Recently we have developed applications which support for iPhone and I am strongly believing that ASP.NET MVC is the best architecture in all ASP.NET versions.

As we are developing applications it can be accessible from any where and any device including computers, mobiles, iphone, ipod or whatever. But, the important thing is UI. A web site how it looks like on computers is completely different from the mobile. So, we need to detect the user agent or the client who requested the site. So, if  request from computer browsers then we don't need to anything as this is the default type. Whereas the request from the mobile phones then we need to render different UI. So, this post will explains that.

Detect request from iPhone in ASP.NET [C#]:
if(HttpContext.Current.Request.UserAgent.ToLower.Contains("iphone"))
{
     //iPhone is the requested client. Write logic here.
}
else
{
     //Normal browsers [from computers] requested.
}

Detect the iPhone request in Java script:
if (navigator.userAgent.match(/iPhone/i)
So, depends on the client we will write the corresponding logic in the specific block to switch UI. Hope this helps.

Wednesday 16 June 2010

Read More link to blogger posts without HTML changes

This is really a very helpful post I believe. Most of the times I write long posts and explain each and every part in the solution I found. So, I really need to show only specific length of each post and add a link called Read More at the end of the post on the blog home page. So, that users get chance to see more posts and look more posts. And the loading of the main page will be faster as the content is less. So, there are lot of advantages by placing the read more link on the home page for each post.

I have tried so many solutions and didn't impress by any of them. Some of them are disturbing my HTML as after specific characters add the read more link. Another option is, strip the HTML from the post and add the read more link after specific characters, but that also removes the blog styles for P tag, div Tag or any other custom styles we have applied. Sp, to get this working either we need to change the Blog HTML or add bunch of Javascript code to do that. This is not very easy to maintain and useful. So, what to do, can't I do it? So, after a very long research and read so much I want to give better user experience to my users to read what they want on my blog. Finally came up with a nice and simple solution which do not need much HTML changes or customization.

What is Jump Break and what it will do?
This is the option which is available in blogger by default and not known to most of the people. Lot of people are doing lot of customization to add read more links to their blogs. With this feature we don't need to do anything as it provides everything for us.

Solution:
  1. Go to create post or edit post and place the cursor in the content where you need to add the read more link. Once set the mouse cursor, from the editor toolbar find the option "Insert Jump Break" as shown below, this option will be visible in new blogger template editors and in editor Compose mode only. In "Edit HTML" mode all these option will go off. So, make sure you are in "Compose" mode to insert jump break.

    Note: If you did not find the jump break as shown below then add the text <--more--> in the Edit HTML mode of the editor wherever you want.
  2. Now, it will insert a bar which represents the Jump Break [see below image how it looks like]. This can be dragged to the place wherever you need it. First set the position of it. You are half done by doing this.
  3. Now, publish the post and go to Edit HTML option from the blog navigation links Layout or Design[Tab name changed recently].
  4. Take the backup of the full template before do any changes.
  5. Now, check the option "Expand Widget Templates".
  6. Search for the tag in your HTML <data:post.body />.
  7. Add this simple HTML text, just below the above tag.
<b:if cond='data:post.hasJumpLink'>
<div class='jump-link'>
<a expr:href='data:post.url + "#more"'><data:post.jumpText/></a>
</div>
</b:if >
Here, it just finds whether the data in the post has the jump link set, if yes, then it will insert the anchor text for read more, otherwise it skips the line. You can place whatever text or image or any other HTML tag instead of anchor tag in the above example code for read more.
Now, save your template and just go to your home page for testing the functionality.

The great advantage is very simple. People like it to use it or maintain it. Very simple and easy right? The only thing you need to do is, just follow the same for each post where you want to place the read more. Don't think like, if your blog already had 100's of posts then the first question in mind will be "Do I need to apply the same for all those posts?". Not needed. Read more is only useful most of the times for only home page posts. So, add to the current home page posts and to new upcoming posts.
Hope this gives you good idea on how to add read more link for your blog posts. Like it? then please share it.

Thursday 3 June 2010

Best Split UDF function with delimeter in T-SQL to return result as a table

This is what the function I am using since many years to get the table of values in the given ID's which are separated by some delimiter.

Simple to understand and see the example in the comments in below function.
From the UI there are sometimes need of sending the data or ID's in the string format separated by a delimiter. So, in database, we need to grab them and apply some operations like with the ID's we need to get the records from a table. In this case, we need to use this UDF function. Everyone knows that inner joins are far better than IN clause or something else. So, what the approach I have taken here is, I will get the delimited string and delimiter and pass them to UDF function. It returns me a table which has the rows consists of the ID's. By using this table, I will apply whatever operation I want and get the result.

UDF Function:

GO
/****** Object:  UserDefinedFunction [dbo].[fnStringSplitter]    Script Date: 04/04/2006 11:44:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*******************************************************************************************************/
--            Author: Praveen Battula
--            Date: 04/04/2006                     /*******************************************************************************************************/
CREATE Function [dbo].[fnStringSplitter]
(   
    @IDs Varchar(max) --A big string which may have delimeter in it or not
    ,@Delimiter Varchar(1) -- Delimeter to use for splitting up the given string
)
/*********************** RETURN *********************/
--Returns the table with specific values in a temporary table. Useful especially if you have any IDs in the
--given string and want to get them as a table row values.
-- Example:
--@IDs = 1,2,3,4,5,6,7,8,9,10
--@Delimeter = ','
--Returns @Tbl_IDS, which is having 10 rows with above IDS in each row by splitting up with given delimeter [in this example ',']
/****************************************************/
Returns @Tbl_IDs Table (ID Varchar(500)) As
Begin
    --Remove the leading delimiter if any
    while (substring(@IDs,1,1) =@Delimiter)
        set @IDs = substring(@IDs, 2,len(@IDs)-1)

    -- Append comma
    Set @IDs = @IDs + @Delimiter

    -- Indexes to keep the position of searching
    Declare @Pos1 Int
    Declare @pos2 Int
    Declare @RowNum Int

    -- Start from first character
    Set @Pos1=1
    Set @Pos2=1
    While @Pos1
    Begin
        Set @Pos1 = CharIndex(@Delimiter,@IDs,@Pos1)
        Insert @Tbl_IDs Values (Substring(@IDs,@Pos2,@Pos1-@Pos2))
        -- Go to next non comma character
        Set @Pos2=@Pos1+1
        -- Search from the next charcater
        Set @Pos1 = @Pos1+1
    End
    Return
End

This is not a very complex logic to understand. And below is the usage of the function.
DECLARE @EmployeeIDs VARCHAR(MAX);
SET @EmployeeIDs = '1,2,3,4,5,6,7,8,9,10';
SELECT * FROM [Employee] as e INNER JOIN  dbo.fnStringSplitter(@EmployeeIDs, ',') as eIDs ON e.EmployeeID = eIDs.ID;

So, here I have passed a string which consists of IDs to the UDF function along with delimiter as second parameter and it returns me the table with IDs as records. Now, I am simply applying the inner join on the primary table and getting what actually I need. Very simple concept and implementaion.

Hope you like this function and please let me know, if you have any ways to improve this or issues with it.

Know COUNT of bit column using Group by in T-SQL

Here is a scenario most of the times we use and look for. I have a bit column in database table and want to filter the count of true count and false count by applying Group By on it. For example, below is the simple scenario I came up with to better present you.

We are storing employee details in database and taking attendance once in every day. So, in reporting, I want to see month wise report on how many are total, absent and present. Now, the challenge is need to find out how many are total employee and among them how many are attended and how many are absent in the given month and year.

OK, let's go to implementation and find the solution.

SELECT [Month],[Year],Count(IsPresent) as [Total], Count(Case When IsPresent='True' Then IsPresent End) as Attended, Count(Case When IsPresent='False' Then IsPresent End) as Absent From [EmployeeAttendance] WHERE [Month] = @Month AND [Year] = @Year GROUP BY [Month],[Year]

This is it!!! Very simple. Hope you understand it on how to apply grouping on bit field to find out the counts.

Compare Date only in Datetime field in T-SQL

This is simple still I want to share as this is asked by so many people around. So, here is the scenario why it's needed. [Mainly in reporting.]

From the UI, users selects the date and by using that date we need to compare the datetime field in database and produce some result. But, in database it actually the datetime field, we can't apply equal operator on it as it fails to do it because of time part.

I know, now there is a need of time for thinking on how to do it.

Solution:
SELECT * FROM [Employee] WHERE Convert(date,DateSent) = Convert(date,@Date);

OR

SELECT * FROM [Employee] WHERE DATEADD(dd,(DATEDIFF(dd,0,DateSent)),0) = DATEADD(dd,(DATEDIFF(dd,0,@Date)),0);

So, in above query we have taken out the Date part from both DateSent field in database and @Date parameter from the UI  and comparing them. Which produces exact result as we are looking for.

Hope this helps and want to know are there any better solutions for it.

Group By Date Time without milliseconds in T-SQL

There are lot of requirements which needs some complex logic and put maximum effort to implement them. The below scenario is the one I want to explain in writing T-SQL queries.

The requirement is very simple, I want to apply group by on DateTime field in database which does not includes the milliseconds part from the time. So, on the UI I need to group by and show records with seconds and but not with milliseconds.

In my first try, I just wrote the T-SQL query by directly applying the GROUP BY clause on the DateTime field and found that milliseconds are also including. Which is not matching with what exactly I was looking for. So, tested lot of scenarios and nothing works. I am out of ideas on how to trim the milliseconds and apply group by.

After spent some good time on it, got an idea and not sure this is the best and efficient way of implementing.

SELECT CAST(CAST(CONVERT(Date,Datesent) AS Varchar(20)) + ' ' + CAST(CONVERT(TIME(0),Datesent) AS Varchar(20)) AS Datetime) AS DateSent,
Name, Department,
    FROM [EmployeHistory]
    WHERE EmployeID = @EmployeID
    GROUP BY CAST(CAST(CONVERT(Date,Datesent) AS Varchar(20)) + ' ' + CAST(CONVERT(TIME(0),Datesent) AS Varchar(20)) AS Datetime),
Name, Department
ORDER BY DateSent Desc

So, in the above query, if you observe take the GROUP BY clause out and analyze it.
GROUP BY CAST(CAST(CONVERT(Date,Datesent) AS Varchar(20)) + ' ' + CAST(CONVERT(TIME(0),Datesent) AS Varchar(20)) AS Datetime)

I am doing some way to get  the things work out. :) So, don't be surprise. I am doing nothing here, other than taking the Date part from the date time and taking the Time part from the date time without milliseconds and finally casting it back to date by clubbing those two back...

Do you think, this is the best and efficient way? I am sure this will work without any issues. But, the main thing is even though it is looking like simple it took me time to get the solution for it. Hope this helps and please let me know, if you know any better solution than this.