Monday, October 28, 2013

Create simple custom lookup picker in "Hyperlink or Picture" Column

One frequent request from users is the selection of document/Picture url from field “Hyperlink or Picture”.
It is hard for users to add the url of document/Picture from Lists in Forms Lists.

There are other Column Types that open a window to sharepoint site content to select Url, these columns are associated with Publishing Content Types and  some users don't know how use this (they dont even know this exist). Some cannot activate because of business/company reasons others by version of the SharePoint

To help end users to improve the process and reduce possible errors spend some seconds thinking to myself “The Form can call a modal dialog to a Listview and there we can select the file to fill out the URL field".
This can be achieve with a simple javascript customization that overrides the control “Hyperlink or Picture” adding a button that List the documents/Picture and fill out the Url Field.


This solution uses the Forms “NEW/EDIT” where is created a custom option in the column “Hyperlink or Picture”.
The users can choose a document or image using list Views of SharePoint in a Modal Dialog.
(update 14-08-2017 - have feedback from users that SharePoint 2013 farm to April 2017 CU breaks this solution code, please remember this is a customization and not out of the box feature from SharePoint). please use the CRS example explained below.

This article has 3 options of implementation of the column picker.
  • SharePoint 2010 (Edit List Forms)
  • SharePoint 2013 / 2016 (Edit List Forms)
  • SharePoint 2013 / 2016  / Office 365 "SharePoint Online" (CSR JS Link)
This Customization was made using Jquery and SharePoint Modal Dialog Method to Listview and return the link to automatic fill the “Hyperlink or Picture” Column.
This customization has to be done in the Forms “New/Edit” where the option will appear and in the ListViews where the users should select the Document/Picture.



Bellow is the Design of the information structure to our Solution to select Document and Pictures and return their Url.



Create the Custom List



The first task is to create a Custom List with 2 new Columns with the following names and Type:
  • Image Link “Hyperlink or Picture” - (Picture)
  • Document Link “Hyperlink or Picture” - (Hyperlink)






After the columns are created the List Forms “NEWFrom.aspx/EDITForm.aspx” needs to be customize to call the correct lists where are located the pictures to make the reference.



Insert Customization

Edit the NewForm.aspx and EditForm.aspx and change the openddialog('Destiny Folder View URL','Name of field').
For this example was used 2 Library, Picture Library and Document Library and copy the Views url associated.
  • OpenDialogUrl (Url of the View)
  • field 'Image Link' and 'Document Link'
After the change add a "Script Editor Web Part" and add the code.



<script src="../../SiteAssets/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript">


$(document).ready(function() {
$("input[title='Image Link']").parent().append('</br><input type="button" onclick="OpenDialog(\'../../PublishingImages/Forms/Thumbnails.aspx\',\'Image Link\')" value="Select Image"></input><br/>');
$("input[title='Document Link']").parent().append('</br><input type="button" onclick="OpenDialog(\'../../Shared%20Documents/Forms/AllItems.aspx\',\'Document Link\')" value="Select Document"></input><br/>');
});


function OpenDialog(OpenDialog,Field) {
    var options = SP.UI.$create_DialogOptions();
    options.url = OpenDialog;
 this.GlobalField= Field;
    //options.showMaximized = true;
    options.dialogReturnValueCallback = Function.createDelegate(null, CloseCallback);
    SP.UI.ModalDialog.showModalDialog(options);
}

function CloseCallback(result, target) {
    if (result == SP.UI.DialogResult.OK) {
        $("input[title='"+GlobalField+"']").val(target);
    }
    if (result == SP.UI.DialogResult.cancel) {
        // Run Cancel Code
    }
}
</script>

Select Picture



When a user chose the option “Select Image” the modal dialog is shown to a Listview of pictures.
There the user should select the picture to reference using the Checkbox in the Tile.



After the Picture is selected the Modal Dialog is close and the Field “Image Link” will have the Url reference.



Insert Customization

Access to the Picture Library View and edit the Page and add a Script Editor Web Part.



Edit the Script Editor Web Part and add the following code to select the Image in the checkbox of the image.

<script src="../../SiteAssets/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.s4-itm-imgCbx-inner').click(function() {
var id= $(this).parent().parent().parent().parent().children().attr('id').substring(0, $(this).parent().parent().parent().parent().children().attr('id').length - 1)+'7';

var filext = $('#'+id).attr('src').substr($('#'+id).attr('src').lastIndexOf('.'));

var remterm=$('#'+id).attr('src').replace('_w/','').replace(filext,'');

var link = remterm.substr(remterm.lastIndexOf('_')+1);
remterm = remterm.replace('_'+link,'.'+link);
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, remterm);

});
});
</script>

Select Document



When a user chose the option “Select Document” the modal dialog is shown to a Listview of Documents.
There the user should select the Document to reference, using the Checkbox in the Grid.




