This project has moved. For the latest updates, please go here.

Expose the list of fields in the form

Feb 11, 2015 at 1:07 PM
Hello KitMenke,

Could you add this method to expose all the fields in the form publicly. This will help me to iterate through the list of fields, and make them in readonly, excepting for some.
SPUtility.GetFieldsHashtable = function() {
    return _fieldsHashtable;
By the way, I had submit you a change request in GitHub last year about a bug on SPFieldUser and some minor change requests. You don't want to accept my merge?
Feb 11, 2015 at 3:51 PM
Oh sorry, I have just seen it already exists: SPUtility.GetSPFields()
Can you add this line in the documentation please ?
Feb 11, 2015 at 9:53 PM
Feb 11, 2015 at 10:09 PM
I have been working on the people fields as well but have been busy. The big thing is I was trying to get it working with 2007 as well but might just release the 2013 version now...

Also, SPUtility.GetSPFields() returns an object right now which might not be best... I think I should be returning an array of field names.
Feb 12, 2015 at 7:45 AM
Thanks for updating the doc and thank you for your library, it's much appreciate.

I have SP 2010 and I can help if you need some assistance.
By the way, I have a BCS field and for the few I have tested, it seems SPFieldBusinessData acts exactly like SPFieldUser.
So for the moment, I have added:
case 'SPFieldUser':
case 'SPFieldUserMulti':
case 'SPFieldBusinessData':
      field = new SPUserField(spFieldParams);
Feb 12, 2015 at 8:33 AM
Edited Feb 24, 2015 at 3:57 PM
I also propose you another version of my previous "Description" property:
SPField.prototype.GetDescription = function () {
        var ctls = this.Controls.parentNode,
        text = $($(ctls).contents().toArray().reverse()).filter(function() {
            return this.nodeType == 3;
        return text.replace(/^\s+/, '').replace(/\s+$/g, '');

SPField.prototype.SetDescription = function (descr) {
        var ctls = this.Controls.parentNode,
        textNode = $($(ctls).contents().toArray().reverse()).filter(function () {
            return this.nodeType == 3;
        descr = descr || '';
        if (textNode.textContent) textNode.textContent = descr;
        else textNode.innerText = descr;
Feb 13, 2015 at 3:50 AM
I did integrate some of your people field changes into the latest 0.10.0 release and gave you a shout out in the changelog. If you can test on SP 2010 that would be very helpful since I don't have easy access to a 2010 environment.

Thanks for your support, I'll take a look at adding Get/Set Description and SPFieldBusinessData.
Feb 14, 2015 at 11:05 PM
I tested GetDescription and SetDescription in SharePoint 2013 and looks like it may work differently than in SharePoint 2010.

In 2013, the description is put in an ms-metadata tag:
<span class="ms-metadata">This is the description of the field.</span>

I will make some updates.
Feb 23, 2015 at 10:03 AM
Edited Feb 23, 2015 at 10:06 AM

I have tested the latest release and the SetDate, SetTime and SetValue work well.
But for the SPUser, I had to fix it.

1) this one is more performant and do not require jQuery. As how you use it, stick with byid (byid = shorthand in SP for document.getElementById)
$('#xxx')[0] -> document.getElementById('xxx')
2) GetValue: need to trim the result because IE returns some whitespaces + linebreak (\u00A0)
3) SetValue: debugging to make it works.

Tested on IE 11 (emulate IE8) & Firefox & Chrome

here is the code:
function SPUserField(fieldParams) {, fieldParams);

        if (this.Controls === null) {

        this.spanUserField = null;
        this.upLevelDiv = null;
        this.textareaDownLevelTextBox = null;
        this.linkCheckNames = null;
        this.txtHiddenSpanData = null;

        var controls = $(this.Controls).find('');
        if (null !== controls && 1 === controls.length) {
            this.spanUserField = controls[0];
            this.upLevelDiv = byid( + '_upLevelDiv');
            this.textareaDownLevelTextBox = byid( + '_downlevelTextBox');
            this.linkCheckNames = byid( + '_checkNames');
            this.txtHiddenSpanData = byid( + '_hiddenSpanData');

    // Inherit from SPField
    SPUserField.prototype = Object.create(SPField.prototype);

    SPUserField.prototype.GetValue = function () {
        return $(this.upLevelDiv).text().replace(/^\s+|\u00A0|\s+$/g, '');

    SPUserField.prototype.SetValue = function (value) {
        this.upLevelDiv.innerHTML = value;
        if (isInternetExplorer()) { // internet explorer
            this.textareaDownLevelTextBox.innerHTML = value;
        } else { // FireFox (maybe others?)
            this.textareaDownLevelTextBox.innerHTML = value;
        return this;
Feb 24, 2015 at 3:46 AM
I integrated your code above and added SharePoint 2013 versions of GetDescription and SetDescription.

Thanks a ton onizet!!! I appreciate all of your testing and contributions a lot.
Feb 24, 2015 at 7:57 AM
Thanks also to you for providing such an useful library. I have also a project on CodePlex and I know how much it's time consuming.

I have also read your comment on gitHub and I'm agree that a rewriting more oriented object may be benefits for everyone.
Mainly when migrating between SP version.

I have recently read an article about VanillaJS and its performance gain ([^] and [^)].
The JS engine in modern browser are quite becomes serious competitors to jQuery...
Do you think it may be interesting to move away from jQuery/PrototypeJS and relies on plain JS ?

I will be happy to assist you in the rewriting if you wish

Feb 24, 2015 at 2:36 PM
Yes I definitely have a much greater appreciation for open source projects after maintaining one myself. :D

I have thought a lot about removing the dependency on jQuery (especially when I got rid of prototype.js). Like you mention we could probably get a performance boost by switching to pure JS but the thing I'm worried about is cross-browser support. Presently I'm supporting 2007/2010/2013 (testing with IE8 in SP 2007 too) so I think we would need to figure out how much work that will be.

Some of the jQuery methods we'd have to replace: next, find, text, each, show/hide, append, children, html, val, on, attr, trim, contents, toArray, reverse, filter.
Feb 24, 2015 at 4:11 PM
I think it's not a big deal as you mainly find and traverse nodes and the 2 links above may greatly help.
There is no more a lot of code required to be cross-browser. The only problem lies in IE8. querySelectorAll is supported but only in normal mode.
Let's me give it a try.

A minor changes to SetDescription to make it work with IE8
SPField.prototype.SetDescription = function (descr) {
        var ctls = this.Controls.parentNode,
        textNode = $($(ctls).contents().toArray().reverse()).filter(function () {
            return this.nodeType == 3;
        descr = descr || '';
        if (textNode.textContent) textNode.textContent = descr;
        else textNode.innerText = descr;
Jul 29, 2015 at 5:43 PM
Edited Jul 29, 2015 at 5:44 PM

When I try to use .MakeReadOnly() property in SPUserField (person or group), then it show this: [object Object].

Could you please help me? ..also, i need to use GetValue() property in SPUserField (person or group), isn't working! ...please, help!

Aug 3, 2015 at 11:40 PM
Hmm.. that seems like a bug to me. I've created an issue for it here:
Aug 6, 2015 at 5:35 AM
KitMenke wrote:
Hmm.. that seems like a bug to me. I've created an issue for it here:
Hi, Kit.

Sorry to bother you, but...any idea to solve this bug?...please, help me!!

Thank you so much!!