Breaking .NET Habits When You Write Script

There’s a long thread over at EndUserSharePoint.com‘s Stump the Panel where I’m trying to help someone to set up some jQuery to do some calculations in the form to check if the values are valid. The person (handles don’t always give away gender!) is struggling (IMHO) with the difference between server-side and client-side code. There’s been a lot of back and forth, but here’s some of the latest exchange, as I think it may be helpful to others.

Where we are at the moment is figuring out where the script should go in the aspx page and how to select, or find, the right values in the rendered page.

They have said that they are “Placing [the script] in the ASP: Content section”. There are lots of asp:content sections, and which one you choose can have an impact on how and when your script runs (or doesn’t run). I generally put my script right below the line:

<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">

This is the most reliable place to put the script in my experience. You can also place the script in a Content Editor Web Part (CEWP).

The person has posted the snippet of code below and asked which of the values shown is the DisplayName.

<tr>
  <td width="190px" valign="top">
    <H3>
      <nobr>Deal 5 Allocation</nobr>
    </H3>
  </td>
  <td width="400px" valign="top">
    <SharePoint:FormField runat="server" id="ff41{$Pos}" ControlMode="Edit" FieldName="Deal_x0020_5_x0020_Allocation" __designer:bind="{ddwrt:DataBind('u',concat('ff41',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Deal_x0020_5_x0020_Allocation')}"/>
    <SharePoint:FieldDescription runat="server" id="ff41description{$Pos}" FieldName="Deal_x0020_5_x0020_Allocation" ControlMode="Edit"/>
  </td>
</tr>

The problem is that this is the server-side code. The SharePoint:FormField will be rendered as HTML by SharePoint, so looking at the page server-side while the script is running client-side really doesn’t work. As I point out to folks a *lot*, you really need to get used to using the Developer Tools or Firebug or something to look at the Document Object Model (DOM) client-side to understand what is rendered rather than what controls are in the page server-side.

This is what the person keeps trying to do:

$("input[Title='ff41{$Pos}']").blur(function () {
  yourCalcFunction();
  // whatever else you want to do... (blank out the column value, turn it red, whatever)
});"

This won’t work, because the Title is never going to equal ‘ff41{$Pos}’ client-side. At the very least, the {$Pos} will be evaluated to the current row position, so the id will look like ‘ff411’. Instead it should be:

$("input[Title='Column 1']").blur(function () {
  yourCalcFunction();
  // whatever else you want to do... (blank out the column value, turn it red, whatever)
});"

The selector $(“input[Title=’Column 1′]”) says “find me an input element which has its Title attribute set to the string ‘Column 1′”. So you need to look at the input element in the DOM to see what the Title attribute contains. SharePoint always sets the Title to the DisplayName of the column for input elements, so if your column is called ‘Deal 5 Allocation’, that’s the DisplayName. ‘Deal_x0020_5_x0020_Allocation’ is the internal name, also called the StaticName. Note that the StaticName never changes after you create the column even if you change the DisplayName repeatedly.

Hope this is useful to folks out there!

4 Comments

  1. Marc,

    I have seen many examples of people doing exactly this and you are right that it will never work. I use custom rendering templates along with jQuery and it can be confusing to some what the id’s will look like. My tip has been to just use the “view source” option of IE if you can to see what the id is rendered as. It works for me and may be helpful to others as well!

    Reply
  2. I’ve been doing a lot of client side script lately and I agree with you Marc, you must turn to some time of client side tool such as FireBug w/ FireFox or the Developer Tools with IE8. Both of these allow you to write code into a console to see what the results will be when executed. Additionally, there is an extension for FireFox called FireFinder that allows you to execute CSS selectors. This works very well for determining which elements a specific selector will find. I did this in a recent project where I needed to detach web-parts from a web-part page and render them using jQuery UI tabs — if I hadn’t had these client side tools the task would have been much more difficult.

    Reply

Have a thought or opinion?