Regex Selector for jQuery by James Padolsey FTW

In researching how to fix the issue with Office 365 Update Changes ‘Display Name’ on Required Fields in SPServices, I came across some true awesomeness from James Padolsky (@).

jQuery is eminently extendable, and people do it all the time by creating plugins, additional libraries, etc. After all, it’s all just JavaScript, right? However, I’ve never seen such a nicely packaged selector extension as what James has done with his :regex extension.

In his Regex Selector for jQuery, James has given us exactly what we need to get around this nasty ” Required Field” thing.

jQuery.expr[':'].regex = function(elem, index, match) {
  var matchParams = match[3].split(','),
    validLabels = /^(data|css):/,
    attr = {
      method: matchParams[0].match(validLabels) ?
        matchParams[0].split(':')[0] : 'attr',
        property: matchParams.shift().replace(validLabels,'')
    },
    regexFlags = 'ig',
    regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags);
  return regex.test(jQuery(elem)[attr.method](attr.property));
}

By adding this nice little chunk of JavaScript into SPServices, I get a nice, clean way to implement a fix. In the snippet of code below from the DropDownCtl function in SPServices, I can maintain backward compatibility (all the way back to SharePoint 2007 – WSS 3.0, even)

// Simple, where the select's title attribute is colName (DisplayName)
//  Examples:
//      SP2013 <select title="Country" id="Country_d578ed64-2fa7-4c1e-8b41-9cc1d524fc28_$LookupField">
//      SP2010: <SELECT name=ctl00$m$g_d10479d7_6965_4da0_b162_510bbbc58a7f$ctl00$ctl05$ctl01$ctl00$ctl00$ctl04$ctl00$Lookup title=Country id=ctl00_m_g_d10479d7_6965_4da0_b162_510bbbc58a7f_ctl00_ctl05_ctl01_ctl00_ctl00_ctl04_ctl00_Lookup>
//      SP2007: <select name="ctl00$m$g_e845e690_00da_428f_afbd_fbe804787763$ctl00$ctl04$ctl04$ctl00$ctl00$ctl04$ctl00$Lookup" Title="Country" id="ctl00_m_g_e845e690_00da_428f_afbd_fbe804787763_ctl00_ctl04_ctl04_ctl00_ctl00_ctl04_ctl00_Lookup">
if ((this.Obj = $("select[Title='" + colName + "']")).length === 1) {
  this.Type = "S";
// Simple, where the select's id begins with colStaticName (StaticName) - needed for required columns where title="colName Required Field"
//   Examples:
//      SP2013 <select title="Region Required Field" id="Region_59566f6f-1c3b-4efb-9b7b-6dbc35fe3b0a_$LookupField" showrelatedselected="3">
} else if ((this.Obj = $("select:regex(id, (" + colStaticName + ")(_)[0-9a-fA-F]{8}(-))")).length === 1) {
  this.Type = "S";

The regex I need to use isn’t too complicated, and the best part is that I can use it right in a jQuery selector with the :regex extension. Here I’m looking for an id which starts with the column’s StaticName followed by an underscore (_) and then 8 hexadecimal characters [0-9a-fA-F] and then a dash (-). That ensures that I’m finding the right id without the greedy selection issues on the title I may run into using some of the other methods people have suggested.

This fix is in the latest alpha of 2014.01, which is named 2014.01ALPHA2. I think that this will be the winning fix, and I’ve already gotten some positive feedback from folks who have tested it. If you have the issue and could test as well, I’d appreciate it. Because the DropDownCtl is the one function I use to find dropdowns for all of the other SPServices function, this should fix all of them.

Now, if we could just get the SharePoint Product Group to stop messing with our markup!

Similar Posts

4 Comments

  1. I’m surprised there are no comments on this! I haven’t implemented this yet but this looks like the best substitution possible! Considering how many lines of code have to change, might as well change them to something that is more reliable and consistent! The only question in my mind, is this should prevent any “false positives” since the static name is unique within a list, right?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.