Creating new discussion thread

Jul 25, 2014 at 6:34 PM
First time using SPServices and jQuery, so apologies if this is a real newbie question ...

Am trying to create a new discussion thread and it seems to work for the most part:

function AddNewDiscussionThread(subject, message) {
 $().SPServices({
      operation: "UpdateListItems",
      async: false,
      batchCmd: "New",
      listName: "Document Reviews",
      valuepairs: [["ContentType", "Discussion"],["Title", subject],["Body", message]],
      completefunc: function(xData, Status) {
        console.log(xData.responseText);
      }
 });
}

What I need to do next is get the URL to this new discussion so I can use it as a link in another list. What I've noticed is that when I create a discussion with a title of "foobar" thru the UI via the "new discussion" method), the title is part of the link (e.g., '/sites/mytestsite/Lists/Document Reviews/foobar'), but when using SPServices as above, it's a form of the ID of the newly created row in the discussion list, e.g. '/sites/mytestsite/Lists/Document Reviews/6_.000'.

This is part of the contents of xData.responseText returned when creating the thread, and "6_.000" shows up in a number of returned attributes:

<z:row xmlns:z="#RowsetSchema" ows_WorkflowVersion="1" ows_GUID="{9EFAB873-F1B1-49EA-B139-681918683E95}" ows_Order="600.000000000000" ows__UIVersionString="1.0" ows__UIVersion="512" ows_owshiddenversion="1" ows_SelectTitle="6" ows_FolderChildCount="6;#0" ows_ItemChildCount="6;#0" ows__IsCurrentVersion="1" ows__Level="1" ows_MetaInfo="6;#" ows_BaseName="6_.000" ows_EncodedAbsUrl="https://testserver/sites/mytestsite/Lists/Document%20Reviews/6_.000" ows_ServerUrl="/sites/mytestsite/Lists/Document Reviews/6_.000" ows_LinkFilename2="6_.000" ows_LinkFilename="6_.000" ows_LinkFilenameNoMenu="6_.000" ows__EditMenuTableEnd="6" ows__EditMenuTableStart2="6" ows__EditMenuTableStart="6_.000" ows_ScopeId="6;#{DE6D70AA-7C03-4462-8198-F15CBB8AA1E1}" ows_ProgId="6;#" ows_UniqueId="6;#{DBDA088D-BCAB-44D0-A6E3-1E029B782345}" ows_PermMask="0x7fffffffffffffff" ows_SortBehavior="6;#1" ows_FSObjType="6;#1" ows_Created_x0020_Date="6;#2014-07-25 13:42:07" ows_Last_x0020_Modified="6;#2014-07-25 13:42:07" ows_FileDirRef="6;#sites/mytestsite/Lists/Document Reviews" ows_FileRef="6;#sites/mytestsite/Lists/Document Reviews/6_.000" ows__ModerationStatus="0" ows_Editor="1;#Test User" ows_Modified="2014-07-25 13:42:07" ows_Author="1;#Test User" ows_Created="2014-07-25 13:42:07" ows_ContentType="Discussion" ows_ID="6" ows_ContentTypeId="0x01200200BCDA3E0C60B0F246A3B60998F5FCBC07" ows_Title="Another discussion" ows_FileLeafRef="6;#6_.000" ows_IsRootPost="1" ows_PersonViewMinimal="Test User" ows_PersonImage="Test User" ows_ToggleQuotedText="6" ows_LessLink="6" ows_MoreLink="6" ows_LimitedBody="<div class="ExternalClass838E5E4A64AE429BB7001BC165A41680">Add feedback on this document as a reply to this thread.</div>" ows_FullBody="<div class="ExternalClass838E5E4A64AE429BB7001BC165A41680">Add feedback on this document as a reply to this thread.</div>" ows_QuotedTextWasExpanded="{9EFAB873-F1B1-49EA-B139-681918683E95}" ows_BodyWasExpanded="{9EFAB873-F1B1-49EA-B139-681918683E95}" ows_MessageBody="<div class="ExternalClass838E5E4A64AE429BB7001BC165A41680">Add feedback on this document as a reply to this thread.</div>" ows_BodyAndMore="<div class="ExternalClass838E5E4A64AE429BB7001BC165A41680">Add feedback on this document as a reply to this thread.</div>" ows_StatusBar="2014-07-25T17:42:07Z" ows_ReplyNoGif="sites/mytestsite/Lists/Document Reviews" ows_LinkDiscussionTitle2="Another discussion" ows_LinkDiscussionTitle="Another discussion" ows_LinkDiscussionTitleNoMenu="Another discussion" ows_LinkTitle2="Another discussion" ows_LinkTitle="Another discussion" ows_LinkTitleNoMenu="Another discussion" ows_Attachments="0" ows_IsFeatured="0" ows_DiscussionLastUpdated="2014-07-25 13:42:07" ows_MyEditor="1;#Test User" ows_Body="<div class="ExternalClass838E5E4A64AE429BB7001BC165A41680">Add feedback on this document as a reply to this thread.</div>"/>

