Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Marc Ferrold 24 posts 105 karma points
    Apr 22, 2015 @ 13:56
    Marc Ferrold
    4

    The Spirit of Sharing - Images With Links in a Grid

    Hello, good day, hi!

    I've fairly recently started working with Umbraco, and I've really been liking the grid so far. I've been experimenting a little with making custom property editors for use in it, and a co-worker requested the ability to set up an image with a link, without it being in an RTE.

    This seemed simple, yet also useful enough that I figured I'd share what I'd come up with. If anyone can use it, they're free to copy/paste it :) My own experience with this sort of stuff has been that examples felt either too complex or too specific, so I hope this helps someone else.

    There might be a better way of doing this particular thing (in which case I suspect it'll pop up here, so problem solved either way), but this is simple and hopefully easy to understand.

    In /App_Plugins/LinkImage (or whatever you choose to name your plugin):

    The controller (LinkImage.controller.js)

    angular.module("umbraco").controller("LinkImage.controller",
    function ($scope, dialogService, entityResource) {
    
        if(!$scope.control.value || $scope.control.value == undefined)
        {
            $scope.control.value = {};
            $scope.control.value.config = {};
            $scope.thumbnail = '';
        }
        else {
    
            // if existing scope has no image, create empty object
            if ($scope.control.value.image == '' || $scope.control.value.image == undefined) {
                $scope.thumbnail = '';
                $scope.control.config
                $scope.control.value.config = { width: 0, height: 0 };
            }
            else {
                // if we have a image id, call information about media item using media resource
                entityResource.getById($scope.control.value.imageId, "Media").then(function (ent) {
                    console.log(ent);
                    $scope.thumbnail = ent.metaData.umbracoFile.Value;
                    $scope.control.value.config = { width: ent.metaData.umbracoWidth.Value, height: ent.metaData.umbracoHeight.Value };
                });
            }
        }
    
        // Select an image
        $scope.pickImage = function () {
            // open the built-in mediapicker
            dialogService.mediaPicker({
                multiPicker: false, // only allow one image to be picked
                // function that is called when the dialog is closed. 
                // Selected item(s) will be passed in by the data object
                callback: function (data) {
                    $scope.control.value.image = data.image;
                    $scope.control.value.imageId = data.id;
                    $scope.thumbnail = data.thumbnail;
                    $scope.control.value.config = { width: data.originalWidth, height: data.originalHeight };
                }
            });
        };
    
        // Select a content node to link to, OR enter a URL to an external site, very similar to pickImage()
        $scope.pickContent = function () {
            dialogService.linkPicker({
                multiPicker: false,
                section: "content",
                treeAlias: "content",
                callback: function (data) {
                    $scope.control.value.link = { name: data.name, id: data.id, url: data.url, target: data.target };
                }
            });
        };
    
        // Remove the selected content or entered link
        $scope.removeContent = function () {
            $scope.control.link = undefined;
        };
    });
    

    The backend/grid view (LinkImage.html)

    <div id="simple-control.valuer-list-editor" ng-controller="LinkImage.controller">
    <div class="usky-editor-placeholder" ng-click="pickImage()" ng-if="!control.value.image">
        <i class="icon icon-picture"></i>
        <div class="help-text"><localize key="grid_clickToInsertImage">Click to insert image</localize></div>
    </div>
    
    <div ng-if="control.value.image">
        <img ng-if="control.value.image"
             ng-click="pickImage()"
             ng-src="{{control.value.image}}"
             class="fullSizeImage" />
        <input type="text" class="caption" style="width:100%; border:none; font-style:italic;" ng-model="control.value.caption" localize="placeholder" placeholder="@grid_placeholderImageCaption" />
    </div>
    <br/>
    <div>
        <i class="icon icon-add blue" ng-show="!control.value.link"></i>
        <a href ng-click="pickContent()" ng-show="!control.value.link">link</a>
        <a href ng-click="control.value.link = undefined" ng-show="control.value.link">
            <p ng-show="control.value.link.name">
                <i class="icon icon-delete red"></i>
                {{control.value.link.name}}
            </p>
            <p ng-show="control.value.link.url && !control.value.link.name">
                <i class="icon icon-delete red"></i>
                {{control.value.link.url}}
            </p>
        </a>
    </div>
    

    The frontend view (LinkImage.cshtml)

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>
    @using Umbraco.Web.Templates
    @if (Model.value != null){
        if(Model.value.image != null && Model.value.image != ""){ 
            var url = Model.value.image;
        if (Model.value.config != null){
            url += "?width=" + Model.value.config.width;
            url += "&height=" + Model.value.config.height;
        }
        if(Model.value.link != null)
        { 
            <a href="@Model.value.link.url" target="@Model.value.link.target"><img src="@url" alt="@Model.value.caption" /></a>
        }
        else
        {
            <img src="@url" alt="@Model.value.caption" />
        }
    
        if (Model.value.caption != null)
        {
            <p class="caption">@Model.value.caption</p>
        }
    }
    }
    

    This is fairly easy to customize to your needs :)

    And finally, the package manifest (package.manifest)

    {propertyEditors: [
        {
            name: "Link Image",
            alias: "linkimage",
            editor: {
                view: "~/app_plugins/linkimage/linkimage.html",
                valueType: "JSON"
            }
        }
    ],
    javascript: ['~/App_Plugins/LinkImage/LinkImage.controller.js']}
    

    When all the files are in order, you simply need to tell Umbraco to allow it in the grid, by going into /Config/grid.editors.config.js, and adding:

    {
        "name": "Link Image",
        "alias": "linkimage",
        "view": "/App_Plugins/LinkImage/LinkImage.html",
        "icon": "icon-link"
    }
    

    It ends up looking like this (with and without a picture selected)

    ImageLink

    With a link dialog like this

    enter image description here

    Now, if there are any errors or redundancies in my code, I'm sure it'll come up - again, I'm fairly new, but it has worked for me, and thought I'd share, for people who just happen to need a link image :)

  • Rune Hem Strand 147 posts 911 karma points hq c-trib
    Aug 27, 2015 @ 21:58
    Rune Hem Strand
    0

    Hi Eric

    When you have the editor view linkimage.html in the plugins folder ~/app_plugins/linkimage/ you can put the the render view (with the same name) linkimage.cshtml in the same folder and it will be detected automatically. You can also specify a render path by adding render in the editor definition:

    {
       gridEditors: [
          {
              name: "Link Image",
              alias: "linkimage",
              view: "~/app_plugins/linkimage/linkimage.html",
              render: "~/app_plugins/linkimage/linkimage.cshtml"
          }
      ],
      javascript: ['~/App_Plugins/LinkImage/LinkImage.controller.js']
    }
    

    In the image you posted it looks like the controller is is not initialized in the view but hard to figure out why without more info :)

    You can read more about the making grid editors here.

    There is also some videos about it on umbraco.tv

    /Rune

  • Eric Schrepel 161 posts 226 karma points
    Aug 27, 2015 @ 22:02
    Eric Schrepel
    1

    It was a minor file capitalization thing. My bad, works great now, thanks.

    Working on tweaking the "link" because often, all the image needs to do is link to a larger (original size) version of itself. It'll give me something to learn as I try to get it working :)

  • Rune Hem Strand 147 posts 911 karma points hq c-trib
    Aug 27, 2015 @ 22:12
    Rune Hem Strand
    0

    Great you got it working :)

    #h5yr

  • Jonathan 6 posts 39 karma points
    Nov 21, 2015 @ 18:50
    Jonathan
    1

    BUMP.

    Thanks for sharing this, it was crucial in helping me fill in some gaps for a problem I've been banging my head on.

    I've come to believe that having a high degree of proficiency in building custom property editors is the key to delivering the sort of interfaces clients demand.

  • Jan Borup Coyle 7 posts 32 karma points
    Aug 30, 2019 @ 13:07
    Jan Borup Coyle
    0

    Please HELP !!!

    I have tried for some hour now to solve a problem with this.

    I have created the files, in the /App_Plugins... but when running my site without creating any LinkImage i got this error in the Bootstrap3.cshtml :

    'string' indeholder ikke en definition til 'sections'

    Beskrivelse: Der opstod en undtagelse, der ikke blev behandlet, under udførelse af den aktuelle webanmodning. Se staksporingen for at få flere oplysninger om fejlen, og hvor den kom fra i koden.

    Detaljer om undtagelse: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'string' indeholder ikke en definition til 'sections'

    Linje 7:  *@
    Linje 8:  
    Linje 9:  @if (Model != null && Model.sections != null)
    Linje 10: {
    Linje 11:     var oneColumn = ((System.Collections.ICollection)Model.sections).Count == 1;
    

    Kildefil: c:\Work\csn-v41\Chainbox.App.Webshop\Views\Partials\Grid\Bootstrap3.cshtml Linje: 9

    I'm running this on a Umbraco 7.4.3

    Any clues ?

    Best regards Jan Borup Coyle

  • tchiggins 1 post 21 karma points
    Mar 26, 2020 @ 15:49
    tchiggins
    0

    I get the following: -

    {{control.value.link.name}}

    {{control.value.link.url}}

    Any ideas what I am doing wrong?

    Thanks Tom

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies