Tuesday, April 1, 2014

Related documents with support of quick upload

In this article, I would like to demonstrate how to design a form with related documents and how to link new documents easily by dragging and dropping them onto the form. To build this solution I will use Forms Designer 2.8.8 which contains a new JavaScript function for auto filling metadata of the uploaded documents.

For my "proof of concept" I will use SharePoint calendar and a simple document library, but the instructions below work for any types of list and related library, e.g. issues and wiki pages, employees and job descriptions etc.

First, I created a Calendar and a Document library, added a lookup field into the document library and connected it with the calendar. Next, I ran Forms Designer from the calendar and designed the Edit form:

SharePoint event form with related documents

I distributed the standard event fields on the first tab and put a Related items control onto the second one. I set Render property into 'Client' to make list refresh automatically when the user drops a document on it. Here is the Data source configuration of the Related items control:

Data source of the related items control

As you can see, I selected my documents library as the data source and filtered it by the lookup column. Well, after that I could drop documents onto this area but the lookup column did not fill automatically and new documents disappeared from the view after uploading. And here I used a new JavaScript function, which had been implemented in Forms Designer 2.8.8:

fd.updateDroppedDocuments(container, fieldValues)

container is a jQuery selector of Related items container which may contains one or more Related items controls.

fieldValues is an object containing the default values of fields. Example:

{
    Lookup: GetUrlKeyValue('ID'),
    Status: 'Closed'
}
Note: the field names of the object have to match the internal names of the related library.

First, I assigned a CSS-class called 'related-docs' to my related documents.

Assign CSS-class to the related items control

Next, I put the following code into JS-editor:

fd.updateDroppedDocuments('.related-docs', {
    Event: GetUrlKeyValue('ID')
});

As you can see, I built the jQuery selector based on the assigned CSS-class and set the current event ID as the default value of the lookup field whose internal name is Event.

Ok, now, when the user drops a document onto the second tab, the lookup field is automatically filled with the currently opened event and uploaded documents appear immediately in the related documents section:

Drop documents onto the parent form

Here is the result:

Default value of the uploaded document

Please, note that with help of fd.updateDroppedDocuments function you can pre-fill not only a lookup field but any other fields. As the default values you can use field values from the parent form, constants, query parameters and other values retrievable in JavaScript.

As usual, I will be glad to answer your questions in the comments.