After select the Document the Modal Dialog will close and the reference will appear in the Field.




Insert Customization

Access to the Document Library View and edit the Page and add a Script Editor Web Part.


Edit the Script Editor Web Part and add the following code to select the Image in the checkbox of the Document.

<script src="../../SiteAssets/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript">
$( document ).ready(function() {
$('.s4-itm-cbx').click(function() {
var link =$(this).parent().parent().children('.ms-vb-title').children().children().attr('href');

SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, link);

});
});
</script>



After the form is fill out, the View should appear the reference to the Document and Image in the ListView.
This option will be also available in the Edit Form.


Ok, that is all you need to create your custom image/document Url with some Javascript and Modal dialog and Out of the Box Features.




Update for SP2010
After some requests associated to SP2010 here are the jquery lines for the picker from document library and image library.

Document Library Picker:
<script type="text/javascript">
$('.s4-itm-cbx').click(function() {var link =$(this).parent().parent().children('.ms-vb-title').children().children().attr('href');SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, link);});

</script>

Image Library Picker:
<script type="text/javascript">
$('[id*=cbxTB]').click(function() {var newid= this.id.replace('cbx','').toLowerCase();
var filext = $('#'+newid).attr('src').substr($('#'+newid).attr('src').lastIndexOf('.'));
var remterm=$('#'+newid).attr('src').replace('_t/','').replace(filext,'');
var link = remterm.substr(remterm.lastIndexOf('_')+1);
remterm = remterm.replace('_'+link,'.'+link);
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, remterm);

});
</script>


Client-side rendering (SharePoint 2013 / 2016 / Office 365 "SharePoint Online") example:

The following JS code provides a picker option that popups the site Libraries to select the associated Asset url document.




CSR JS Link Picker example:

(function () {
window.CSRPicker = {
    getInit: function () {
        var priorityFiledContext = {};
        priorityFiledContext.Templates = {};
        priorityFiledContext.Templates.Fields = {
            "ImageLink": {
                "NewForm": this.renderImage,
                "EditForm": this.renderImage
            },
            "DocumentLink": {
                "NewForm": this.renderPicker,
                "EditForm": this.renderPicker
            },
        };

        SPClientTemplates.TemplateManager.RegisterTemplateOverrides(priorityFiledContext);
    },
    renderImage: function (ctx) {
        var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);

        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            return document.getElementById('URLTextBox').value;
        });
        return "<input type='text' class='ms-long' name='' id='URLTextBox' value='" + formCtx.fieldValue + "' /><p/><input style='width: 200px;' type='submit' class='ms- input' value='Select Image' id='BtnBrowseDocumentStorageLocation' onclick='CSRPicker.OpenAssetPortalBrowserDialog(\"URLTextBox\"); return false;' />";
    },
    renderPicker: function (ctx) {
        var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            return (document.getElementById('DocumentPicker').value !== null) ? document.getElementById('DocumentPicker').value : "";
        });
        return "<input type='text' class='ms-long' name='' id='DocumentPicker' value='" + formCtx.fieldValue + "' /><p/><input style='width: 200px;' type='submit' class='ms- input' value='Select Document' id='BtnBrowseDocumentStorageLocation' onclick='CSRPicker.OpenAssetPortalBrowserDialog(\"DocumentPicker\"); return false;' />";
    },
    OpenAssetPortalBrowserDialog: function (ObjectId) {
        var clientContext = SP.ClientContext.get_current();
        Web = clientContext.get_web();
        clientContext.load(Web);
        clientContext.executeQueryAsync(function () {
            var UrlPagePicker = "/_layouts/15/AssetPortalBrowser.aspx";
            var Parameteres = "?&AssetType=Link&AssetUrl=" + _spPageContextInfo.webServerRelativeUrl + "&RootFolder=" + _spPageContextInfo.webServerRelativeUrl + "Bild&MDWeb=" + Web.get_id();
            var url = '';
            if (_spPageContextInfo.webServerRelativeUrl === '/')
            { url = UrlPagePicker + Parameteres }
            else { url = _spPageContextInfo.webServerRelativeUrl + UrlPagePicker + Parameteres }
            var options = SP.UI.$create_DialogOptions();
            options.url = url;
            options.dialogReturnValueCallback = Function.createDelegate(null, function (result, target) {
                if (result === SP.UI.DialogResult.OK) {
                    document.getElementById(ObjectId).value = target.AssetUrl;
                }
            });
            SP.UI.ModalDialog.showModalDialog(options);
        }, function () { alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); });
    }
};
        CSRPicker.getInit();
})();

You can include the associated CSR JS Code in your List Schema in the Form Area "EditForm" or "NewForm" to be active in the List by default or directly in the List Form Web Part



Hope you like this article,
Kind regards

No comments: