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

Multi-line Field GetValue() not working

description

Hello,

I am trying to compare the old and new values of all of the fields in a list to see if the "as of date" field needs to be updated. When I load the list, I am capturing the value of each field. For some reason my multi-line fields are coming up empty.
$(document).ready(function()
{
  var getValues = function()
  {
    //all of the other fields
    progPer   = SPUtility.GetSPField('Progress This Period');
    progPerVal    = progPer.GetValue();
    //the rest of the fields
  }
  a bunch of other code
  getValues();
});
The call inside of PreSaveAction() works fine and captures the value correctly and it's basically identical except for the variable name.
checkprogPerVal = progPer.GetValue();
Is is something to do with document.ready? Should I set the initial values elsewhere?

comments

n30t3h1 wrote May 23, 2016 at 4:12 PM

Ok, so I figured out that I should be putting them in $(window).load instead. However, there are two fields that are being captured properly and two fields that are not. They are all multi-line RTFs, so I am not sure what is going on.

n30t3h1 wrote May 24, 2016 at 6:50 PM

UPDATE: I figured out, that only the first two multi-line fields are being captured. If I change the column ordering then the previously captured fields stop working and visa versa. What could be causing this?

KitMenke wrote May 27, 2016 at 2:20 PM

Hmm tested this out real quick and it was working ok for me. Here is the code I was using for testing:
  var beforeValues, afterValues;

  function getAllValues() {
    var fields = SPUtility.GetSPFields();
    var values = [];
    for (var name in fields) {
       if (fields.hasOwnProperty(name) && name !== 'Attachments') {
          values.push({
            'name': name,
            'value': SPUtility.GetSPField(name).GetValue()
          });
       }
    }
    return values;
  }
  
   // wait for the window to load
   $(window).load(function () {
      try {
        console.log("Started!");
         var count = 0;
         beforeValues = getAllValues();
      } catch (e) {
         if (typeof console === 'undefined') {
            alert(e);
         } else {
            console.log(e);
         }
      }
   });

   function PreSaveAction() {
     console.log("Inside PreSaveAction");
     try {
       afterValues = getAllValues();
       if (afterValues.length !== beforeValues.length) {
         console.log("Not the same number of values!");
         return false;
       }
       for (var i = 0; i < beforeValues.length; i++) {
         if (beforeValues[i].name !== afterValues[i].name) {
           console.log("Something went wrong, name is different", beforeValues[i].name, afterValues[i].name);
         }
         if (beforeValues[i].value !== afterValues[i].value) {
           console.log("Something changed:", beforeValues[i].name, beforeValues[i].value, afterValues[i].value);
         } else {
           //console.log("No change:", beforeValues[i].name);
         }
       }
     } catch (e) {
       console.log(e);
     }
     return false;
   }

n30t3h1 wrote Jun 1, 2016 at 6:29 PM

I was able to test this code and it's still not working. I think part of the issue is that I have several different field types, including dates and checkbox fields.
  • When comparing two dates with strict (not) equal it doesn't compare correctly due to them being objects.
  • The checkbox field does not compare correctly either.
In other words, I am getting false positives on non-single line or dropdown fields.

Finally, the multi-line fields are still not being captured. This feels like it is something more local. Could I attach a handler on these that captures them when the user clicks inside? I know this probably isn't the best solution, but it's all I can think of.

KitMenke wrote Jun 2, 2016 at 1:34 AM

Yep you'll have to handle the comparisons differently depending on the type of field. It would be nice if this were easier so I logged an issue.

Any chance you could you share your full code? If you don't want to post it publicly, you can email me via my blog.

n30t3h1 wrote Jun 7, 2016 at 4:27 PM

How would I attach a listener to the multi-line field similar to a dropdown field? I think we can safely assume that if they don't click in a field (and I don't have any functions changing said fields) then they haven't changed.

I have gotten this to work multiple times:
$(myDropdown.Dropdown).change(function(){});
However this (and any other field type) alludes me:
$(myMultiLine.'MultilineEquivalent'.onfocus(function(){});
Finally, is there a library or documentation available specific to this? Google is failing me.

KitMenke wrote Jun 9, 2016 at 12:45 AM

I haven't tried to attach a listener to a Rich Text field before but it might get tricky. Multi-line fields come in a couple of different varieties based on your version of SharePoint and whether or not you're using plain text or rich text.

If you're using plain text multi-line fields then it is easy because they use a textarea which you can attach a listener to just like you did for dropdowns like this:
$(myDropdown.Textbox).change(function(){});

The rich text fields quickly get more complicated. In order for SPUtility.js to work I had to read a lot of the SharePoint javascript code to figure out how they worked. For example, if you're using an "enhanced" rich text field there are two properties: Textbox and ContentDiv. You might be able to attach the listener to the textbox here and see if that works.

Take a look at SPEnhancedNoteField in the source code.

KitMenke wrote Jun 9, 2016 at 12:48 AM

Regarding the documentation, jQuery docs are good for finding out what elements it can attach listeners too and how they work.

There isn't really any solid documentation for how SharePoint fields work but you can take a look at the SPUtility.js source to find out what I know. :)