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!

Was it helpful?

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 add myItems[i]=[]; before.
  • get item properties with myItems[i]["Item"].get_item('Title') instead of myItems[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:

  1. retrieve items themselves
  2. 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;
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top