4

A customer has a added a content type called "New link to a document", which let users add links to other documents, or any other site.
I'm not able to create new items of this content type programmatically using JSOM.
The file seems to be a template located at /_layouts/15/NewLink.aspx.

My current approach is:

  1. Download NewLink.aspx.
  2. Create new file, with contents for NewLink.aspx.
  3. Set URL and ContentTypeId on newly created file.

Creating the file works, but when opening the file I get an error about List not being set in query string.
One work-around is to create a dummy-file, and use this as template instead, this works perfectly (same approach as above).

I found this answer but I didn't understand how it could help me.

Test code

My test-code (which I just run in Chrome console) looks like this:

const templateBase64 = await fetch(`/_layouts/15/NewLink.aspx`, {credentials: 'include'})
  .then(res => res.blob().then(blob => new Promise(resolve => {
    const reader = new FileReader()
    reader.readAsDataURL(blob)
    reader.onloadend = () => resolve(reader.result)
  }))).then(dataUrl => dataUrl.slice(dataUrl.indexOf(',') + 1))

const ctx = SP.ClientContext.get_current()
const list = ctx.get_web().get_lists().getByTitle(listTitle)

const fileCreateInfo = new SP.FileCreationInformation()
fileCreateInfo.set_url('Test.aspx')
fileCreateInfo.set_content(templateBase64)
fileCreateInfo.set_overwrite(true)
const file = list.get_rootFolder().get_files().add(fileCreateInfo)

const fields = file.get_listItemAllFields()
fields.set_item('URL', 'http://google.com')
fields.set_item('ContentTypeId', contentTypeId)

fields.update()

ctx.executeQueryAsync(() =>  console.log('done'), (a, b) => console.log(b.get_message()))

listTitle is title of my document library, and contentTypeId I got from creating a link first and then checking what ContentTypeId it had in ListItemAllFields.

Note

My app is actually a sharepoint-hosted app, so I can't actually reach the file because I have to use GetFileByServerRelativeUrl, which won't work against /_layouts/, but I can get this file locally from the app site, which seems to be identical. But before I try this I want to make it work on host web.

3

Some fieldtypes can't be set by calling set_item with a string. You have to build the corresponding SP.FieldUrlValue object.

Here's a untested draft:

let ctx = SP.ClientContext.get_current(); // or SP.ClientContext('url')
let web = ctx.get_web();
let parentFolder = web.getFolderByServerRelativeUrl('websites/web/yourllib');

let fileCreateInfo = new SP.FileCreationInformation();
fileCreateInfo.set_url('filename.txt');
fileCreateInfo.set_content(new SP.Base64EncodedByteArray());

/*  Some fieldtypes can't be set by calling `set_item` with a string. You have to build the corresponding `SP.FieldUrlValue` object.  */
let fuv = new SP.FieldUrlValue();
fuv.set_url('yourUrl');
fuv.set_description('yourDescription');

let file = parentFolder.get_files().add(fileCreateInfo);
let fields = file.get_listItemAllFields();
fields.set_item('URL', fuv);

ctx.executeQueryAsync(() => {
  // success
  console.log('Success!');
}, (sender, args) => {
  // fail
  console.log('Fail!', args.get_message());
});
  • Nice catch, but I just tried my test-script using SP.FieldUrlValue, but I got the same error – eirikb Mar 5 '17 at 20:56
  • What is the error message? – Mx. Mar 5 '17 at 20:58
  • The same error as I mentioned in my original question "List not being set in query string." (it's not the exact error since it is localized). – eirikb Mar 5 '17 at 21:06
  • Also, I mentioned it works if I copy an existing link (simply point to a link in the library instead of /_layouts/15/NewLink.aspx), and then I can set a new URL using a string. – eirikb Mar 6 '17 at 5:45
1

Without JSOM, you can add the "Link to Document" content type to a library. Perhaps they reinvented the wheel?

  • 1
    When you say "with JSON", so you mean REST? And the content type is already added, I'm struggling with adding a new file with that content type. – eirikb Mar 2 '17 at 14:03
0

The bounty deadline is creeping up, and so far I haven't gotten a satisfactory answer, and until anything better comes up I'm going to post my workaround/hack as a solution.

  1. Manually create a new document link, call it "dummy.aspx" and set the URL to anything.
  2. When user wants to create a new link copy "dummy.aspx" to the new file with JSOM and set correct URL.

It's a bad workaround, but it's the only one I've found so far.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.