Finding the Contents of a SharePoint Rich Text Column with jQuery

I’ve had two questions this week about how to find the contents of a Rich Text column reliably with jQuery. Rich Text columns are rendered in a more complex way than just a nice textarea. Like some of the other column types they are a sort of hybrid, with some HTML elements and some script to hold it all together.

Taking a look at a Rich Text column with the Developer Tools in IE8, all of the gunky HTML below makes up the column. The value in the column is stored in a div inside one of the iframes. So it’s available, but you need to do some digging!

image

There are two spans wrapping everything, and within them there are the following elements:

  • textarea – This textarea contains the previously set value, not the currently edited value.
  • table – This table contains the buttons above the box which allow you to set the formatting.
  • iframe – I’m not exactly sure what this iframe is for; in my test WSS environment, it simply contains the image /_layouts/images/blank.gif that SharePoint uses as a placeholder.
  • div – this div contains the iframe where the real value is.
  • script – Finally, this script block sort of holds everything together.

So, as you can see in the screenshot above, we want to grab the contents of the body inside the iframe inside the div. Make sense?

To do this, we can use the following jQuery:

$("textarea[Title='System Description']").closest("span").find("iframe[Title='Rich Text Editor']").blur(function(){
  alert($(this).contents().find("body").html());
});

The name of my column in this example is System Description. First I find the texarea with System Description as the title. Then I find the closest ancestor which is a span. (I usually prefer to use .closest() rather than .parent() when I can in case anything else ends up inserted between the two elements.) Next I am finding the iframe which has its title attribute set to ‘Rich Text Editor’. That gets me into the right neighborhood. To test this, I decided to alert the contents of the iframe’s body when a blur event is triggered. That will happen when you’re finished editing the System Description (in this case) and my cursor exits the column.

If you’d just like to grab the value, you could use this jQuery. Yes, it’s a bit messy, but it gets the job done!

var systemInformation = $("textarea[Title='System Description']").closest("span").find("iframe[Title='Rich Text Editor']").contents().find("body").html();

p.s. This all works exactly the same in SharePoint 2010 as it does in SharePoint 2007.

