This project has moved and is read-only. For the latest updates, please go here.

Reference field by InternalName

Feb 5, 2014 at 9:48 AM
Hi KitMenke,


Just a quick question? Why do you reference the fields by their display name instead of their internalName ? I'm wondering if there is a particular reason because the display name can be changed anytime but never its static/internal name.

I'm following your project from many years but sadly never used it (due to its lack of support for jQuery). But now it has changed :-)

In the past, I'm used to rely on this code which is more raw: (note: it's a slight modification from the popular getTagFromIdentifierAndTitle method)
function getTagFromIdentifierAndTitle (tagName, identifier, fieldName) {
    fieldName = "FieldInternalName=\"" + fieldName + "\"";
    var field = null;
    $("#onetIDListForm " + tagName + "[id$=" + identifier + "]").each(function () {
       if ($(this).closest('td').html().indexOf(fieldName) > 0) {
          field = this; return false;
       }
    });

    return field;
}

getTagFromIdentifierAndTitle("input", "onetidIOFile", "fileLeafRef")
getTagFromIdentifierAndTitle("select", "DropDownChoice", "Relationship");
Will you change in the future or stick with display name ?
Feb 5, 2014 at 2:56 PM
Great question onizet and thanks for following the project. :)

The short answer is.. I've been busy and just haven't added that feature yet. It has been on my list but getting the different field types working took priority. Looks like I need to move it up the list! :)
Feb 5, 2014 at 3:13 PM
no worry, I works nevertheless :-)
I know how working on free project could be time-consuming :-)

thank you and good job!
Apr 25, 2014 at 6:03 PM
I agree about the internal names. I was working on this method to scrape the form and get internal and display names and the label and control cells all in one pass:
   function lazyLoadSPFields() {
      if (null === _fieldsHashtable) {

        _isSurveyForm = false;
        _fieldsHashtable = {};
        
        $("table.ms-formtable > tbody > tr").each(function() {

            var labelCell = $(this).children()[0];
            
            elemLabel = $(labelCell).children()[0];
            if (null === elemLabel || elemLabel.nodeName === 'NOBR') {
               return null; // attachments row not currently supported
            }
            
            var controlCell = $(this).children()[1];

            var match = controlCell.innerHTML.match(/FieldName=\"(.*)\"/);
            if ((match === undefined) || match === null) return;
            var displayName = match[1];

            var match = controlCell.innerHTML.match(/FieldInternalName=\"(.*)\"/);
            if ((match === undefined) || match === null) return;
            var internalName = match[1];

            var match = controlCell.innerHTML.match(/FieldType=\"(.*)\"/);
            if ((match === undefined) || match === null) return;
            var fieldType = match[1];

            var label = $.trim($(labelCell).text());
            var isRequired = label.lastIndexOf(' *') === (label.length - 2);        
            
            var fieldParams = {
                'name': displayName, // compatibility 
                'displayName': displayName,
                'internalName': internalName,
                'label': $(elemLabel),
                'labelRow': this,
                'labelCell': labelCell,
                'isRequired': isRequired,
                //'controlsRow': isUndefined(surveyElemTD) ? null : $(surveyElemTD.parentNode),
                //'controlsCell': isUndefined(surveyElemTD) ? null : surveyElemTD,
                'controlsCell': controlCell,
                'type': fieldType, // compatibility 
                'fieldType': fieldType,
                'spField': null
            };

            _fieldsHashtable[fieldParams.name] = fieldParams;
        });     
 
      }
   }
Apr 26, 2014 at 6:18 PM
Vinny,
Awesome looks like you have a good start. I haven't implemented this yet because I was having issues with this in older versions of IE because it had to iterate over all of the form fields to parse internal name and type... which resulted in the page loading extremely slowly. To fix this, I implemented the lazy loading so it only had to iterate over the display names and then dynamically creates the SPField only when it is needed.

Thinking about this again, it seems like this isn't as much of an issue anymore with SharePoint 2013 and newer browsers. However, I'm not sure I want to remove the lazy loading entirely.

I'm thinking about adding a new method to support internal column names but not quite sure what that would be yet. I logged an issue here so I don't lose track of this: https://github.com/kitmenke/sputility/issues/8
Thanks,
Kit
Apr 27, 2014 at 8:34 AM
I haven't looked into performance yet - will need to do that.

I need to loop through all fields when the form opens because I want to wrap the descriptions into an information icon tooltip, something like this:
var desc = $(inputRow).contents() // get the span containing the inputs
    .css("display", "inline-block") // make the span inline-block so the information tooltip will position correctly
    .prop("required", required) // for jquery validate
    .filter(function() {return (this.nodeType === 3 || this.nodeName === "BR")}) // get all text after the span, this is the field description
    .remove() // remove it from beneath the span
    .map(function () (return $(this).text()}) // ech line is a seperate child so join the lines back together
    .get()
    .join ("<BR">)
    .replace("/\'/g, "&quot;");
if (desc) {
    $(inputRow).append('<span style="overflow: hidden; height 16px; width: 16px; display: inline-block; position: relative; vertical-align: middle">' 
        + '<img class="fieldInfo" title="' + desc + '" style="border-width: 0px; position: absolute; left: 0px !important; top: -33px !important" src="/layouts/images/fgimg.png">';
}
$('img.fieldInfo').tooltip({
    position: { my: 'left-80 top-10', at: 'right center' },
    content: function() { return $(this).attr('title') }
});
I also want to pass in options to hide fields on start:
if (!require && ($.inArray(internalName, options.hiddenFields) != -1)) {
  $(this).hide();
 return;
}
May 9, 2014 at 5:39 AM
You probably already have a solution working, but I wanted to let you know that I've added a new method in the latest version of SPUtility (0.9.1) to support getting fields using their internal name.

For example: SPUtility.GetSPFieldByInternalName('Date_x0020_and_x0020_Time');
May 9, 2014 at 9:05 AM
Cool, nice work :)