2

I am working on a custom Display Template inside my content search web part. Now the Display Template build a URL for the items , as follow:-

<mso:ManagedPropertyMapping msdt:dt="string">'Link URL':'Path'...</mso:ManagedPropertyMapping>

var linkURL = $getItemValue(ctx, "Link URL");
linkURL.overrideValueRenderer($urlHtmlEncode);

here is how the link is being created inside the display template:-

String.format("<a href='{0}' class='ms-listlink'>{1}</a>", linkURL, property)

now i am facing a problem when building links for my discussion items, since the discussion Path include the discussion item tile (not the item Id as in the issue tracking list for example), so if the discussion title contain ' or " as in these examples :-

Customers' feedback

OR

we are planing to "Do the following"

then the generated link will truncate the title and i will get the following inside the href:-

  <a href="Customers">

and

  <a href="we are planing to"> 

so i am not sure how i can overcome this ? seems if the linkURL variable inside my display templete contain ' or " then the href will reach its end at that point, which causes the link href to be truncated if the correct href contain ' or "..

EDIT now i have noted something is that when i remove the following line of code from my display templete

linkURL.overrideValueRenderer($urlHtmlEncode);

i got my above 2 urls being rendered correctly.. but the logic says that i need this function linkURL.overrideValueRenderer($urlHtmlEncode); to get my url working well .but seems in my case using this function will cause the problem inside my above 2 urls..

so not sure what is going on ?

2 Answers 2

2
+50

linkURL.overrideValueRenderer($urlHtmlEncode); is a function processing your HTML,
if you provide it incorrect HTML it will NOT fix it.

When creating HTML and/or Links with JavaScript you have to take two types of encoding into account:

  • HTML encoding
  • URI encoding

Disclaimer:

Single vs. Double quotes in HTML or JavaScript is an endless debate,

The W3C specification allows for both single quote and double quote notation for HTML attributes

And Google advices Double Quotes for Attributes

I write about HTML encoding in detail because that explains the WHY of your error and applies to all HTML attributes

Your problem can simply be solved with URI encoding, because you create an HREF attribute

HTML encoding: Browsers and quotes

When you look in the Browser source:

HTML attribute values are always double quoted, the Browser processes any HTML you provide and converts it to double-quotes

So if you create HTML code like:

<a href='http://365coach.nl'>365Coach</a>
<a href=http://365coach.nl>365Coach</a>

They will all end up in the Browser as:

<a href="http://365coach.nl">365Coach</a>

Spaces

Quotes are only required when the attribute value contains spaces, as the browser stops processing (one value) if it encounters a space or a quote (matching the single OR double that was used to start/open the value string)

The IMG alt attribute is the easiest way to show the effect:

That means

 document.write('<img alt=Hello World >')

Will end up in the Browser as:

 <img alt="Hello" World>

cleaner HTML string in your JavaScript code

You now understand you not have to write:

 document.write('<DIV class="ms-Grid-row"  style="color:red">');

But can write:

 document.write('<DIV class=ms-Grid-row  style=color:red>');

But be careful when working in a team, most developers are not used to this notation.

Quote clash

