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

Quick Fix: “The content type name ‘$Resources:ReportServerResources … cannot contain … special characters”

I’ve been spending some time cleaning up a SharePoint 2010 site and one of the cleanup issues relates to a corrupt / incorrectly installed SQL Server Report Services issue.  The issue arose when one of my colleagues tried to save a site as a template and then create create a new site based on that template.  The save operation worked fine, but when she tried to create the new site, SharePoint displayed the following error message:

Error

The content type name ‘$Resources:ReportServerResources,DataSourceContentTypeName;’ cannot contain: \ / : * ? “ # % < > { } | ~ & , two consecutive periods (..), or special characters such as a tab.

Here’s a screen cap:

 

image

I had a look at the content types in the site and found this:

image

Those content types are clearly unhealthy.

This issue seems to come up a lot on the Internets and there doesn’t seem to be a single consensus on how to solve it.  I found a handy table that mapped the bad content type names to good content type names here: http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010programming/thread/cb03e866-8184-4943-acfe-cafffa1b8b7a.  I manually updated them thusly:

image

(BrightStarr in the name is obviously optional, but it can’t hurt Smile )

This allowed me to create a new template and didn’t break anything on the other sites, including some PerformancePoint Server stuff that a completely different group of people were working on.  I was then able to create a new site on the template.  Success!

I am not sure this is a 100% solution, but it got me and everyone involved past this annoying error.  If I find anything new, I’ll post an update.  My nervousness stems from the fact that these names shouldn’t be wrong in the first place and by fixing the display name, I am not touching the internal name. 

</end>

Subscribe to my blog.

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

One Cause for “The creator of this fault did not specify a Reason.”

I’ve been doing a lot of work with SharePoint search lately and specifically the KeywordQuery class, properties and methods.

If you want the result set to return results above and beyond the usual suspects (see here), you add it to the SelectedProperties collection, as in:

myKeywordQuery.SelectProperties.Add("xyzzy");

Many thanks and a tip of the hat to Corey Roth and this enormously helpful blog post (http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/02/19/how-to-use-the-moss-enterprise-search-keywordquery-class.aspx)

In my case, “xyzzy” isn’t actually a managed property.  When I added it to SelectedProperties anyway, SharePoint threw one of my favorite ever runtime exceptions:

“The creator of this fault did not specify a Reason.”

I especially like the capital “R” in Reason.  This sounds to me like the .NET equivalent of “I have no mouth, and I must scream.”

</end>

Subscribe to my blog.

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

Handy Reference: Default Results from KeywordQuery Search

When you invoke the Execute() method on a KeywordQuery, you can create a ResultTable based on ResultType.RelevantResults.  This code snippet illustrates what I mean:

ResultTableCollection resultsTableCollection = myKeywordQuery.Execute();

ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];

The resulting table will have the following columns of information: 

WorkId
Rank
Title
Author
Size
Path
Description
Write
SiteName
CollapsingStatus
HitHighlightedSummary
HitHighlightedProperties
ContentClass
IsDocument
PictureThumbnailURL
ServerRedirectedURL

I derived this list from a SharePoint 2010 environment, enterprise edition.  Hopefully it will be handy to someone in future.

</end>

Subscribe to my blog.

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

One Reason for: “Failed to extract the cab file in the solution”

While working on a visual studio web part project today, I did a minor re-org of some files to be put into the _layouts folder as part of the deployment process. Specifically, I renamed a .js file from “TypeAhead.js” to “TypeAhead(old).js”  I plan to remove it as soon as its successor “TypeAhead.js” proves correct.  It looked like this:

image

This immediately caused a problem with visual studio when I tried to deploy the project:

Error occurred in deployment step ‘Add Solution’: Failed to extract the cab file in the solution.

It turns out that you should not put a parenthesis in file names.  I removed the parens and that solved the problem.

</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

Parsing XML with LINQ

Here’s a quick example using LINQ to parse some  XML and get at the sweet, sweet attributes therein.

Here’s the XML I want to parse:

<?xml version="1.0" encoding="utf-8" ?>
<DeafultConfigurationSets>
  <PageLayouts>

    <PageLayout name="xyzzy">
      <Tabs>
        <Tab TabOrder="1" TabLabel="x" SharePointContentType="a" AdditionalConstraints="ac1"/>
        <Tab TabOrder="2" TabLabel="y" SharePointContentType="b" AdditionalConstraints="ac2"/>
      </Tabs>
    </PageLayout>

    <PageLayout name="xyzzy2">
      <Tabs>
        <Tab TabOrder="100" TabLabel="x" SharePointContentType="a" AdditionalConstraints="ac1"/>
        <Tab TabOrder="101" TabLabel="y" SharePointContentType="b" AdditionalConstraints="ac2"/>
        <Tab TabOrder="103" TabLabel="z" SharePointContentType="c" AdditionalConstraints="ac3"/>
      </Tabs>
    </PageLayout>

  </PageLayouts>