15 Comments

  1. Thank you so much for this code. Not only is it important, but it’s needed to fix the prepopulate.js code that we use a lot for passing in variables from a hyperlink from other applications.

    Reply
  2. I am getting the DIV Tag appended to the Rich Text Area field while using the above code in SharePoint 2010.

    I need to find the length of the Rich Text Area field. So the Length is taking this DIV also. So my validation is not working. Please help.

    Reply
  3. Marc,

    Thanks for the blog and the help.I have observed two things.

    When i create a Multi Line text box in SharePoint i have three option Plain Text,Rich Text and Enriched Rich Text.

    Use Case 1:(Rich Text)

    When i select Rich Text Editor for the Multi line text box my HTML is rendered with main frame as mentioned in the above blog .

    I am always getting the DIV appended to the text area in it.Is there a way to get the Text Area without HTML Content.I need the length also.

    Use Case 2:

    When i used Enriched Rich Text Editor for the Mutli line text box my HTML Is rendered with the DIV tags as mentioned in the blog below

    http://sympmarc.com/2013/09/11/setting-a-rich-text-column-in-a-sharepoint-form-with-jquery-sharepoint-2010/

    In this case i am able to get the text area using FindFormField method that you have used.

    When i am trying to check whether the control is having any values i am able to see the Empty string in Alert.

    Validations needed”

    function isBlank(object)
    {

    alert(object.length);
    return (($.isPlainObject(object) && $.isEmptyObject(object)) ||

    ($.isArray(object) && object.length == 0) ||

    (typeof(object) == “string” && $.trim(object) === “”) ||

    (!object)
    );
    };

    var RootCauseField = findFormField(“Root Cause”).find(“.ms-rtestate-write”).text().length;

    var RootCause = findFormField(“Root Cause”).find(“.ms-rtestate-write”).text();

    alert(RootCause);

    alert(“Alertroot” + RootCauseField );

    isBlank(“”) gives me True

    I have debugged the JS code and i am able to see empty string while debugging.

    if(isBlank(RootCauseField)) always false eventhough its empty string.
    {
    alert(“Provide Root Cause while closing the KTI.”);

    return false;
    }

    But the length for the string is always 1 and the empty string condition is not getting satisfied.Is it the expected behavior.How can i check the length and the empty text condition in Enriched Text Editor.

    Please let me know your thoughts.

    Reply
  4. Marc,

    I have a list with three columns named Issue,Root Cause and Resolution Fields.All of them are Enhanced Rich Text Fields.Its a type of ticketing system.When the ticket is closed the support team needs to provide the root cause and resolution for the partilcuar issue.

    I have a Save button in a list.When users click the save button i am checking that the Root Cause(Enhanced Rich Text Fields) and Resolution(Enhanced Rich Text Fields)must be provided while closing a ticket.
    The reason for this is if we get the similar issue in future we dont need to spend time.

    So i need to check Whether the Root Cause and Resolution Fields are Empty while cilcking the save buttpn.

    As i stated earlier i am getting the text area as empty and length of the text area as 1.

    The other problem is when the support memebrs are inserting some pictures(screen shots) since its a Enhanced Rich Text field the length is always 1 and the text area is empty.

    I have two queries:

    1.If the textarea.length=1 then can i ask the user to provide the Root Cause and Resolution.

    2.Even though if i implement the above condition.When users inserts picture it will be always 1 and the validation will again ask the user to provide root cause and resolution.

    Scripts Used:

    // Finds the td which contains a form field in default forms using the comment which contains:
    //
    // as the “anchor” to find it. Necessary because SharePoint doesn’t give all field types ids or specific classes.
    function findFormField(columnName) {
    var thisFormBody;
    // There’s no easy way to find one of these columns; we’ll look for the comment with the columnName
    var searchText = RegExp(“FieldName=\”” + columnName.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, “\\$&”) + “\””, “gi”);
    // Loop through all of the ms-formbody table cells
    $(“td.ms-formbody, td.ms-formbodysurvey”).each(function() {
    // Check for the right comment
    if(searchText.test($(this).html())) {
    thisFormBody = $(this);
    // Found it, so we’re done
    return false;
    }
    });
    return thisFormBody;
    } // End of function findFormField

    function PreSaveAction()
    {

    var thisFieldHtml = findFormField(“Resolution”).find(“.ms-rtestate-write”).html();

    alert(thisFieldHtml);

    var thisFieldText = findFormField(“Resolution”).find(“.ms-rtestate-write”).text();

    alert(thisFieldText);

    alert(thisFieldText.length);

    var thisRootCauseFieldText=findFormField(“Root Cause”).find(“.ms-rtestate-write”).text();

    alert(thisRootCauseFieldText);

    alert(thisRootCauseFieldText.length);

    var env= $(“select[title=’Environment’]”);

    var cio= $(“select[title=’CIO’]”);

    var ktistatus= $(“select[title=’Status’]”);

    var targetRel= $(“select[title=’Target Release’]”);

    if(env!=null)
    {

    if(env.val()==”None”)
    {
    alert(“Provide Respective Environment.”);
    //alert(Issue);
    return false;
    }
    }

    if(cio!=null)
    {

    //alert(cio.val());

    if(cio.val()==”None”)
    {

    alert(“Provide Your CIO.”);
    //alert(Issue);
    return false;
    }
    }
    if(targetRel!=null)
    {
    if(targetRel.val()==”None”)
    {
    alert(“Provide your App Target Release Date.”);
    //alert(Issue);
    return false;
    }
    }
    if(ktistatus!=null)
    {
    if(ktistatus.val()==”Completed”)
    {

    if(thisRootCauseFieldText.length==”1″)
    {
    alert(“Please Provide Root Cause while closing the KTI.”);
    return false;
    }

    if(thisFieldText.length==”1″)
    {
    alert(“Please Provide Resolution while closing the KTI.”);
    return false;
    }

    }

    }
    return true;

    }

    Reply

Have a thought or opinion?