CSOM - CAML : Get document icon
-
08-10-2020 - |
Question
I was using JSLink to change the display of a documents webpart. I was retrieving the document icon url set by Sharepoint for a document library item like this:
(it can be shortcut icon (DOCLINK.GIF), or document type icon (ictxt.gif, ichtm.gif, icdoc.gif, etc.) -> i.e. not the File type document, since shortcuts are aspx files, but are not the same icon as a standard aspx file: it recognizes it's a shortcut (="Link to document" type) )
itemHtml:function (ctx) {
//...
var iconURL = ctx.imagesPath+ctx.CurrentItem["HTML_x0020_File_x0020_Type.File_x0020_Type.mapico"];
//...
}
It is working fine.
Now i'm trying to get that same icon with CSOM and caml query, for easier implementation (JSLink is quite a pain to do)
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where></Query></View>");
collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
clientContext.executeQueryAsync(function () {
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
//...
var icon = oListItem.get_item('???');
//...
}
}, function(){
alert('error');
});
Do you know a way to get the icon set by SP for each item?
Many thanks!
Solution 3
Thanks a lot to @jcp for his useful help. I made a few modifications:
- can't set directly a array sub value
myItems[i]["Item"] = oListItem;
. Had to addmyItems[i]=[];
before. - get item properties with
myItems[i]["Item"].get_item('Title')
instead ofmyItems[i]["Item"]['Title']
- get the m_value of iconName since it returns an object (SP.Result type)
Here is my final code:
var collListItem;
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('My List Name');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where></Query></View>");
collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
clientContext.executeQueryAsync(function () {
var myItems=[];
var i=0;
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
myItems[i]=[];
myItems[i]["Item"] = oListItem;
i++;
}
getDocsIcons(myItems,targetId,rootFolder)
}, function(){
console.log('Error loading elements');
});
function getDocsIcons(myItems) {
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
for (var i = 0; i < myItems.length; i++) {
var iconName = web.mapToIcon(myItems[i]["Item"].get_item("FileLeafRef"), '', SP.Utilities.IconSize.Size16);
myItems[i]["DocIcon"] = iconName;
}
ctx.executeQueryAsync(
Function.createDelegate(this, function(){ renderAllItems(myItems); } ),
console.log('Error on retrieving docIcons')
)
}
function renderAllItems(myItems){
for (var i = 0; i < myItems.length; i++) {
var iconFile = myItems[i]["DocIcon"].m_value;
var title = myItems[i]["Item"].get_item('Title');
var fileRef = myItems[i]["Item"].get_item('FileRef');
$('#myContainer').append('<li><img src="'+_spPageContextInfo.layoutsUrl+'/images/'+iconFile+'" /><a target="_blank" href="'+fileRef+'">'+title+'</a></li>');
}
}
OTHER TIPS
You can fetch the icons after after you've fetched the items using the function SP.Web.mapToIcon()
(see corresponding MSDN-Article).
This function returns the name of an icon image for a given filename. E.g. passing in MyDocument.docx
returns icdocx.png
.
To fetch the document icons for multiple items proceed as follows:
First fetch all itmes and store them in an array (here: myItems
).
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where></Query></View>");
collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
clientContext.executeQueryAsync(function () {
// array to store items
var myItems = [];
var i = 0;
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
// store item in array
myItems[i]["Item"] = oListItem;
i++;
}
getDocIcons(myItems);
}, function(){
alert('error');
});
Pass the results myItems
to a second function getDocIcons()
to retrieve the icon names. This is where SP.Web.mapToIcon()
comes into play. Here you call ctx.executeQueryAsync()
a second time to retrieve the icon names from the server.
// get icons for items
function getDocIcons(myItems) {
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
for (var i = 0; i < myItems.length; i++) {
var iconName = web.mapToIcon(myItems[i]["Path"], '', SP.Utilities.IconSize.Size16);
myItems[i]["DocIcon"] = iconName;
}
ctx.executeQueryAsync(
Function.createDelegate(this, function(){ doSomethingWithResults(myItems); } ),
alert ('Error on retrieving docIcons');
}
On success call the function doSomethingWithResults()
. Within this function you can access the icon names retrieved from the server.
// do something with your items and icons
function doSomethingWithResults(items) {
for (var i = 0; i < myItems.length; i++) {
var fileName = item[i]["Item"]["FileLeafRef"];
var iconName = item[i]["DocIcon"]; // sth. like "icdocx.png"
var imgSrc = _spPageContextInfo.siteAbsoluteUrl + "/" + _spPageContextInfo.layoutsUrl + "/images/" + iconName;
...
}
}
Overall you have two ctx.executeQueryAsync()
calls:
- retrieve items themselves
- retrieve icon names for the items
Disclaimer: I've copied the JavaScript code from another project, modified it for this answer but haven't tested the modified code in depth.
The field : DocIcon will just give to you the Name of the icon (log, xlsx...) it will not give you the FileName of the icone.
To do that there is a wonderfull methode in CSOM/JSOM : SP.Web.mapToIcon That return the icone file name of a SPFile
Exemple of use :
var fileAbsolutURL = http://server/sites/web/docLib/myFile.docx"
var context = SP.ClientContext.get_current();
var web = context.get_web();
context.load(web);
context.executeQueryAsync();
var iconResult = web.mapToIcon(fileAbsolutURL,'',SP.Utilities.IconSize.size16)
context.executeQueryAsync();
var iconFileName = iconResult.get_value();
var imgSrc = _spPageContextInfo.siteAbsoluteUrl + "/" + _spPageContextInfo.layoutsUrl + "/images/" + iconFileName;