Reformat URL from calculated column with decent clickable link text

19.11.2009 Fixed the bugs from yesterday…
18.11.2009 Added support for grouped views.
17.11.2009 Updated code to remove the filter in the viewheader for the field with the calculated column “Link”. Noted by Paulo Sousa in the post comments. I have also added a code to use for the DispForm to format the link.

If you create a link from a calculated column it is not formatted right in the list view. Here it a small jQuery script to fix this issue.

The list has these columns:
IMG

The code in the calculated column “Link” looks like this:

="<a title='The mouseover text goes here' href='"&URL&"'>"&Description&"</a>"

The NewForm looks like this:
IMG

The list view looks like this before the script is added:
IMG

And like this after the script is added:
IMG

How is it done?

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

Add a CEWP below the list view like this:
IMG

With this code:

<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
// Updated 19.11.2009
// Reformat the url in the calculated column
reformatCalculatedColumnUrl();

function reformatCalculatedColumnUrl(){
	$(".ms-listviewtable td.ms-vb2:contains('href')").each(function(){
		$(this).html($(this).text())
	});
}

// If grouped by the calculated column - reformat the group header
var groupHeaderClickableLink = true; // Set to false to remove the link on the groupheader
$(".ms-listviewtable td[class^='ms-gb']").each(function(){
	if($(this).html().indexOf('<')>0){
		// Get full HTML of group header
		var rawHTML = $(this).html();
		// Extract the part before the calculated column's content
		var preWrap = rawHTML.substring(0,rawHTML.indexOf("<"));
		// Extract the part after the calculated column's content
		var postWrap = rawHTML.substring(rawHTML.lastIndexOf('>')+4);
	
		if(!groupHeaderClickableLink){
			// Find the clickable part of the calculated column's content 
			var linkTextStart = rawHTML.indexOf('>') + 4;
			var linkTextStop = rawHTML.lastIndexOf('<');
			var linkText = rawHTML.substring(linkTextStart,linkTextStop);
			// Write back the HTML
			$(this).html(preWrap + linkText + postWrap);
		}else{
			// Find the clickable part of the calculated column's content 
			var linkStart = rawHTML.indexOf('<');
			var linkStop = rawHTML.lastIndexOf('>') + 4;
			// Find raw link				
			var rawLink = rawHTML.substring(linkStart,linkStop);
			// Find the parts to keep
			var pre = rawLink.substring(0,rawLink.indexOf('href=') + 6);
			var mid = rawLink.substring(rawLink.lastIndexOf('href=')+6,rawLink.indexOf('>')-1);
			var post = rawLink.substring(rawLink.indexOf('>')-1);
			// Get the full url and replace the < and >
			var fullUrl = (pre + mid + post).replace(/</g,'<').replace(/>/g,'>');
			// Write back the HTML
			$(this).html(preWrap + fullUrl + postWrap);	
		}
	}
});

// Disable the filter for the field named "Link"
$(".ms-viewheadertr table[displayname='Link']").parents('th:first').removeClass('ms-vh2').addClass('ms-vh2-nograd').html("Link");

// Attaches a call to the function "reformatCalculatedColumnUrl" to the "expand grouped elements function" for it to function in grouped listview's
function ExpGroupRenderData(htmlToRender, groupName, isLoaded){
	var tbody=document.getElementById("tbod"+groupName+"_");
	var wrapDiv=document.createElement("DIV");
	wrapDiv.innerHTML="<TABLE><TBODY id="tbod"+groupName+"_" isLoaded=""+isLoaded+"">"+htmlToRender+"</TBODY></TABLE>";
	tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
reformatCalculatedColumnUrl();
}
</script>

The “group by calculated column – feature” is requested by Paulo Sousa. You can specify whether to have a clickable link or a plain text in the group header by setting the parameter “groupHeaderClickableLink” in line 14 to true or false.

In line 50 in this codeblock i have disabled the filter link in the view header for the field with DisplayName “Link” – you must insert your own field’s DisplayName here.

I do not know of a way to “reformat” the filter values for a calculated column, and therefore the filter values will be like the calculated column’s raw value – therefore i found that disabling the filter was he best option.

For use with DispForm – add code to CEWP below list form (edit the location of jquery as needed):

<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
fields = init_fields();

// This is an array of FieldInternalNames for all fields to reformat
var arrOfFieldsToReformat = ['Link'];
// Loop trough all fields in array and reformat to decent link
$.each(arrOfFieldsToReformat,function(idx,item){
	var LinkField = $(fields[item]).find('.ms-formbody');
	LinkField.html(LinkField.text());
});

