9

Task

Short - Access item attribute from a picture library by picture url.

Long - When editing a pagelayout and an image is added to the page, the image's description should be loaded. This is triggered by a button "Get Description" to prevent the user from writing multiple times.

Approach

function GetImageDescription (imageUrl) {
//possible image URLs so far -- additions are welcome !
imageUrl = "http://www.exampleURL/lorem-ipsum.jpg" //does not need to work
imageUrl = "http://root/Sub/PublishingImages/MyFolder/MyFolderN/lorem-ipsum.jpg" //does not work
imageUrl = "http://root/OtherSub/PublishingImages/lorem-ipsum.jpg"; // would work when using correct context.
imageUrl = "http://root/Sub/PublishingImages/lorem-ipsum.jpg"; // works

var libraryUrl = imageUrl.substr(0, imageUrl.lastIndexOf("/")); //trim the picture URL (what about folders ?)
var clientContext = SP.ClientContext.get_current(); 
var lists = clientContext.get_web().get_lists(); //get all lists
clientContext.load(lists, 'Include(DefaultViewUrl, Title)'); //load lists with needed attributes

clientContext.executeQueryAsync(function (sender, args) {
    var enumerator = lists.getEnumerator();
    while (enumerator.moveNext()) { //walk over all lists
        var list = enumerator.get_current(); //get current list
        var listUrl = list.get_defaultViewUrl(); //get somewhat containing the url - View for example
        listUrl = listUrl.substr(0, listUrl.lastIndexOf("/Forms")) // trim to get pure list URL
        if (endsWith(listUrl, libraryUrl)) { // check if its a match
            //list found ! 
            //do awesome stuff  
        }
    }
}, function (sender, args) {
    throw "Sadly there occured an error - " + args.get_message() + ' ' + args.get_stackTrace();
});

function endsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

This works as long as there is no folder created.

Update

I took the approach Vadim Gremyachev delivered and added cross site compatibility.

//get absoulute image url
var imageUrl = $("#Image img")[0].src.split("?")[0]; //remove querystring

//get image file properties
getFileProperties(imageUrl, imageUrl);

function getFileProperties(url, fileUrl) {
    //to get the file specific client context
    //you can create the context based on a url
    //the url sadly must match the pure site's url 
    //exmpl. 
    //http://contoso/library/image.jpg does not work
    //http://contoso/library does not work
    //http://contoso does work
    //to get the pure site's url I simply add a try 
    //error query and repeat recursively until no error
    //is thrown or the url does not contain "/"

    var ctx = new SP.ClientContext(url); //get context
    var siteCollection = ctx.get_site(); //try get site to check if context is valid
    ctx.load(siteCollection);
    ctx.executeQueryAsync(
        function () {
            // context is valid - proceed 
            var relUrl = fileUrl.replace(_spPageContextInfo.siteAbsoluteUrl, '');  //convert to relative url
            var file = ctx.get_web().getFileByServerRelativeUrl(relUrl);   //get file
            ctx.load(file, 'ListItemAllFields');

            ctx.executeQueryAsync(
                function () {
                    var listItem = file.get_listItemAllFields(); 
                    var comment = listItem.get_fieldValues()._Comments; 
                    var copyright = listItem.get_fieldValues().wic_System_Copyright;

                    $("#Description input").val(comment); //apply
                    $("#Copyright input").val(copyright);

                },
                function (sender, args) {
                    console.log(args.get_message()); //errorhandling
                }
            );                
        },
        function (sender, args) {
            //context is invalid - shrink url and try again
            if (url.indexOf("/") !== -1) {
                url = url.substr(0, url.lastIndexOf("/"));
                getFileProperties(url, fileUrl); //recursive call
            }
            //else - the url is not compatible
        }
    );
}

1 Answer 1

11

Convert absolute URL into server-relative URL and use SP.Web.getFileByServerRelativeUrl Method to return file object located at the specified server-relative URL as demonstrated below:

function getFileProperties(url,success,error) {

   var ctx = SP.ClientContext.get_current(); 
   var relUrl = url.replace(_spPageContextInfo.siteAbsoluteUrl,'');  //convert to relative url
   var file = ctx.get_web().getFileByServerRelativeUrl(relUrl);   //get file
   ctx.load(file,'ListItemAllFields'); 

   ctx.executeQueryAsync(
      function () {
         success(file);
      }, 
      error
   );
}

Usage

//get image file properties, e.g. Comments  
getFileProperties('https://contoso.sharepoint.com/media/PublishingImages/Lake-Baikal.jpg',
  function(file){
     var listItem = file.get_listItemAllFields();
     var comments = listItem.get_fieldValues()._Comments;
     console.log(comments);
  },
  function(sender,args){
      console.log(args.get_message());
  });
1
  • 1
    Thanks for pointing that out ! This works as long as SP.ClientContext.get_current() is the corresponding site for the file. If the file is from another site you have to get the specific context. - I added a solution to my question.
    – Mx.
    Commented Aug 5, 2014 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.