</DeafultConfigurationSets>

I want to build up some tabs at runtime by parsing the above.  My tabs depend upon a page layout.  If my page layout’s name is “xyzzy2” then I want to get tabs 100, 101 and 103 (the tabs in <PageLayout name=”xyzzy2”>).

Here’s the LINQ that does it:

var allTabs =
              from p in
                  XElement.Parse(theXmlToParse).
                 
Elements("PageLayouts").
                  Elements("PageLayout")
              where (p.Attribute("name").Value.Equals("xyzzy2"))
              from m in p.Elements("Tabs").Elements("Tab")
              select m;

          Results.Text = string.Empty;

          foreach (var aTab in allTabs)
          {
              Results.Text +=
                  "Tab Order: " + aTab.Attribute("TabOrder").Value + " |" +
                  "Tab Label: " + aTab.Attribute("TabLabel").Value + " | " +
                  "SharePointContentType: " + aTab.Attribute("SharePointContentType").Value + " | " +
                  "AdditionalConstraints: " + aTab.Attribute("AdditionalConstraints").Value + "\r";
          }

In the above, the variable “theXmlToParse” is a string variable, but you can use the load() method on a stream if you like.

“Results” is a label on a web form and when this code executes, it looks like this:

SNAGHTML11cd2e7c

I haven’t worked out how to sort the results yet, so I’ll leave that for a future blog post.

</end>

Subscribe to my blog.

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

SharePoint 2010 KeywordQuery and Anonymous Users

I enabled anonymous access in my site to test out a search web part I’ve been developing and to no great surprise, it didn’t quite work.  Anonymous access is pretty much always a challenge for me.

In this case, the initial search wasn’t running for some reason.  I should say that it was running but it was not returning any results.  I’m using the KeywordQuery for that initial display.

I did a quick search and this blog post by “sowmyancs” came up fairly quickly: “SharePoint 2010 Search: not showing any results for anonymous users?”  That blog entry describes the problem from an out of the box keyword search perspective but the behavior was similar to mine – it worked for authenticated users and for anonymous users, but anonymous users got no results. 

I followed the instructions and bang!  It solved my issue.  I’m not sure what side effects this will have and they may prove to be a problem, but the short term result is helpful.

Click on through the blog:

image

</end>

Subscribe to my blog.

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

SharePoint 2010 KeywordQuery and the HiddenConstraints Property

I’ve been doing a bit of work with the KeywordQuery object in SharePoint 2010 and making use of the HiddenConstraints property.

I didn’t find any immediately helpful information on the that property, so I thought I’d quickly jot down how I’ve been using it.

As far as I can tell, this is an automatic constraint added to the query so that you can sort of park it there and not worry about it.  As such, it’s just another keyword (or set of keywords) and modifiers that you can type in to the UI when you do a keyword search.  Here’s an example:

keywordQuery.HiddenConstraints = "scope:\"Industry\"";

You can add additional constraints with a space delimiter.

keywordQuery.HiddenConstraints = "scope:\"Industry\" defense";

The above is saying in English, “run a keyword query looking for “defense” and furthermore, use the “Industry” scope.

Here’s another way of looking at it:

image

I’ve been using it to provide a context-dependent automatic scope on a custom web part.  When the user clicks on a tab and clicks a search button, the tab dictates a particular search scope.  It’s working well so far.

</end>

Subscribe to my blog.

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

Example: XSLT Creating HTML Href’s

I’ve been doing a bit of XSL stuff lately and thought I’d put together a sample for my future reference and that may be of value to all of us XSLT-ers making a living in the internets.

Consider the following XML:

<FdcSearchTabsCollection Count="2">
  <SearchTab Label="Industry" SortOrder=”00” Label=”Industries” SearchConstraints="contenttype:Industry" TabID="831b2a74-98c4-4453-8061-86e2fdb22c63"/>
  <SearchTab Label="Practices" SortOrder=”01” Label=”Practices” SearchConstraints="contenttype:PracticeGroups" TabID="678e206b-6996-421f-9765-b0558fe1a9c0"/>
</FdcSearchTabsCollection>

The following XSL snippet will generate a sorted list of hrefs tabs:

<xsl:template match="FdcSearchTabsCollection" xml:space="preserve">
   
    <!– The "all" tab –>
    <a href="javascript:ViewTab(‘All’)">View all</a>
   
    <!– Each individual tab –>
    <!– Iterate through all the Tabs and display the correct  links. –>
    <xsl:for-each select="SearchTab">
      <xsl:sort select="@SortOrder"/>

      …
      <a href="javascript:ViewTab(‘{@TabID}’)"><xsl:value-of select="@Label"/></a>
    </xsl:for-each>

    <br/> 
   

   </xsl:template>

Here’s what it looks like in SharePoint:

SNAGHTML78aa2cb

 

 

</end>

Subscribe to my blog.

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