function init_fields(){
var res = {};
$("td.ms-formbody").each(function(){
if($(this).html().indexOf('FieldInternalName="')<0) return; 
var start = $(this).html().indexOf('FieldInternalName="')+19;
var stopp = $(this).html().indexOf('FieldType="')-7; 
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}
</script>

In line 6 you must insert your own FieldInternalNames!
You can add multiple FieldInternalNames, comma separated.

This will result in a DispForm like this:
IMG

That’s it!

Regards
Alexander

37 thoughts on “Reformat URL from calculated column with decent clickable link text”

  1. Hi wss3dude,
    Which version of FireFox are you using? – i have tested it with the latest 3.5.4 (on windows) and it works for me.

    If you fill me in with some details i can try to fix it, but as i cannot recreate the problem, i must have some input from you.

    Alexander

    1. Hi,
      Thanks for noticing it. I have only one solution – disable the filter for that column. See updated code above.

      I have also added code to use in DispForm to format the link in the same way as in the list view.

      Alexander

  2. Thanks! That’s a way to solve the problem.
    However there is another issue: this function fails if we have a List View with a ‘Group By’.
    Can you solve this?
    TIA

  3. Almost perfect!
    It works as long as you don’t Group By the Link.
    Keep thinking in a way of Filtering and Grouping by this Calculated Column, showing a decent text.
    This is VERY useful. Thanks a lot!
    Paulo

    1. Hi,
      Maybe I’m thinking in the wrong terms, but why would you want to group by the calculated link?

      If so, a click on he group header – should it expand the grouping or follow the link?

      Please fill me in on the details and i may be able to help you.

      Alexander

  4. Hi again,
    It would be perfect if a click on the group header also follow the link, but it would be good enough just to show the decent text (without link). But this is not very important. What I really need is the filter in the List Header.
    By the way, I can´t make this work in DispForm – each field shows the concatenation of all the fields content, despite, in the middle of this, it shows the Link as need, in all the fields …

    Thanks again for your time,

    Paulo

    1. Hi,
      I have updated the code to reformat the link if grouped by the calculated column. The filter i cannot help you with.

      The code for the DispForm is updated as well.

      Alexander

  5. Hi,
    The Link in the Group Header looks nice but the URL becomes invalid, but, as I said before, this is not much important.
    DispForm: still the same problem – Link looks nice but everything else is a mess.
    One other smal thing: this script works for Lists with Groups but it won’t work for simple List (without Groups) – it would be nice to have the same script working for both types of List.
    TIA

    1. Updated code – can you test it to see if it does the trick?

      Regarding the DispForm: Did you add your own FieldInternalName in the array “arrOfFieldsToReformat”?

      Alexander

  6. Just to drop you some notes (not very important):
    1. I changed the apearence of the calculated link to bold and orange.
    In the list works great, but in the Group Header it looses the color attribute.
    2. If have 2 group levels it fails in the 2nd one.

    And yes, in the DispForm I changed the line:
    var arrOfFieldsToReformat = [‘my-calculated-link-field-name’];
    Am I missing something?

    TIA

    Paulo

  7. Now the situation is the following:
    List: link works and looks ok (bold and orange);
    1st group level: header link works but it shoes bold only (not orange);
    2nd group level: header link works but it shows normal (not bold nor orange). Must important: doesn’t expand.

    1. Hi,
      My testlist looks OK, but you can experiment with line 15 in the codeblock. I have changed it like this:

      // Use this for level 1 only
      $(".ms-listviewtable td.ms-gb").each(function(){
      // Use this for both levels:
      $(".ms-listviewtable td[class^='ms-gb']").each(function(){
      // Use this for level 2 only
      $(".ms-listviewtable td.ms-gb2").each(function(){
      

      Can you try to change the grouping – switch nr 1 with nr 2 and see? – it could be something wrong with your calculated link on level 2.

      PS: I have not addressed the coloring and bold issue.

      Alexander

    1. Hi,
      That is strange, as my test list looks OK, but my test list is a very simple list though…

      If you modify the code in line 15 like this (like i wrote in the answer above):

      $(".ms-listviewtable td.ms-gb2").each(function(){
      

      Now only the second grouping should be formatted. How does that look?

      Could you send me some screen shots of your calculated column and your view without the script added (so that i can see the column before formatting).

      Alexander

  8. Hi Alexander,

    The solution is brilliant, thanks !

    The only problem I have got is that we are using a template for our site and we have used Microsoft SharePoint developer to add some views such as the related tasks and issues, to our display form webpage. So in the webpage that my form is located on, some views of other lists are included as well. This is causing strange problem, the code enables creating the link but at the end it merges the value for all columns and creates a very big entity made of the values in all columns. For example let say my form has 3 columns as:
    Project name : P1
    Owner: O1
    Link: http://www.L1.com
    After including the code the display form looks like this:
    Project name : P1 O1 http://www.L1.com
    Owner: P1 O1 http://www.L1.com
    Link: P1 O1 http://www.L1.com

    When the http://www.L1.com is being transferred to the hyperlink

    1. Hi,
      This solution is supposed to be used in unmodified SharePoint forms and views. If you have modified the form and view in SharePoint Designer you could make these changes directly in SharePoint Designer. If you still want to use this solution in your customized page, I’m afraid you will have to make the modifications yourself because no two customized pages are alike.

      Alexander

  9. Hi Alexander,
    The js code works just fine, however, I have difficulty with the sharepoint side of it.
    Using the “&Field Name&” reference to field names runs to error in SP. So I tried [Field Name] instead, but that did not work. Also, I need to construct a fairly complicated anchor tag: [Field2].
    Can you please help with this?
    Cheers,
    Levente

  10. HI Alexander,
    Using this solution is there a way i can create a solution where my color coded calculated field (KPI Lights) can be turned into hyperlink. Where Url of the Hyperlink will be fed from another column named [Hyperlink1].

    So when user clicks on those individual KPI Lights they would be redirected to whatever url user entered in column [Hyperlink1].

    Your help would be greatly appreciated.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.