I assume I could just use the value returned in ows_ServerUrl for the link in the other list. But "6_.000" also shows up as the thread title when you click the link to open the discussion, which is not very user friendly. So I was wondering if there's another field to include in the valuepairs list when creating the thread to have the result be the same as you get when creating a new thread natively.

Thanks in advance.
Jul 25, 2014 at 6:45 PM
Edited Jul 25, 2014 at 6:48 PM
Actually, as soon as I posted this, I took a shot in the dark and apparently hit the mark. :-\ I noticed a return parameter called ows_BaseName had the '6_.000" value, so since that sounded plausible, I added that to the valuepairs with the same string as the intended subject:

valuepairs: [["ContentType", "Discussion"],["Title", subject],["Body", message],["BaseName", subject]],

And that appears to have used the expect string all throughout, instead of the form of the list ID. :-)

Related to this, can anyone point me to detailed online documentation which lists all of these parameters and data structures? I've been trying to suss them out by using the GetListItems operation for different list types and seeing what comes back, which is somewhat hit or miss (using the same method with this discussion thread returned none of these additional parameters like BaseName). Any help on that is appreciated.
Dec 22, 2014 at 4:11 AM
Dear ShawnC1959 --

Please help.

(1). Could you post your whole page code sample here or somewhere or email it to me at mkamoski AT gmail DOT com please ?

(2). Could you please let me know how to create a new thread in an existing discussion for the item and put a link to it in a list item as the DispForm loads?

I want to load the DispForm for a given list item, and there is the column in the list "Discussion Thread" and if that is not already set then I want to create a new thread and put the link to the thread in the list item and then show the list item in the DispForm. I am hoping that is possible. I need to do everything with jQuery and/or JavaScript and/or SPServices. I am hoping you can help.

Thanks.

Mark Kamoski
Dec 24, 2014 at 4:42 AM
All --

This SPServices library is GREAT and really saves time.

I am going to reply to my own questions above, just in case it helps someone.