29 comments:

  1. Hi Dimitry, great solution by the way.

    Can't get the updateDroppedDocuments to work reliably. Works most of the time, but skips associating the parentID at times. Can't figure out a pattern to it though.

    Also noticed a 404 on style%20library/formsdesigner/jquery/jquery-1.10.2.min.map.

    Actually the formsdesigner folders (JQuery/Images) seems empty, wondering if it has something to do with it.

    ReplyDelete
    Replies
    1. Think we may have figured it out. We had a event receiver attached which was conflicting with the js trying to add the ID.

      Delete
    2. Ok, I see. With regard to the empty folder, I'd recommend to download the latest version from our website, upgrade the solution and deactivate/activate Forms Designer feature at the site collection level. All the designed forms will continue working properly.

      Delete
  2. Is it possible to set a specific Content Type for the document?

    ReplyDelete
    Replies
    1. Sure, like any other field. Just pass ContentTypeId to fd.updateDroppedDocuments. Here is an example:
      fd.updateDroppedDocuments('.related-docs', {
      ContentTypeId: '0x010100C04107EB3C45C448948ACB77E1668335003214CB77ED825A40A928547E50B49085'
      });

      To get ID of the specific content type, please, go to the document library settings, choose the required content type and copy value of ctype query parameter from the browser command line.

      Delete
  3. Does it work also in Trial version?

    ReplyDelete
  4. Is it possible to get the same functionality also when user uploads a file Clicking on New document link? Seems this works only when documents are dropped.
    Or perhaps it is possible to hide the New item link?

    ReplyDelete
    Replies
    1. Hi,
      You're right, this approach works for dropped documents only. You can hide 'Add new item' by setting Editable property of the Related items control to False in Forms Designer. Or you can hide it via JavaScript as well.

      Delete
    2. Hi Dmitry,
      Is it possible to lock / make read only Related items control in Display Form? I need to prevent adding, editing and deleting related documents from Display Form.

      Delete
    3. Sure, you can turn off Editable property of the Related items control in Forms Designer.

      Delete
    4. I did but it is still possible to drop documents. Just metadata is not filled.

      Delete
    5. Hi,
      Please, put the following JS-code into JS-editor in the display form:

      ExecuteOrDelayUntilScriptLoaded(function() {
      g_uploadType = DragDropMode.NOTSUPPORTED;
      SPDragDropManager.DragDropMode = DragDropMode.NOTSUPPORTED;
      }, "DragDrop.js");

      Delete
  5. This solution updates metadata not only for just dropped documents, but also for other documents with the same name located in different folders. How to restrict overwriting and update only empty lookup fields?

    ReplyDelete
    Replies
    1. Hi Agnese,
      Thank you for the bug report.
      We've fixed the issue. Please, install the latest version of Forms Designer from our website and clear the browser cache.

      Delete
  6. Hi Dmitry,

    this is really a great solution!
    Do you think it is possible to move the uploaded document to a specific folder?
    Maybe with setting FileDirRef or FileRef attribute?

    Thank you in advance

    Felix

    ReplyDelete
    Replies
    1. Hi,
      Unfortunately, you cannot move documents by modifying their metadata. So, I'd recommend you to move them with the help of a workflow or use the Content organizer to route documents automatically based on predefined rules.

      Delete
    2. Hi Dmitry,
      I created an eventreceiver to move the document to a folder after upload. The problem is now, that this happens asynchron so after the partial reload of the related items the item has the original path. A few moments later the item is moved. When the user clicks on the item he gets an error because the item is moved in the background.
      Is it possible to reload the related items control or the complete form after a short delay?

      Delete
    3. I think I solved it with overriding the UploadFinishFunc:
      ExecuteOrDelayUntilScriptLoaded(function() {
      var UploadFinishFuncICOrig = window.UploadFinishFunc;
      window.UploadFinishFunc = function(element, state) {
      var argumentsOrig = arguments;
      UploadFinishFuncICOrig.apply(null, argumentsOrig);
      refreshAfterOneSecond();
      }

      }, 'DragDrop.js');

      Delete
  7. Hi Dmitry,
    I tried to pass a people's picker value but with no success.It worked fine with single line fields and choice fields. Any help would be greatly appreciated.
    (i am using sp2013)

    Thank you,
    Katerina

    ReplyDelete
  8. Can you use form fields to populate values in the dropped document? Or is it restricted to the GetUrlKeyValue('ID') from the actual record?

    ReplyDelete
    Replies
    1. Yes you can. This would fill out SampleColumn with the initial value of the Title field that will be present in it on form load:

      fd.updateDroppedDocuments('.related-docs', {
      SampleColumn: fd.field('Title').value(),
      });

      If you want to have the thing fill out SampleColumn dynamically, i.e. fill out with its current value, do something like this:

      var obj = {
      SampleColumn: fd.field('Title').value(),
      text: "some text",
      }
      function updateObject() {
      obj.SampleColumn = fd.field('Title').value();
      }
      fd.field('Title').change(updateObject);

      fd.updateDroppedDocuments('.related-docs', obj);

      This will update the object every time the Title field is changed.

      Delete
    2. Thanks what works great.

      When trying to upload using the drag and drop, I get the following error when in a Modal/Popup in view mode:

      The file or folder name "*/Document.txt" contains invalid characters. Please use a different name. Common invalid characters include the following: # ? : < > ? / |

      Is there any way to fix that? Id love to have the functionality to be able to quickly upload, without having to go into a record in edit mode.

      Delete
    3. Hi,
      Could you send your script and the detailed description of the issue to support@spform.com.

      Delete
  9. Hello Dmitry,

    thanks for this, works fine for me at EditForm.
    Is there a way to get this done on NewForm?

    Need to handle Attachements to a new list item.

    ReplyDelete
  10. Hello Dimitry,
    This is working fine, but when document library is growing to more than 5000 elements (SharePoint online) the metadata script is not working anymore. Is it a known problem?

    ReplyDelete
    Replies
    1. I've tried to clear cache on Internet Explorer.

      Delete

Note: Only a member of this blog may post a comment.