Problems arise because we tend to use double quotes for our JavaScript strings as well

 document.write("<img alt="Customer's Choice" >") // JavaScript error

So you need to escape JavaScript strings properly with a backslash:

 document.write("<img alt=\"Customer's Choice\" >")

Output:

 <img alt="Customer's Choice">

Note that

 document.write("<img alt='Customer\'s Choice' >")

Will not work because the \' is the JavaScript escape notation,
you are still providing the string 'Customer's Choice' to the Browser
So the output is:

 <img alt="Customer" s Choice>

The Browser also has escape notations

&#34; and &quot; are the HTML escape notations for a double quote

&#39; (no named escape) is the HTML escape notations for a single quote

So a valid statement is:

 document.write("<img alt='Customer&#39;s Choice' >")

You can also escape that space character with &#32; and make the alt attribute one string without spaces,
and have the Browser add those missing double-qoutes:

 document.write("<img alt=Customer's&#32;Choice >")

BOTH will output:

<img alt="Customer's Choice">

Be aware that HTML is processed character by character

So

document.write("<img alt=&#34;Customer's Choice&#34;>")

outputs:

<img alt=""Customer's" Choice&#34;>
  • Because the first character & is not a quote
  • The attribute value ends at the space
  • Choice&#34; is now considered an HTML attribute name and not a value (with encoding)

HTML/URI encoding with JavaScript

There is no JavaScript function to sanitize Strings into HTML encoded strings, you have to proces strings yourself:

function encodeHTML(str){
  str=str.replace(/'/g,"&#34;");
  str=str.replace(/"/g,"&#39;");
  str=str.replace(/ /g,"&#32;");
  return str;
}

var blogtitle="Customer's Choice:\"apples\"";
var link="http://sharepoint/blog.aspx?"+encodeHTML(blogtitle);
var html="<A href="+link+">";
html+=blogtitle;
html+="</A>";
document.write(html);

outputs correct HTML:

Also note that the Browser encodes the HREF to a proper URI for you:

So you do not have to use the (standard) JavaScript encodeURIComponent( ) function

If you only care about the HREF attribute you could also only encode that URI:

var blogtitle="Customer's Choice:\"apples\"";
var link="http://sharepoint/blog.aspx?"+encodeURIComponent(blogtitle);
var html="<A href="+link+">";
html+=blogtitle;
html+="</A>";
document.write(html);

There are subtle differences on using ? , & in URLs:

  • encodeURI
  • encodeURIComponent

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

4
  • thanks for your detailed reply,, but i am still not sure why i got this behavioure inside my display template.. now when i remove the built-in linkURL.overrideValueRenderer($urlHtmlEncode) the href value inside my String.format("<a href='{0}' class='ms-listlink'>{1}</a>", linkURL, property) worked well, so what is the reason ?? so even if the url contain ' or " the href will be formatted correctly?? so i can not understand what is really going on? why removing the built-in linkURL.overrideValueRenderer($urlHtmlEncode) allow my <a> link to be formatted correctly ???
    – John John
    Nov 13, 2016 at 22:40
  • You will have to dig into what that SP function does in detail, maybe there is code in there to prevent event injections (creating other attributes by breaking out another) Because your code allows to inject linkURL as: ' onload='alert(\'Hello World!\')' Nov 14, 2016 at 8:18
  • can you exaplin your point in more details please?
    – John John
    Nov 14, 2016 at 12:36
  • You are giving that function incorrect formatted HTML (attribute values in single quotes) It could well be that is what that Microsoft function does not like. Only way to find it is to go in deep and see what that function does. (which I am not going to do, seen enough Microsoft code up close) Nov 14, 2016 at 14:08
1

Try the code as below:

var linkURL = $getItemValue(ctx, "Link URL");
linkURL = encodeURIComponent(linkURL);

Instead of the OOTB linkURL.overrideValueRenderer($urlHtmlEncode) method, you use the builtin javascript method to encode the url.

It looks like the overrideValueRenderer is trimming and formatting the value of the url.

encodeURIComponent

7
  • thanks for the reply. but in my case the linkURL.overrideValueRenderer($urlHtmlEncode) is not doing any thing , not even triming .. now the triming is happening on the <a href='{0}' where the href will reach it ends when it find the first ' or " .. now if the linkURL.overrideValueRenderer($urlHtmlEncode) is actually doing url encoding then the href will not trim any thing.. so not sure what is going on .. second point the w3school link you provide is broken
    – John John
    Nov 5, 2016 at 0:50
  • also can you please check my edit
    – John John
    Nov 5, 2016 at 1:04
  • also using your code i will get the following error "_A potentially dangerous Request.Path value was detected from the client (:). _" when i click on the generated url..
    – John John
    Nov 5, 2016 at 1:16
  • can u advice on my replies please?
    – John John
    Nov 7, 2016 at 12:40
  • 1
    add console.log(linkURL) to see what URL is getting generated. It should be a valid url. Hit the URL in the browser to see if its working Nov 8, 2016 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.