13 August 2012

Solr date formats in C#

The Solr search engine requires dates to be in the UTC format. Using C# to create a Solr crawler, I came across a challenge as the engine would not accept the default dates. It kept throwing errors: "Error adding field". Some research revealed that Solr expects dates to always end with the "Z" character. This handy page showed the different String.Format() patterns to get just about any date string you need. This one worked for Solr:
var date = String.Format("{0:yyyy-MM-ddTHH:mm:ss.fffffffZ}", 
    dateObjectToFormat);
This produces a date in this format in Solr:
2010-03-09T00:00:00Z
Check out this documentation on the Solr date formats.

11 July 2012

Hide CSS rule from IE7

This is clearly a hack, but a quick and dirty solution that works nicely in hiding a CSS rule from IE7, but show it to modern browser:
html>/**/body .my-css-rule-name {
   /* some CSS */
}
Thanks to David Hammond's CSS Hacks page.

Datasheet view is grayed out

This is an interesting issue: Some of our users couldn't bring up lists in SharePoint's Datasheet view, which makes the list appear almost like an Excel spreadsheet. The item was grayed out on the Internet Explorer 64-bit on Windows 7 64-bit. Solution? Use IE 32-bit. More on the issue here. It has to do with a 32-bit ActiveX control used to render the Datasheet View.

One other interesting item: Both of the IE shortcuts on the Programs menu of Windows 7 x64 are to the 64-bit version; it's somewhat misleading, because one has "(64-bit)" in parenthesis and the other doesn't, so one assumes the one without that is 32-bit. That's not the case. To run 32-bit IE, go to "C:\Program Files (x86)\Internet Explorer\iexplore.exe" and create a shortcut to it on your desktop.

29 January 2012

IE7 and bulleted lists' margins

For a recent project, we noticed that IE7 was giving us fits with unordered lists: It was "hiding" the actual bullet of the item, but showed the text. Some research revealed that it was flushing everything to the left because we had this in our CSS:
#main-content ul{ margin-left:0 }
The solution? Use the hack to reference only IE7 (the hash tag):
#main-content ul{
 margin-left:0;
 /* 
  The next two lines are only visible to IE7. This fixes the 
  issue of IE7 not showing the bulleted items; they were 
  flushed left so far that the bullet was mostly hidden. 
  All other browsers ignore the next two lines.
 */
 #margin:0 5px 0 42px !important; 
 #padding:0; 
}

27 October 2011

SharePoint: Get parent site title

In SharePoint, we can use subsites to handle navigation beyond the 2nd level; let's assume we have a structure such as this:
  • Site Collection Root
    • Site 1: site title - "Products & Software"
      • Subsite A: site title - "Widgets"
        • Subsite AA: site title - "Widget X"
        • Subsite BB: site title - "Widget Y"
    • Site 2
    • Site 3
It often makes sense to show Site 1's title "Products & Software" down that branch of subsites, regardless of how deep you are. This helps users know they're still under "Products & Software". To fetch the root parent's title (Site1, not the Site Collection Root), you have to use a recursive function, thanks to W0ut and help from Stack Exchange:
protected override void OnLoad(EventArgs e)
{
  // To ensure page behaves correctly, must call base.OnLoad(e).
  base.OnLoad(e);

  GetRootTitle();
}

private void GetRootTitle()
{
  string title = string.Empty;

  /* 
     On admin pages, this label object doesn't exist and will throw
     a NullReferenceException if we don't check it before trying
     to use it.
  */
  if (sectionTitle == null) return;

  using (SPSite site = new SPSite(SPContext.Current.Site.ID))
  {
    using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
    {
      title = IterateThroughParentsAndStoreInfo(web, title);
    }
  }

  sectionTitle.Text = title; // Set a label's value to the title.
}

private string IterateThroughParentsAndStoreInfo(SPWeb web, string title)
{
  if (web.ParentWeb != null)
  {
    title = web.Title;
    return IterateThroughParentsAndStoreInfo(web.ParentWeb, title);
  }
  return title;
}
Note the using statements; these ensure there are no memory leaks by disposing of the objects properly and also implicitly handling the try/catch/finally block. The change to W0ut's code is the addition of the OnLoad() handler, which can be either in your master page or page layout. Also, we've added the title variable, which gets set in the recursive function; note that its value is always of the title for the site one before the last. This is because when the web variable's ParentWeb becomes null, we've reached the site collection. This is exactly what we need.

One last thing to note: We do a null check for the label object which will hold the title's value. On some administrative (system) pages, the label isn't rendered so we'll throw a NullReferenceException. Another way to do this is to always add the title label as a new Label(); this way it's always present, regardless of which page we're on.

19 October 2011

IE7 and "Error: Expected identifier, string or number"

IE7 (and earlier versions) have trouble with errant commas in array declarations. Take this code, provided by James Messinger on Stack Overflow:
<script type="text/javascript">
// Replace the normal jQuery getScript function with one that supports
// debugging and which references the script files as external resources
// rather than inline.
jQuery.extend({
   getScript: function(url, callback) {
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;

      // Handle Script loading
      {
         var done = false;

         // Attach handlers for all browsers
         script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
                  this.readyState == "loaded" || this.readyState == "complete") ) {
               done = true;
               if (callback)
                  callback();

               // Handle memory leak in IE
               script.onload = script.onreadystatechange = null;
            }
         };
      }

      head.appendChild(script);

      // We handle everything using the script element injection
      return undefined;
   }, // <-- Unneeded comma which blows up IE7.
});
</script>
IE7 blows up with this error:
Error: Expected identifier, string or number
It took quite a bit of debugging and Google searches to finally understand where the problem was. Note the last comma, after the next-to-last closing curly brace "}," -- this is unnecessary. Modern browsers can handle this, but IE7 chokes. Simply remove the comma and you're good to go. More on this problem on Stack Exchange.

How to hide/show table rows in IE7

If you need to hide a table row (TR), you'd usually use the following:
.hide-tr { display:none; }
The problem develops when you later wish to show the row; simply setting the display to block is insufficient, as the individual cells in the row lose their positions and often get bunched next to each other. Using display:table-row works on most modern browsers, but IE7 ignores that and prefers display:inline-block. So the solution? There are a few ways to fix the problem, as indicated on Stack Exchange. The problem with using visibility:hidden is that the row still takes up space on the page and shrinking its height is a non-trivial task. Another solution involves a method less recommended, using browser and version detection via jQuery. However, it does fix the issue:
if ($.browser.msie && jQuery.browser.version == '7.0'){
  $('.hide-tr').css('display','inline-block');
}
else {
  $('.hide-tr').css('display','table-row');
}
Not a clean solution but it gets the job done :)

Update: An even easier solution: Simply call the jQuery show() method on the object and it's smart enough to apply the appropriate CSS to the object.