Parameter-Driven Javascript in XSL

As a follow on to my last post, getting the syntax right for Javascript to work well within XSL can drive you a little batty at times.  One good trick is using the <xsl:attribute> tag.  The XSL below is a snippet from the page that I described in my last post.  When the user checks or unchecks the checkbox, I want to commit the changes (I set a bunch of item column values in the setValues Javascript function) and then return to the same page with the same query string arguments.  Getting all of that right in the onclick event parameter is problematic at best, impossible at worst.  By using the <xsl:attribute> tag, I can “step out of” the <input> tag context and let the XSL do its thing.
<input title="RequestTicket" name="RequestTicket" id="ff4{$Pos}" type="checkbox">
  <xsl:attribute name="onclick">
    setValues(this.checked, '<xsl:value-of select="$Pos"/>', '<xsl:value-of select="$RequestID"/>');
    <xsl:value-of select="ddwrt:GenFireServerEvent(concat('__commit;__redirect={',$URL,'?EventID=',$EventID,'&amp;RequestID=',$RequestID,'}'))"/>
 </xsl:attribute>
 <xsl:if test="@RequestID = $RequestID">
  <xsl:attribute name="checked" />
 </xsl:if>
</input>
  • In the setValues line, I can easily pass along the two parameter values ($Pos is the current record number and $RequestID is a parameter that I get from the query string) and, even nicer, I have access to this.checked (the checked state of the checkbox itself).
  • In the ddwrt:GenFireServerEvent line, I can also easily include parameter values ($URL is the Server Variable for the current page’s URL, etc.) and concatenate everything together (using concat).
  • Finally, as I described before, the <xsl:if> section allows me to set the checked state of the checkbox by comparing the RequestID in each item with the value of RequestID passed in on the query string.

XSL, Not Javascript, in SharePoint Forms

I’ve been working a lot with custom forms in SharePoint lately, and I’m finding all sorts of shortcuts.

Here’s a good example.  I’ve got a form on which I am allowing the user to select 1-n tickets for an event by ticking a checkbox in each row.  The form displays all available tickets for the event, as well as any tickets that the user has already selected (so that they can deselect the ticket to “give it back”).  So, when the page loads, I want to set the state of each checkbox to reflect whether it has already been selected.

This is an occasion where it may feel natural to turn to Javascript.  I certainly did, because I already had some Javascript in the page that I could clone and alter to my needs.  However, rather than needing this Javascript (and all its attendant functions):

function setCheckBoxes() {
  rows = getRowsWithFieldName('input', 'RequestID', 'ff1_'); //Get a count of the number of rows displayed
  for (var i = 1; i <= rows; i++) { //For each row
    RequestID = getValueWithFieldName('input', 'RequestID', 'ff1_' + i); //Get the RequestID
    if(RequestID != 'NOID') { //If the RequestID isn't equal to our default 'unrequested' value of NOID
      setCheckedWithFieldName('input', 'RequestTicket', 'ff4_' + i); //Set the checkbox
    }
  }
}

I can just do this in the XSL:

<input title="RequestTicket" name="RequestTicket" id="ff4{$Pos}" type="checkbox" onclick="setIncrementDecrement(this.checked, {$Pos}', '{$RequestID}')">
  <xsl:if test="@RequestID = $RequestID">
    <xsl:attribute name="checked" />
  </xsl:if>
</input>

I’ve used the XSL method many times before, but that temptation to use Javascript got me. Clearly in this case, the XSL makes for a nicer, more maintainable solution.

Probable Permissions Problem in SharePoint DVWP

I got a message through my Live Space today, but I couldn’t respond due to the sender’s preferences, so I decided that I’d reply here.

I’m having an issue with some Data View Web Parts I created via SPD. I create the data views in Designer using data sources from SharePoint lists. That works fine. Then I link my data views through Web Connections (all in Designer). That seems to work fine. They I test in a browser. That works fine.  I make my radio button selections and all the data views switch to that linked items content. However, I’m the only one that can see this info from the browser. HELP!!!

My best guess based on what you’ve told me is that your users have different permissions on the content than you.  Since you are able to edit the page with SharePoint Designer, it’s highly probable that you have Site Collection Administrator permissions.  This would allow you to see all content in any list on the site.  Check to see what your users’ permissions are on the same content that you are seeing.

Hope this helps.  Drop me a comment if you have further questions.

Damaged Master Page Link in SharePoint

There are occasions when the master page that is attached to a site is not valid.  The master page connection is made with a URL, and if that URL isn’t valid, you will get errors like:
  • File not found (This is SharePoint saying that the master page itself is not found.)
  • / cannot be opened (or the like)
  • etc.

One quick check you can do is to go to the Site Settings page to check the master page connection.  Do this by hacking the URL to point to:

http://servername/sitename/_layouts/settings.aspx

Once there, you can set the master page something valid and your site will miraculously be back in business.

“Deleted” SharePoint Web Parts

This one was suggested to me by my friend and colleague Mike Koffman.  He always tries to take the time to go to Advanced in the Modify Web Part panel and take away the user’s ability to "close" the web part.  Here’s the story why.

In working on other people’s sites in SharePoint, I’m often amazed at how many Web Parts are on the pages, but not visible to the users.  This is usually due to false starts in implementation, trying things out and then abandoning them for some reason, etc.

Most people seem to just click the little "X" in the upper corner of the Web Part and assume that it has been deleted.  But no, it’s still there.  If you open the page in SharePoint Designer, you’ll see all of the "ghostie" Web Parts still hanging around.  (I say "ghostie" because they are faded out in the UI.  And because I have a four year old.)

Because the Web Part is still there, SharePoint still has to process it when the page loads.  I heard through the grapevine that a Microsoft engineer said recently that it takes more work for the system to process the Web Part when it’s closed than it does when it’s visible, but I can’t vouch for that.  In any case, SharePoint has to at least read the code for the Web Part to realize that it shouldn’t display it.

To really get rid of the Web Part, you should select the "Delete" option from the menu rather than clicking the "X". The problem is that, once it’s closed, it’s virtually invisible so you don’t even know it still exists. One trick you can use is to navigate to the page and add "?contents=1" to the end of the URL. This gives you a page with a list of all the Web Parts on the page, with a column showing whether the Web Part is open or closed. To get rid of the closed Web Parts, select the check boxes next to them and use the "Delete" option on the toolbar.  The other option is the one which I prefer: open the pages in SharePoint Designer and delete those little "ghosties"!

Technorati tags: , ,