Contents
- Retrieving the ecm.model.ContentItem from the ecm.model.item
- Get a document by path
- Retrieve a document absolute path
- Test if an item is document or a folder
- Test if a document is locked
- Get the class of a document
- Get the content of the document into a JavaScript variable
- Get attributes (properties) of a document
- Add/Check In a document.
- Check in a JavaScript variable
Retrieving the ecm.model.ContentItem from the ecm.model.item
repository.retrieveItem(documentOrFolderId, function (contentItem) { // Do something with the ContentItem }); repository.retrieveItem(folderPath, function (contentItem) { // Do something with the ContentItem });
Note: Unlike the documentation says, that does not work with an document path (see this), only with a folder path. However that works with both Document and Folder ID.
Example:
repository.retrieveItem(item.id, function (contentItem) { // Do something with the ContentItem }); repository.retrieveItem('/Folder/MySubFolder', function (contentItem) { // Do something with the ContentItem });
Get a document by path
Since it is not possible to use the retrieveItem function to retrieve an item by path, here is a work around. However a more efficient way would be to implement your own service calling Factory.DocumentfetchInstance and return it. But this way does not require any extra work:
getItemByPath: function (itemPath, repository) { var def = new Deferred(); var parentPath = itemPath.substring(0, itemPath.lastIndexOf("/")); var itemName = itemPath.substring(itemPath.lastIndexOf("/") + 1, itemPath.length); repository.retrieveItem(parentPath, function (item) { item.retrieveFolderContents(false, function (resultSet) { if (!resultSet.items || resultSet.items.length == 0) { def.resolve(null); } else { def.resolve(resultSet.items[0]); } }, null, null, true, null, "", item, {type: "AND", conditions: [ {name: "{NAME}", condition: "endWith", value: itemName}, {name: "{NAME}", condition: "startWith", value: itemName} ]}); }, 'Folder'); return def.promise; }
Retrieve a document absolute path
The way to do that is the following, but it can get a bit tricky and I’ll explain why just after the code.
getAbsolutePath: function (item) { var res = "", current = item; while (current && !current.rootFolder) { res = "/" + current.name + res; current = current.parent; } if (res == "") { res = "/"; } return res; }
Now the problem is that in order for this to work, the item needs to be connected to a parent, meaning it needs to come from the content view or the tree. This will be true if you are using the item in a context action, it won’t if you are retrieving the document from the repository (retrieveItem). That makes sense because in FileNet, a document doesn’t have to be filed in a folder or can be in several so what would be the parent? You can get all of them by retrieving the FoldersFiledIn though. So if you are retrieving an item from the server, you will have to set the parent manually (item.parent=aFolderContentItem) after retrieval to set a context for your item.
Test if an item is document or a folder
var isFolder = item.isFolder();
JSDoc, item can be an ecm.model.Item, it doesn’t have to be an ecm.model.ContentItem.
Test if a document is locked
var isLocked = item.locked; var lockedUser = item.lockedUser
JSDoc and JSDoc, item can be an ecm.model.Item, it doesn’t have to be an ecm.model.ContentItem.
Get the class of a document
item.getContentClass()
JSDoc, item needs to be an ecm.model.ContentItem.
Get the content of the document into a JavaScript variable
For obvious readon, document’s content are not fetch in the ContentItem objects. However, some times when working with small text document, it can be nice to get the content to analyze it or display it to the user. You can do this using the following code:
xhr(item.getContentUrl(), { handleAs: "text" }).then(function (data) { // Do something with the handled data }, function (err) { // Handle the error condition }, function (evt) { // Handle a progress event from the request if the // browser supports XHR2 });
Get attributes (properties) of a document
To get the attributes (properties) of a document, use:
item.retrieveAttributes(function (resItem) { // It actually returns the item, but with the attributes member fully fetched // You can now access your property via resItem.attributes.propName }, false, false, function () { // What to do if an error occurred });
The attributes member is not an array, but an object looking like this:
Add/Check In a document.
There is two ways to add/check in a document with ICN, using a pure JS model, or using the FileTracker applet. Since applets are not the most portable things, I would advice against using the applet. However if you are using the applet to locate the file (which I have to say is pretty convenient for the user, especially if you are writing a multi check in wizard), then you will have to use the File Tracker applet to check in the documents since it does not provide a W3C File object. For the add however, I don’t really see the point, except if you like the Java File Chooser better of the Browser one or the D&D…
Using the JS model
ecm.model.Repository.addDocumentItem(parentFolder, objectStore, templateName, criterias, contentSourceType, mimeType, filename, content, childComponentValues, permissions, securityPolicyId, addAsMinorVersion, autoClassify, allowDuplicateFileNames, setSecurityParent, teamspaceId, callback, isBackgroundRequest, onError, compoundDocument) ecm.model.ContentItem.checkIn(templateName, criteria, contentSourceType, mimeType, filename, content, childComponentValues, permissions, securityPolicyId, newVersion, checkInAsMinorVersion, autoClassify, callback)
Add and CheckIn JSDoc, but the doc miss some information so let’s detail that together:
That adds/checks in this item to the repository using the content stream. Parameters are quite the same for both method so let’s detail them all together
Parameters:
- parentFolder (add only): the ContentItem of the folder where to file the new document
- objectStore (add only): the object store to use to add the document. You can use repository.objectStore to get it.
- templateName: The item’s content class name.
Be careful there, despite the name, this is NOT the entry template name, but as it is said here it’s the class’ id. If you want to checkIn using an entry template, you’ll have to set the property EntryTemplateId in the criterias. - criteria: An array of property values to be set on checkin.
Properties you want to set, if property exists for the item but is not in this array, it will be left untouch. Meaning you can send an empty array if you don’t want to change any property. Here what this property looks like. This is an array of Criteria item (this is not a class, just an object):
- contentSourceType: A string value holding the content source type.
- “Folder”
- “Document”
- “Item” (no content)
- “ExternalURL” (FileNet P8 only)
- mimeType: A string value holding the MIME Type of the content.
You can also leave this empty (“”) and the content engine will figure out the correct value if it can. - filename: A string value holding the file name of the content.
- content: The file content stream.This a W3C File object, that looks like this:
You can also use the BLOB straight if you need, we’ll see this in the section how to check in a JavaScript variable. - childComponentValues: An array of child component values. (Content Manager only). If you don’t care about that, just send an empty array ([]).
- permissions: The permissions of the object.
This is an array of permission object. If you leave it null on check in, it will keep the current version’s permissions, you have to provide it on add, you can use either the entry template permissions if you are using one, or the user choices.This array is usually produced by the AddDocumentPropertiesPane or a PropertiesPane you’re using in your custom wizard. In case you need at some point to set this, here what the permission array looks like:
- securityPolicyId: A string holding a security policy id. (FileNet P8 only. This value can be null.).
Security policies are rules to automatically change permissions when creating new versions (release, minor, deprecated…). You can just leave this null. - newVersion: A boolean value indicating whether to create a new version. (Content Manager only).
Not for P8, P8 will create a new version anyway. Leave it null. - checkInAsMinorVersion: A boolean value indicating whether the item should be checked in as a minor version. (FileNet P8 only).
Tells P8 to create a minor a major version. It depends of your need. Usually it is good to use the repository configuration on this (repository.checkinAsMajorVersion) or at least pre check the checkbox (or not) if you are letting the user set this. - autoClassify: A boolean value indicating whether the item should be auto-classified. (FileNet P8 only)
Autoclassify is used to set class and properties automatically when addig document. This is really important when adding document, I’m not sure it really matters on CheckIn since it has already been done, but in doubt you can set it to true. - allowDuplicateFileNames (add only): if true, the Content Engine will throw an error if a document with the same DocumentTitle property already exists in the ‘parentFolder‘
- callback: A callback function to be called after the item has been checked in.
What you want to do when check in is done. The signature of the method is callback(item, fieldErrors). However this method will be call as follow:- If no error: callback(item) where item is a ecm.model.ContentItem
- If errors: callback(undefined, fieldErrors)
That means you’ll never have both filled at the same time.
- compoundDocument:P8 only, indicates if the document is a compound document or not
Here is an example of checking in using the JavaScript model:
_checkInUsingJS: function (contentItem) { contentItem.checkIn( this._currentItem.classId, // ex: 'document' this._currentItem.criterias, // can be [] if you are not changing any property but just updating content this._currentItem.contentSourceType, // ex: 'Document' this._currentItem.mimetype, // ex: text/xml this._currentItem.filename, // ex myFile.xml this._currentItem.content, // ex: the File object provided by your browser from the D&D this._currentItem.childComponentValues, // usually null for P8 this._currentItem.permissions, // null if you want to keep all current permissions and just update content this._currentItem.securityPolicyId, // a security policy id or null if you don't use one this._currentItem.newVersion, // Not used by P8, using false won't just update the content :) this._currentItem.checkInAsMinorVersion, // if false the reservation version will be converted into a major one this._currentItem.autoClassify, // If you want to run the autoclassify module if you have one configured for this MIME Type lang.hitch(this, this._processCurrentItemComplete) // What to do after ); }
And here is an example of adding using the JavaScript model:
this.repository.addDocumentItem( this._parentFolder, // The ecm.modelContentItem of the folder where to file the new document this.repository.objectStore, // The object store, you can use the repository to get here like I do here this._currentItem.classId, // The class id of the new document, for instance 'document' this._currentItem.criterias, // The array of criterias, see note after this code this._currentItem.contentSourceType, // ex: 'Document' this._currentItem.mimetype, // The MIME Type, or empty if you want to let the CE figure it out this._currentItem.filename, // The filename this._currentItem.content, // This is also a W3C File object, or the BLOB object this._currentItem.childComponentValues, // can be null this._currentItem.permissions, // Can't be null or [] for an add, you have to provide some permissions. Usually you can use the SecurityPane widget to do that, or use the permissions for the entry template if you are using one. this._currentItem.securityPolicyId, // The security policy if you want to use one, or null this._currentItem.addAsMinorVersion, // if false it will create a major version (1.0), otherwise a minor version (0.1) this._currentItem.autoClassify, // if true, the CE will run the autoclassify module on this document if the its MIME Type has one this._currentItem.allowDuplicateFileNames, // true if you want to allow several documents with the same name in the folder this._currentItem.setSecurityParent, // This is deprecated since FileNet P8 4, avoid using this, we will prefer security proxy or SecurityFolder instead this._currentItem.teamspaceId, // can be null if you are not adding this document from a teamspace, if you are set its id here lang.hitch(this, this._processCurrentItemComplete), // what to do after the add is done isBackgroundRequest, // only for the ui lang.hitch(this, this._onError), // what to do if your CE burns because of your document (more seriously if you use the allowDuplicateFileNames to false, you'll get the exception here) this._currentItem.compoundDocument // Tell P8 (only) if this is a compound document );
Note: be careful about the criterias. You HAVE to define the DocumentTitle even is you want to use the FileName. The Content Engine won’t do this for you and the client side has to set it even when using the file name. If you don’t the document will have a blank name.
Using the FileTracker applet
Checking in a document:
_checkInUsingFT: function (contentItem) { var contentURL = ecm.model.Request.getServiceRequestUrl("checkIn", this.repository.type); var contentUrl1 = contentURL; if (contentUrl1.charAt(0) == ".") { contentUrl1 = contentUrl1.substr(1, contentUrl1.length); contentUrl1 = ecm.model.desktop._cServicesUrl + contentUrl1; } var documentInfo = []; var documentInfoInstance = contentItem._makeCheckinParams( this._currentItem.classId, // The class ID, ex 'document' this._currentItem.criterias, // The arrays of property values, can be [] if you are not changing anything this._currentItem.contentSourceType, // The type, ex 'Document' this._currentItem.mimetype, // The MIME Type, ex text/plain this._currentItem.filename, // The file name { filePath: item.filePath, // The content is not a File anymore, but an object with the filename and the path on the system fileName: item.fileName // This is usually provided by the applet, and the applet will use the path to upload the file }, this._currentItem.childComponentValues, // can be null on P8 this._currentItem.permissions, // can be null if you want to keep current permission, or an array of Permissions this._currentItem.securityPolicyId, // the security policy id or null if you don't use one this._currentItem.newVersion, // not use by P8 this._currentItem.checkInAsMinorVersion, // if false the reservation version will be converted into a major one this._currentItem.autoClassify, // If you want to run the autoclassify module if you have one configured for this MIME Type null, // the call back method, but with the FT that's not used, we will used the FT callback when checking in true // true to add form parameters to the request for compatibility with older browser. I won't focus on that here, ); this._buildFTParameters(documentInfoInstance, this._currentItem); // Add security token to the request documentInfo.push(documentInfoInstance); this._currentItem.repositoryId = [this.repository.id]; this._currentItem.docid = [contentItem.id]; this._currentItem.ObjectStoreName = [this.repository.objectStoreName]; this._currentItem.vsId = [contentItem.vsId]; var inputParameters = { contentUrl: contentUrl1, documentInfo: documentInfo, deleteFile: false, isBackgroundRequest: true, onError: lang.hitch(this, this._onError), progressMessage: (Messages["progress_message_" + this.repository.type + "_" + "checkIn"] || Messages["progress_message_" + "checkIn"] || Messages.progress_message_general) }; // This is where we actually check in the document using the File Tracker applet // It is good practice and highly recommended to call _checkInCompleted to update the item after the checkin FileTracker.uploadFiles(inputParameters, lang.hitch(this, function (response) { contentItem._checkInCompleted(response, lang.hitch(this, "_processCurrentItemComplete")); })); }, _buildFTParameters: function (documentInfoInstance, documentItem) { documentInfoInstance.security_token = Request._security_token; documentInfoInstance.filePath = documentItem.filePath; return documentInfoInstance; }
Adding a document (since I don’t really see the point of adding using the applet, I won’t comment this but you still have it if you need):
// Building the service URL var contentURL = ecm.model.Request.getServiceRequestUrl("addItem", this.repository.type); var contentUrl1 = contentURL; if (contentUrl1.charAt(0) == ".") { contentUrl1 = contentUrl1.substr(1, contentUrl1.length); contentUrl1 = ecm.model.desktop._cServicesUrl + contentUrl1; } // Building params needed for the add var documentInfo = []; var args = this.repository._makeAddDocumentItemArgs( this._parentFolder, this.repository.objectStore, this._currentItem.templateName, this._currentItem.criterias, this._currentItem.contentSourceType, this._currentItem.mimetype, this._currentItem.filename, this._currentItem.content, this._currentItem.childComponentValues, this._currentItem.permissions, this._currentItem.securityPolicyId, this._currentItem.addAsMinorVersion, this._currentItem.autoClassify, this._currentItem.allowDuplicateFileNames, this._currentItem.setSecurityParent, this._currentItem.teamspaceId, lang.hitch(this, this._processCurrentItemComplete), isBackgroundRequest, lang.hitch(this, this._onError), this._currentItem.compoundDocument, true ); var documentInfoInstance = this._buildFTParameters(args, this._currentItem); documentInfo.push(documentInfoInstance); // Bulding params needed for the FileTracker applet var inputParameters = { contentUrl: contentUrl1, documentInfo: documentInfo, isBackgroundRequest: isBackgroundRequest, deleteFile: false, onError: this._onError, progressMessage: (Messages["progress_message_" + this.repository.type + "_" + "addItem"] || Messages["progress_message_" + "addItem"] || Messages.progress_message_general) }; // Calling FileTracker to add the document FileTracker.uploadFiles(inputParameters, lang.hitch(this, function (response) { this.repository._addDocumentItemCompleted(response, this._parentFolder, lang.hitch(this, this._processCurrentItemComplete)); }));
Check in a JavaScript variable
Sometime it can be useful to check in a variable into a document instead of a File. ICN JavaScript model does not offer such a function, but you can make it work by building your own BLOB object from your variable and use it to check in the document. Here is an example:
var blob = new Blob(['This is some content'], {type: 'text/plain'}); // You can use the blob as content in the check in function but in case you need the File object, // here is how to construct it var file = new File(blob, 'test.txt');
Note: this doesn’t work with Firefox 27, it says this is a restricted operation, it has been fixed in Firefox 28 and above.
Hi,
I want to extend ecm.widget.dialog.CheckInDialog to create custom checkin
Can you help me how can I do that?
Thank you
Hi Bhavik, I was going to write about extending built-in UI stuffs but I guess it’s not ready yet :). It depends what you want to do, changing small visual thing,behavior or he whole interface. In any case the first step would be create a new dialog extending ecm.widget.dialog.CheckInDialog. Code should look like:
Then you’ll have to tell me a little bit more about what you want to do. If this is small behavior change you can overwrite postCreate and do your thing in it, like aspect and small dom changes. Example:
If you want change the whole UI, you might want to copy the template and overwrite it with
assign it to a variable then use it as
I would rather use the first solution if you have small changes. Again, tell me what you want and I may help you more.
Hope that helps you!
I want to get the Document Id which ever is selected by the context menu (1 or more than one). Please guide me.
Hi Prabu,
You’ll have to tell me a little bit more about what you’re trying to do. The answer depends on where you need the id.
In an action, if you need it to set the visibility, just uses the array of items provided as parameter (isVisible : function (repository, items, repositoryTypes, teamspace)), for instance items[i].id.
You have the same in the performAction function.
If not, please clarify where you need the information.
Thank you Guillaume,
I am trying to add a context menu item…
In which I Created a plugin with pluginAction and in action model class js I am trying to get the documentId which are selected by user. when they click on that menu item it has to show the document ids. thats my first step further in that i got to add other functions.
Thank you for clarifying 🙂
Basically, to do this, you need to:
In this JavaScript class, which should extend ecm/model/Action, you can overwrite only the performAction method, to display the Id (with an alert to do this dirty or using the ecm/widget/dialog/MessageDialog class.
Here is a quick snippet of the class. Of course, don’t forget to create a new custom menu for documents and add your action to it, then assign your menu to the “Document context menu” in your desktop.
WebContent/testPluginDojo/ShowId.js:
Hope that’s enough to get you started.
That worked. Great Guillaume. Thank you so much. Have a great day.
Hi Guillaume,
I need to invoke the service class with docid as one of the service parameter.
For which I am trying to get the item id from dojo class to action model class but its says “ContextMenuDojo is not a constructor”
.
var documentItems = new ContextMenuDojo();
documentItems.performAction(repository, itemList, callback, teamspace, resultSet, parameterMap);
Please tell me how to solve it.
Thanks.
Hi Prabu,
I’m not sure you are understanding how the Action works, you are not supposed to instantiate Context Menu, you are only creating a new Action class and ICN will take care of using it. In the performAction that you are overwriting (not using), you have access to the items. ICN will call your function, when clicking on the the context menu item, that’s not to you to call it.
Now for the service, it looks like this. But you should take a look to the RedBook it is great.
Hi Guillaume,
How to use MessageDialog for getting the input value from user in action model class and pass it to service class
Thank you.
Hi Prabu,
You can’t. You should create your own dialog extending ecm/widget/dialog/BaseDialog and call your service in the method you registered with your Valid button. For example:
this.addButton(“Valid”, “_execute”, false, true);
and call your service in your _execute method.
Let me know if you need more help.
Yes Guillaume, I need your help.
Here I am not adding any button. Like how alert gets displayed I need to prompt a Dialog box to get two input values. Below is the sample one.
======
<link rel="stylesheet" href="../_static/js/dojo/../dijit/themes/claro/claro.css">
<script>dojoConfig = {parseOnLoad: true}</script>
<script src='../_static/js/dojo/dojo.js'></script>
<script>
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
function checkData(){
var data = formDlg.get('value');
console.log(data);
if(data.sdate > data.edate){
alert("Start date must be before end date");
return false;
}else{
return true;
}
}
</script>
Total Number of Page:
Number pages in each to split:
Submit
Cancel
When pressing this button the dialog will popup:
Show me!
dijit.byId(“formDialog”).show();
But i need to execute this for one of my document context menu action model class
require([“dojo/_base/declare”,
“dojo/_base/lang”,
“ecm/model/Request”, “ContextMenuPluginDojo/ContextMenuDojo”],
function(declare, lang, Request, items, ContextMenuDojo) {
/**
* Use this function to add any global JavaScript methods your plug-in requires.
*/
lang.setObject(“contextMenuSplit”, function(repository, itemList, callback, teamspace, resultSet, parameterMap) {
}
})
How can i achieve that… Please tell me.
Thank you.
Hi Prabu,
As I told you, you need to create a new dialog. Please refer to the Dojo documentation to know how to create a new widget. To help you, here is what your code should look like but you should try to understand what’s going on here. You have two files for the widget/dialog, one for the template (InputDialog.html usually in a templates sub-folder), one for the class itself (InputDialog.js). They should be:
The template:
The class:
Then you can use your widget like:
Of course don’t forget to import your widget in the define statement (testPlugin/InputDialog).
Above didn’t work out. its throwing InputDialog is not a constructor. Please tell me how to invoke the Dojo class.
Hi Prabu,
I think you are missing basic Dojo knowledge. You should follow some tutorials on Dojo first. Especially on how to create a class/widget, how to import it and how to instantiate it.
In your case, I would say you InputDialog.js file isn’t a proper Dojo class or you import isn’t correct. You can post your code if you wish, I’ll take a look.
Dojo class
html template
action model class
Error
InputDialog is not a constructor.
Hi Prabu,
You really need to look at the Dojo documentation to see how the loader works. In your case you are importing “ContextMenuPluginDojo/splitDialog” as the variable splitDialog so that’s the name you have to use to create a new instance:
Sorry I forgot to edit that while posting it here… But I had given exactly as how you mentioned here.
But then why its throwing saying splitDialog() is not a constrcutor it should have thown me the error as splitDialog is not defined right??
Thanks & Regards,
Prabu
Indeed my bad, I haven’t looked close enough :). Your parameters do not match, you have 6 for 7 mapping:
Move “BaseDialog” to “items” and try again and let me know.
I removed the BaseDialog but the plugin is not getting loaded….
“dojo/_base/declare”: declare
“dojo/_base/lang”: lang
“ecm/model/Request”: Request
nothing : items ???
“ecm/widget/dialog/AddContentItemDialog”: AddContentItemDialog
“ContextMenuPluginDojo/ContextMenuDojo”: ContextMenuDojo
“ContextMenuPluginDojo/splitDialog”: splitDialog
and its says that same error splitDialog is not a constructor
I am not sure whether its following the serier or matching with names. But without items plugin is not getting loaded itself
I don’t know what your code is, but it should start with:
What do you have. And what error do you get in the console if any?
I got dojo popup worked by using it in another plugin project.
But I was looking to get the value1 & value2 from the dojo class to action class. But I couldn’t get it. Can you help me please.
Thank you,
Prabu
If you want to use the value you will need to wait the user validate the dialog. If you’re execute action is in the dialog class, just access the value of the field:
If you function is in the action class, and assuming you can access your dialog with the dialog variable, just access the fields from the dialog:
However you can’t call this right after calling the dialog.show() function. You need to wait for the user to validate the dialog, in a callback function, or using a deferred object.
Hi Guillaume,
First Of all, This is good documentation. Thank you.
I need your help…
I am trying to update the permissions on a existing document. Below is the snippet i am using, i am getting null pointer exception…. Not sure how to proceed. Any Idea?
docObj.retrievePermissions(lang.hitch(this,function(permissions){
var acc1 = ({
accessMask: 131201,
accessType: 1,
granteeName: “rmedam”,
granteeType:2001,
inheritableDepth:0
});
permissions.push(acc1);
docObj.saveAttributes([], null, null, permissions, false, lang.hitch(this, function(response) {
console.log(‘DocObject Saved With New Permissions’);
}),false,lang.hitch(this,function(er){
console.log(er);
}));
Below Code Worked………
docObj.retrievePermissions(lang.hitch(this,function(res){
permissions = [];
dojo_array.forEach(res, function(permission) {
var acc = {
accessMask: permission.accessMask,
accessType: permission.accessType,
granteeType: permission.granteeType,
inheritableDepth: permission.inheritableDepth,
granteeName: permission.name
}
permissions.push(acc);
});
var acc1 = ({
accessMask: 131201,
accessType: 1,
granteeName: "rmedam",
granteeType:2001,
inheritableDepth:0
});
permissions.push(acc1);
docObj.saveAttributes([], null, null, permissions, false, lang.hitch(this, function(response) {
console.log('DocObject Saved With New Permissions');
}),false,lang.hitch(this,function(er){
console.log(er);
}));
}))
Hi,
I have a requirement, where I need to download the documents selected from the search results along with the metadata of each documents in an excel as a zip file.
I am able to get the vsID of each documents and can call a service method to perform the download action.
But, I am not able to find a way to download the document in a temp location in server and send the content(zip file) to the browser as OutStream.
here is my dojo code:
var reqParams = new Object();
reqParams = serviceParams;
var request = ecm.model.Request.invokePluginService(“DateFormatter”,”DownloadExportService”,{
requestParams : serviceParams,
requestCompleteCallback : function(response) {
// success
console.log(“DownloadExportService called”);
console.log(“The sample plugin service completed, returning:\n”+ dojo.toJson(response,true,” “));
}
}
Can I transform the byte[] of the zip file as json and send it back the above javascript call, and somehow export the file to the browser?
Any kind of help will be appreciated, related to downloading the document to a temp location in server and stream out the document/zip content to the browser.
Thanks,
Deep Thakkar
Hi Deep,
I took a look at the Request class and I think there is no way it can handle file result sent by writing in the response.getOutputStream(), even if we do some aspect tweak in the Request class. I will eventually try again to overwrite the whole process to see if I can make it work, but meanwhile what I would do is to:
Sending the byte array in the json is a terrible idea 🙂 And I doubt that would work anyway because of binary issue.
Hope that helps.
I just thought, an easier way could be to call your service in a new popup. That way:
Just open the popup with the URL http://host:port/navigator/jaxrs/plugin?plugin=PluginId&action=ServiceId&security_token=7917535885080325046&someparam=value, token being from ecm.model.Request._security_token.
I can’t come up with a better way right now but this one is pretty nice, only one service, no extra space.
Hi!
Great article!
I’m new to all this ECM (especially ICN) stuff, and I have a problem. Could You, please, help me?
I need to create an action in ICN, which will create a new version of existing ContentItem and I’m confused with setting all the parameters for JS checkIn function. For example, the content parameter, as well as others. Could You provide me with the sample, which will just create a new version of existing CintentItem?
Hi George,
I’m really sorry about the delay. I was travelling in the previous month and I didn’t get a chance to answer any of the comments. I hope that doesn’t come to late.
Here is a simple example on how to check out/in a document. Hee I’m using hard coded content for this example, but you can replace the “new File” by the File object provided by your browser (meaning the user), that would be the content of your new version.
var item = itemList[0];
repository.lockItems([item], function () {
// Ok here the item is checked out (locked, same meaning :))
// Let's check it back
item.checkIn(
item.template, // templateName, we want to keep the same class
[], // criteria, I don't change any property here, hence the empty array
"Document", // contentSourceType
"", // mimeType, leaving it empty will let the CE figure it out
"test.txt", // filename, if you're using a File object, get its name
new File([new Blob(['This is some content'], {type: 'text/plain'})], 'test.txt'), // Creating the file on the fly, but if you have a File object provided by the user use it here
[], // childComponentValues, not a compound doc here
null, // permissions, leave it null will keep previous version permissions
null, // securityPolicyId, no security policy
null, // you don;t care for P8, this is a CM feature
false, // checkInAsMinorVersion, we want a major version
false, // autoClassify, I don't want to autoclassify on check it, maybe you do
function () {
// callback when check in is done
// I want to refresh the folder so user instantly see the new version number
// in the grid
item.parent.refresh();
});
});
Hope that helps.
Hi, Guillaume! Thanks a lot for such a detailed reply!
In principle, I’ve already implemented something like this, but in any case I’m very grateful to You! Would You be so kind to answer some more questions?
Another task of mine is to develop an action which will create a new ContentItem with the special standard “blank” (containing some text) PDF-file as its content. For now, my intermediate solution is to use HTML (instead of PDF) file (contained within the plugin), which is read as text inside the action. Then the BLOB is created from this text and used as new item file content (the same way as shown in Your example). By the way, I recognized that Internet Explorer doesn’t allow “new File([new Blob…” (Chrome – does!), but the workaround is using BLOB itself, without wrapping with the File…. 🙂
This works fine, but the final requirement is that the file should be PDF, and I still didn’t find a solution on how to work with binary data for explained scenario… The main point is that the user shouldn’t select file manually – everything have to be automated.
Could You, please, help me?
As well, I have some questions regarding EDS. I use it with success, but some points are not clear for me… Maybe I should ask this in some other thread here?
Thanks in advance!
George
Hi George,
Well, generating PDF using JavaScript is not really an ICN issue. I’m sure you can find some documentation on this easily, first Google link being this.
But one suggestion: isn’t it enough to store files as text, and let users use the “Download as PDF” action to get a PDF from it? ICN already has a PDF engine, so why not use it?
Hope that helps.
Hi, Guillaume!
Thanks a lot for Your reply! Well, for the moment the customer is satisfied with the solution of storing text files for initial “blanks”.
However, I have another question, and it’s related exactly the ICN – custom editors, etc. Would You be so kind to answer it, if I post it to the proper topic (Custom editors)?
Hi guillaume
I’m new to for ICN . and I have a problem. Could You, please, help me?
I need to create in ICN, which will auto generate ID No like (Invoice1234) that when adding document i will select Entry template like (invoice ) then all properties is coming in there one properties should be auto generate number like Invoice1234….., can you suggest me how i need to step by step
Hello, Guillaume!
I have a simple question. Hopefully, You can help me.
My item class contains a reference attribute (with dataType=”xs:reference”). What I need is to set it’s value via ecm JS, having a PID String (I’m using CM8.4.3). The question is how to achieve this, if it’s possible? I was trying the following simple code in my Action:
And during the execution of saveAttributes method I get an error on server side:
[1/23/17 16:06:37:516 MSK] 000000e9 SystemErr R CIWEB Error: [admin(unknown) @ fe80:0:0:0:fcd0:34ae:b4e:2fd7%11] com.ibm.ecm.struts.actions.cm.CMEditAttributesAction.executeAction()
java.lang.NullPointerException
at com.ibm.ecm.struts.actions.cm.CMEditAttributesAction.updateItem(CMEditAttributesAction.java:700)
at com.ibm.ecm.struts.actions.cm.CMEditAttributesAction.executeAction(CMEditAttributesAction.java:215)
….
So, is it possible in principle, and if Yes – then How?
Thanks in advance!
George Bredis
Hi George,
I apologize for the really late answer, but I changed my hosting in January and I just noticed emails weren’t working anymore so I missed all the comments.
To answer your question, yes it’s definitely possible. First it’s not necessary to check out (lock) an item before updating a property. Check out is only necessary to update the content of a document.
So you can get rid of your lockItems call and unlockItems call. Since you don’t do the unlock anymore, you can also get rid of retrieveItem 🙂
This leaves you with this code, that I just made work on my VM to make sure 🙂
I don’t have CM and I’m using FileNet P8 but this should basically be the same for you with a CM ID.
Now looking at your NullPointerException, it’s possible that the item your trying to update does not have the property so are you sure it’s the correct class?
Hope that helps.
Hello, Guillaume!
Thanks a lot for Your reply! I’ll check the behavior once more, since the code You provided me with is actually almost the same as mine (except of lock / unlock item). For now I implemented the requirement via the call to ICN service and updating the item in backend, but that’s not what I like 🙂
By the way, looks like new hosting makes Your site much faster, than before! 🙂
Once again, thank You for Your replies and help!
How can I fetch user role from response filter for p8/search filter service? I could get login user with the help of callback.getuserId
Hello, Guillaume!
I have the following quetsion regarding user privileges for the specified item. A time ago, while developing plugins for ICN and IBM Enetrprise Content Manager for DB2 – there was a posiibility to create (using admin console) a custom privilege and use it within ACLs of items, so I was able to create some custom privilege, assign it with the necessary user/group in the item’s ACL and then programmatically check, whether user has it on the item or not (and depending on this do that thing or another).
However, when I started to work with IBM FileNet P8 CE – I see only the list of standard privileges and found no posiibility to create my own. Concretely, I’d like to use them for Actions, beeing able to manage their availability throw item’s ACL. But don’t see – how.
So, the question is: is there such possibility in FileNet P8 CE or not?
Thanks in advance for You reply!
Sincerelly Yours,
George Bredis
Hi All,
Need a little help.. I created a custom viewer plugin in ICN. Here is main js: (no updates here)
require([“dojo/_base/declare”,
“dojo/_base/lang”,
“aFPCustomViewerDojo/aFPCustomDTAPIViewer”],
function(declare, lang, afpCustomDTAPIViewer) {
/**
* Use this function to add any global JavaScript methods your plug-in requires.
*/
console.log(“custom viewer”);
});
And in DOJO/js – postCreate : function(), I am calling a service and that service will need to call an API to transform the document.
How can I get the document ID in js to pass to the service?
When I try below, I get item undefined
postCreate : function(item)
{
var repository = this._item.repository;