Pnpjs: Cannot set title of list part, title property ignored and property HtmlPropertiesData is not on ClientsideWebpart class

Created on 7 Jan 2021  路  1Comment  路  Source: pnp/pnpjs

Category

  • [ ] Enhancement
  • [ ] Bug
  • [X] Question
  • [ ] Documentation gap/issue

Version

Please specify what version of the library you are using: [ 2.0.13 ]

Please specify what version(s) of SharePoint you are targeting: [ SPO ]

Expected / Desired Behavior / Question

I want to be able to set the title of a clientside List Part. Even if I set the title (to "Downloads" in the example) like this, the webpart does not show this title but instead the selected folder name:

        // Documents WebPart (Downloads)
        const partDefListWebPart = partDefs.filter(c => c.Id === "f92bf067-bc19-489e-a556-7fe95f508720");
        if (partDefListWebPart.length < 1) {
            // we didn't find it so we throw an error
            reject(new Error("Could not find list web part"));
        } else {
          // Get values needed for setting up the webpart
          const serverRealtiveWebUrl: string = (await sp.web.get()).ServerRelativeUrl;
          const library = await sp.web.lists.getByTitle(ticketsDocumentLibraryTitle).select("Id", "RootFolder/ServerRelativeUrl").expand("RootFolder").get();
          const selectedListId: string = library.Id;
          const selectedListUrl: string = library.RootFolder.ServerRelativeUrl;
          const webRelativeListUrl: string = selectedListUrl.substring(serverRealtiveWebUrl.length);
          const selectedFolderPath: string = this.getTicketPageFolderNameForTicketNumber(ticketNumber);
          // Create webpart from definition
          listPartDocuments = ClientsideWebpart.fromComponentDef(partDefListWebPart[0]);
          listPartDocuments.title = "Downloads";
          listPartDocuments.setProperties({
            title: "Downloads",
            isDocumentLibrary: true,
            selectedFolderPath: selectedFolderPath,
            selectedListId: selectedListId,
            selectedListUrl: selectedListUrl,
            webRelativeListUrl: webRelativeListUrl,
          });
        }

Observed Behavior

Title set is not being displayed on the page. Title property of WebPart is correctly set and stored. When I manually change the webpart title in a Browser I see that the new title is not stored in the title property but rather in a property called HtmlPropertiesDatawhich looks like:
<div data-sp-prop-name="listTitle" data-sp-searchableplaintext="true">Downloads</div>
It looks like we cannot set this property using PnP JS.

Looks like this is a speciality of the list part (maybe only when we set a 'selectedFolderPath'?). Is there any way to set the list part title using JavaScript?

documentation answered question

Most helpful comment

You can accomplish this by creating a wrapper class and adding a property for the title. I am also updating the docs with this example.

import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import { ClientsideWebpart } from "@pnp/sp/clientside-pages";

// we create a class to wrap our functionality in a reusable way
class ListWebpart extends ClientsideWebpart {

  constructor(control: ClientsideWebpart) {
    super((<any>control).json);
  }

  // add property getter/setter for what we need, in this case "listTitle" within searchablePlainTexts
  public get DisplayTitle(): string {
    return this.json.webPartData?.serverProcessedContent?.searchablePlainTexts?.listTitle || "";
  }

  public set DisplayTitle(value: string) {
    this.json.webPartData.serverProcessedContent.searchablePlainTexts.listTitle = value;
  }
}

// now we load our page
const page = await sp.web.loadClientsidePage("/sites/dev/SitePages/List-Web-Part.aspx");

// get our part and pass it to the constructor of our wrapper class
const part = new ListWebpart(page.sections[0].columns[0].getControl(0));

part.DisplayTitle = "My New Title!";

await page.save();

>All comments

You can accomplish this by creating a wrapper class and adding a property for the title. I am also updating the docs with this example.

import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import { ClientsideWebpart } from "@pnp/sp/clientside-pages";

// we create a class to wrap our functionality in a reusable way
class ListWebpart extends ClientsideWebpart {

  constructor(control: ClientsideWebpart) {
    super((<any>control).json);
  }

  // add property getter/setter for what we need, in this case "listTitle" within searchablePlainTexts
  public get DisplayTitle(): string {
    return this.json.webPartData?.serverProcessedContent?.searchablePlainTexts?.listTitle || "";
  }

  public set DisplayTitle(value: string) {
    this.json.webPartData.serverProcessedContent.searchablePlainTexts.listTitle = value;
  }
}

// now we load our page
const page = await sp.web.loadClientsidePage("/sites/dev/SitePages/List-Web-Part.aspx");

// get our part and pass it to the constructor of our wrapper class
const part = new ListWebpart(page.sections[0].columns[0].getControl(0));

part.DisplayTitle = "My New Title!";

await page.save();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

SpliceVW picture SpliceVW  路  3Comments

pavan2920 picture pavan2920  路  3Comments

simonagren picture simonagren  路  3Comments

AJIXuMuK picture AJIXuMuK  路  3Comments

jcosta33 picture jcosta33  路  3Comments