Tag Archives: jQuery

XSLT and jQuery Samples

I have been doing a lot of of XSLT and jQuery and thought I’d share a few snippets that others may find useful in future.

Example 1: Emit simple JavaScript / jQuery in XSLT:

<xsl:template match="something" xml:space="preserve">

  <!– Blank out the query friendly filters hidden field –>
  <script type="text/javascript">
    $(document).ready(function(){
      $("#QueryFriendlyFilters").val("empty");
    });
  </script>

</xsl:template>

That bit emits some JavaScript that waits for the page to finish loading (because of the $(document).ready(…)) and then sets the value of a hidden field named QueryFriendlyFilters to the literal value “empty”.

Example 2: Use <xsl:if> to check “greater than”,  “less than”, etc.

<xsl:template match="something" xml:space="preserve">

  <div id="fdcAllFilters">
 
    <xsl:if test="@Count>0">
      <span class="fdcFilterLabel">Current filters:</span>
    </xsl:if>

    <!– more stuff happens here. –>

</xsl:template>

The above snippet checks to see if an attribute named “Count” of the “something” element is greater than zero.  The XML behind this would be something like:”

<something Count=”5” />

Example 3: Iterate through all elements, interspersing jQuery calls.

<!– Iterate through all the filters and display the correct  links. –>
<xsl:for-each select="UserFilter">

  <a class="FilterHref" href="javascript:mySubmitPage(‘RemoveUserFilter’,'{@ID}’)">[X]</a>

  <span class="fdcFilterLabel"><xsl:value-of select="@FilterValue"/></span>

  <script type="text/javascript">

    $(document).ready(function(){
        <xsl:text><![CDATA[$("#QueryFriendlyFilters").val( ($("#QueryFriendlyFilters").val() + " ]]></xsl:text>\"<xsl:value-of select="@FilterValue"/>\"<xsl:text><![CDATA["));]]></xsl:text>
    });

  </script>

</xsl:for-each>

The above snippet is the most complex and there may be easier ways to do it.

The XML behind this looks roughly like this:

<UserFilter ID=”123” FilterValue=”xyzzy” />

This snippet is iterating through <UserFilter> nodes. 

It first emits an anchor tag that when clicked invokes a JavaScript function that is already on the page, “mySubmitPage” and passes the value of an attribute on the <UserFilter> node named “ID”. 

It then emits some jQuery that waits for the page to load.  That jQuery updates a hidden field named “QueryFriendlyFilters” by adding the value of the FilterValue attribute.  Note all the crazy <xsl:text> and <![CDATA[ … ]]> stuff.

That’s it, hope it helps!

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin

Lists.asmx, GetListItems and Folders

I was doing some research for someone today around the list.asmx web service provided as part of SharePoint 2010 (and earlier).  She was able to get the list items at the root folder (including the names of sub-folders), but couldn’t get items in sub-folders.  I did some looking around on the internets and it’s a surprisingly common question.  Yet, I couldn’t get a good answer to the simple question, “if I know the folder, how do I get the items in the folder?”  To be honest, I didn’t try all that hard since I’ve wanted to figure this one out on my own for a while Smile.

To set this up, I created a site named “Blogging Scenarios” and a custom list named “Custom List with Sub Folders”.  I then created folders named:

  • Year 2005
  • Year 2006
  • Year 2007

I added a few items to the folder “Year 2006”.  This is what it looks like:

image

My friend isn’t writing C# code but rather using Java, so the SOAP envelope was what she really needed.  To get that, I wrote a bit of jQuery and then used fiddler to get the actual HTTP conversation.

Here’s the relevant jQuery (I copied the code down below if you want to copy/paste):

image

They first key is to include both a <queryOptions> and <QueryOptions> node.  The second key is that the <Folder> node is a URL to which the client has access.

There may be other ways to get this, but this worked well for me when using jQuery.

Here is the SOAP envelope for the above:

<soapenv:Envelope xmlns:soapenv=’http://schemas.xmlsoap.org/soap/envelope/’>                
  <soapenv:Body>
    <GetListItems xmlns=’
http://schemas.microsoft.com/sharepoint/soap/’>
      <listName>Custom List with Sub Folders</listName>
      <viewFields>  
        <ViewFields>
          <FieldRef Name=’Title’ />
          <FieldRef Name=’EncodedAbsUrl’ />
        </ViewFields>
      </viewFields>
      <queryOptions>
        <QueryOptions>
          <Folder>
http://demoserver1/Blogging Scenarios/lists/Custom List with Sub Folders/Year 2006</Folder>
        </QueryOptions>
      </queryOptions>
   
</GetListItems>
  </soapenv:Body>
</soapenv:Envelope>

A lot of examples and discussion around this led me to believe that all I need was <QueryOptions> and specify a folder name.  For me, I need to both wrap it inside <queryOptions> as well as specify a fully qualified URL for the <Folder> node.

Here’s the jQuery AJAX setup:

$(document).ready(function() {
       var soapEnv =
           "<soapenv:Envelope xmlns:soapenv=’http://schemas.xmlsoap.org/soap/envelope/’> \
               <soapenv:Body> \
                    <GetListItems xmlns=’http://schemas.microsoft.com/sharepoint/soap/’> \
                       <listName>Custom List with Sub Folders</listName> \
                       <viewFields> \
                           <ViewFields> \
                              <FieldRef Name=’Title’ /> \
                              <FieldRef Name=’EncodedAbsUrl’ /> \
                          </ViewFields> \
                       </viewFields> \
                       <queryOptions> \
                         <QueryOptions> \
                           <Folder>http://demoserver1/Blogging Scenarios/lists/Custom List with Sub Folders/Year 2006</Folder> \
                         </QueryOptions> \
                       </queryOptions> \
                   </GetListItems> \
               </soapenv:Body> \
           </soapenv:Envelope>";

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin

Endlessly Nesting <div> Tags and jQuery

This seems like such an oddball topic, I’m not sure it’s really worth blogging about, but that’s never stopped me before, so here we go Smile

I’m working out on a project where I’m pulling some data from a search, packaging it up into an XML message and then that XML is ultimately transformed into HTML via XSLT.  There’s a lot of jQuery involved, one bit of which implements some tabbing functionality.  When you click on a tab (really, a <div>), jQuery invokes .hide() and .show() on various divs (the initial page load downloads all the content so there are no postbacks in this case).

A bunch of hours ago, the tab switching logic started to behave erratically and it wouldn’t show one of my tabs.  I ultimately tracked it down to the fact that internet explorer (at least) thought that the <div> tags nested far, far deeper than intended.The developer toolbar would show:

-<div id=”Tab1Content”>
  -<div>
    -<div>
      -<div id=”Tab2Content”>
        -<div>
           …………………………
                   </div>  <—finally showing it was closed all the way down here!

So, if I did a $(“#Tab1Content”).hide(), I’d also hide Tab2 and I could never show Tab2 if I didn’t also show Tab1.  I copied and pasted the code up into visual studio and it showed all of the div’s lining up nicely, just like they were supposed to be doing, looking like this:

-<div id=”Tab1Content”>
  +<div>
  +<div>
-<div id=”Tab2Content”>
  +<div>
  +<div>

I beat my head against the wall for a while and noticed that in the actual HTML code was generating a lot of empty <div> tags, like:

<body>

  <div id=”Tab1Content”>

    <div id=”row1” />
    <div id=”row2” />

  </div>

  <div id=”Tab2Content”>

    <div id=”row1” />
    <div id=”row2” />

  </div>

</body>

(The above is waaaaaaaaaaaay oversimplified.  The empty div tags are totally valid. Some of my <div> tags were full of content, but many more were not.  I came to the realization that my <xsl:for-each> directives were emitting the short-form div tags when the xsl:for-each didn’t’ find any data.  I forced an HTML comment into the output, as shown:

image

 

After I did that, all the div’s lined up nicely and my tab switching started working.

As always, I hope this helps someone in a pinch.

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin

Yet More jQuery–Resize an Image Example

I inherited a web part from a client’s old vendor and it has an image size problem.  The images should be 60×50 but for some odd reason, the original vendor forced them into 42×42, so they look squashed:

 

Good Image

Bad Image

Here’s the markup (somewhat simplified):

<table class=’extended-outlook’>
  <thead>
    <tr>
      <th  width=’100′>3 Tuesday</th>
    </tr>
  </thead>

  <tbody>
    <tr class=’forecast’>
      <td width=’100′>
        <ul>
          <li class=’high’>High: 72&deg;F</li>
          <li class=’low’>Low: 44&deg;F</li>
          <li class=’condition’>Sunny
            <img src=’
http://deskwx.weatherbug.com/images/Forecast/icons/localized/60×50/en/trans/cond007.png’ width=’42’ height=’42’ alt=” />
          </li>
        </ul>
      </td>
    </tr>

  </tbody>

</table>

You’ll note that even though the path to the image itself shows the proper dimension (60×50) the original vendor forced it in 42×42.  Why?  Crazy.

Anyway, I wanted a quick and easy solution to this issue and I turned to jQuery.  The trick was to locate all of the appropriate <img> tags.  I didn’t want to muck about with any other img tags (of which there are many).  This bit of jQuery did the trick:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>

<script type="text/javascript">
     $(document).ready(function () {

         $(‘li.condition > img’).each(function (index, item)
           
{
             $(item).css("width", "60"); 
             $(item).css("height", "50");
            });
     }); // on document load
</script>

That bit of code finds the collection <li> tags whose class is “condition” and <img> children.  It then iterates through all of that.  Worked like a charm.

I could probably streamline it, but I never was a the kind of unix guy that solved π to 18 digits precision using sed and awk and I’m not that kind if jQuery guy either Smile.

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin

Take Control of your OK and Cancel Buttons

I wrote this article a while back, but looks like I didn’t link to it from my blog at the time, so here goes:

image

This article describes how to force newform.aspx to redirect to one page when the user clicks OK and a different page when she clicks cancel.

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin

Quick Tip: Adding jQuery to MOSS Publishing Pages

When enhancing MOSS publising pages using jQuery, I hit the following speed bump:

Server Error in ‘/’ Application.


Parser Error

Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: Only Content controls are allowed directly in a content page that contains Content controls.

Source Error:

 
Line 10: 
Line 11: 
Line 12: <script 
Line 13:     type="text/javascript" 
Line 14:     src="/jQuery/jquery-1.4.min.js"> 

Source File: /_catalogs/masterpage/KCC_FacultyMember.aspx    Line: 12


Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

It was easy enough to fix (h/t to my colleague, Uday Ethirajulu).  Be sure that the jQuery code lives inside the “PlaceHolderAdditionalPageHead” as shown:

<asp:Content ContentPlaceholderID="PlaceHolderAdditionalPageHead" runat="server">

<script

    type="text/javascript"

    src="/jQuery/jquery-1.4.min.js">

</script>

<script type="text/javascript">

  $(document).ready(function() {

   // Brilliant jQuery stuff goes here.

   });

</script>

</end>

Subscribe to my blog.

Follow me on Twitter at http://www.twitter.com/pagalvin