In this article I will show how to tag a file in IBM Smartcloud using the JavaScript API.
Introduction
Following on from the previous article on how to load a file into Smartcloud we will start from the point of the fileId has been returned to the screen via the upload partial refresh.
Hang on what about the Java API?
Good question, I knew it was on your mind…….so there is a method to update a tag on a community file – but it is broken in the most recent version of Smartcloud. It has actually been fixed in the most recent GitHub version of the code but it is not available for download as of April 2015.
The bug is reported here https://github.com/OpenNTF/SocialSDK/issues/1624. The method SHOULD be updateCommunityFileMetadata and with that we could add TAGs as Metadata. That would be simple to add to the end of the “addFile” Java method. But alas we cannot.
Back to the Front End…..
So we have the file uploaded and we have the fileId. Looking at the Playground example code we can see the code for “Tagging” a file through the JavaScript API looks like this.
require([ "sbt/connections/FileService", "sbt/dom", "sbt/json" ], function(FileService, dom, json) { var fileService = new FileService(); var fileId = "%{name=sample.communityFileId|helpSnippetId=Social_Files_Get_Community_Files}"; var communityId = "%{name=sample.fileCommunityId|helpSnippetId=Social_Communities_Get_My_Communities}"; fileService.updateCommunityFileMetadata({ id : fileId, label : "New Label" + (new Date()).getTime(), summary : "New Summary", visibility : "public" }, communityId).then(function(file) { dom.setText("json", json.jsonBeanStringify(file)); }, function(error) { dom.setText("json", json.jsonBeanStringify(error)); }); });
In my example I return all the values I need back to the front end via the partialRefresh. The import parts at the fileId and the docId of the document. Using a class selector in jQuery I am able to extract these values when it comes time to do the tagging.
<xp:div id="fileIdWrapper" styleClass="row"> <!-- fileId--> <xp:div id="fieldId" styleClass="fileId"> <xp:div> <xp:text escape="true" id="computedField1"> <xp:this.value><![CDATA[#{javascript:viewScope.get("fileId");}]]></xp:this.value> </xp:text> </xp:div> </xp:div> <!-- docId--> <xp:div id="div1" styleClass="docId"> <xp:text escape="true" id="computedField2"> <xp:this.value><![CDATA[#{javascript: document1.getDocument().getUniversalID();}]]></xp:this.value> </xp:text> </xp:div> </div>
To trigger this tagging after the partialRefvresh I wrap it all in a function, and call that function in the onComplete event of the partialRefresh.
The final code looks something like this for the button
<xp:button value="Add File" id="button1"> <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="fileIdWrapper"> <xp:this.action><![CDATA[#{javascript: var uuid = compositeData.get('communityUuid'); com.psclistens.sbt.Utils.addFile(uuid);} ]]></xp:this.action> <xp:this.onComplete><![CDATA[ tagFile(); ]]></xp:this.onComplete> </xp:eventHandler> </xp:button>
and then for the actual tagFile function
function tagFile(){ require([ "sbt/connections/FileService", "sbt/dom", "sbt/json" ], function(FileService, dom, json) { var fileService = new FileService(); var fileId = $('.fileId').text().trim(); var docId = $('.docId').text().trim(); var fileTitle = $('.fileTitle').text().trim(); var communityId = $('.communityId').text().trim(); var tagArray = []; tagArray.push(docId) fileService.updateCommunityFileMetadata({ id: fileId, tags: tagArray }, communityId).then(function(file) { dom.setText("json", json.jsonBeanStringify(file)); }, function(error) { dom.setText("json", json.jsonBeanStringify(error)); }); }); }
One the file it loaded into Smartcloud it is then tagged with the docId of the document back in my XPages application. In this way we can start to see how tying the Smartcloud attachment back to the XPages application becomes possible.
Conclusion
Unfortunately due to a bug in the currently release of SBT we are unable to use the Java API (unless we want to mess with it ourselves, which I don’t), so we have to use the JavaScript API. It means more code, but it is also more learning which is always good.