Ok, so I figured this out, GEFN, and answered my own questions, with the help of searching other threads here, so this is what I came up with for now, in case anyone is interested, and note that TTL for this code base is less-than 5 months so it is a bit hacky (I know), anyway...
    //Per specs, if valid and if on the NewFormV01 then create a Discussion thread and add Discusion link for this item, because Discussion Link is read-only everywhere else.
    if (myIsValidFlag && getHref().contains(getPageNameForNewFormV01()))
    {
        //Use a helper to get the project name.
        var mySubject = getProjectName();
        var CONST_MAX_LENGTH = 32;

        if (mySubject.length > CONST_MAX_LENGTH)
        {
            mySubject = mySubject.substring(0, CONST_MAX_LENGTH);  
        }

        //Use a helper to make the subject from the first 32 chars of the project name plus a date-time-stamp. 
        mySubject = mySubject + " (" + getDateTimeStringNoSep() + ")";
        var myMessage = "Use this thread for questions-and-answers on the Review Request."; 

        //Use SPServices to create the thread.
        jQuery().SPServices({
            operation: "UpdateListItems",
            async: false,
            batchCmd: "New",
            listName: "Discussions",
            valuepairs: [["ContentType", "Discussion"], ["Title", mySubject], ["Body", myMessage], ["BaseName", mySubject]],
            completefunc: function (xData, Status)
            {
                console.log(xData.responseText);
                var myLink = "";

                //Get the URL from the responseText return value from the SPSevices call.
                jQuery(xData.responseXML).SPFilterNode("z:row").each(function ()
                {
                    myLink = jQuery(this).attr("ows_EncodedAbsUrl");
                });

                //Set the link in this item.
                var CONST_SELECTOR_FOR_VALUE = "input[title='Discussion Link']";
                jQuery(CONST_SELECTOR_FOR_VALUE).val(myLink); 
            }
        });
    }
HTH.

Thanks.

Mark Kamoski
Dec 24, 2014 at 8:38 AM
Edited Dec 24, 2014 at 8:42 AM
Hi Mark. Sorry for not responding sooner, but just saw your original post.

The solution you came up with aligns closely with what I had done:
            var xData_save;
            var Status_save;
            $().SPServices({
                  operation: "UpdateListItems",
                  async: false,
                  batchCmd: "New",
                  listName: "Document Reviews",
                  valuepairs: [["ContentType", "Discussion"],
                               ["FSObjType", "1"],
                            ["Title", newDiscussionTitle],
                            ["Body", "Post comments as replies to this thread after reviewing document. Right-click on &lt;a href=\"" + newDocURL + 
                                "\"&gt;[Link]&lt;/a&gt; and open in a new window to view document properties."],
                            ["BaseName", baseName]],
                  completefunc: function(xData, Status) {
                        xData_save = xData;
                        Status_save = Status;
                  }
            });
            
            if (Status_save != "success") {
                alert("Error creating discussion thread for new document");
                return false;
            }
            var discussionURL;
            $(xData_save.responseXML).SPFilterNode("z:row").each(function() {
                discussionURL = $(this).attr("ows_ServerUrl");
            });
            SPUtility.GetSPField('Review Discussion').SetValue(discussionURL, baseName);
However, using this method resulted in an odd situation which I've still not resolved ... using SPServices to create the thread does so in such a way that only the person who creates it can reply to it. I could not find any obvious difference in the permissions or other settings of this thread compared to one I created "natively" by clicking the "Add New Discussion" button. Also, I included the value pair ["FSObjType", "1"] to the call to UpdateListItems because I read somewhere that threads in discussion boards are really folders (and replies are items within that folder), and that you need FSObjType to be '1' to ensure it's created as a folder, but that didn't seem to make a difference with regard to the reply permission issue.

The only way I was able to get around it was to change the Create and Edit setting (under Advanced Settings for the list); the default setting for a new discussion board list is "Create items and edit items that were created by the user" and I had to change that to the "Create items and edit all items" option so others could reply to a thread someone else created using the code. I really don't know what the difference is between these settings as they don't seem to have any other effect (I was afraid changing it to "Create items and edit all items" meant that someone else could edit or delete the thread you create, but that doesn't seem to be the case).

I did also try using Microsoft's JSOM method to create the discussion thread, SP.Utilities.Utility.createNewDiscussion(), and that seemed to work in that the reply issue no longer existed (I could keep the default setting for the discussion board). However, my problem is that the JSOM library is all asynchronous and, because I needed to get the link to the newly created discussion thread to use elsewhere (this is all being called in the PreSaveItem() function as a new document is being added to a library), there was no easy way to wait around for the asynch call to finish. Since I had something that was working with SPServices and the list setting change, I left it at that.