Copied to clipboard

Flag this post as spam?

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


  • Paul de Quant 403 posts 1520 karma points
    Jul 17, 2019 @ 08:04
    Paul de Quant
    0

    Custom Grid Editors in Umbraco 8

    Hi,

    Are there any tutorials/documentation around how to create a new grid editor for use in Umbraco 8. I've created a few for v7 but when I add them to v8 they don't work any more.

    I've used things like dialogService, which I understand don't exist in v8 and have been replaced by editorService.

    Thanks

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Jul 17, 2019 @ 10:53
    Søren Gregersen
    0

    Hi Paul,

    The build-in editors are always a god place to start looking for inspiration.

    The dialog/editor service is the biggest replacement. Are you running into any specifc issues that you need help with?

    best, Søren

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 06:57
    Paul de Quant
    0

    Hi,

    The issue I'm facing at the moment is that the model value isn't being saved.

    I'm saving my custom data to $scope.model.value, but when I submit - the value of value vanishes.

       function submit() {
            if ($scope.model.submit) {
                $scope.model.submit($scope.model);
            }
       }
    
  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 07:32
    Frans de Jong
    0

    This is my controller to save a image with a url.

    It isn't perfect but it works. Maybe this will help?

    angular.module("umbraco").controller("webwonders.imageWithLink.controller",
    function ($scope, editorService, 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
            editorService.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
                submit: function (data) {
                    var selectedImage = data.selection[0];
    
                    $scope.control.value.image = selectedImage.image;
                    $scope.control.value.imageId = selectedImage.id;
                    $scope.thumbnail = selectedImage.thumbnail;
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            });
        };
    
        // Select a content node to link to, OR enter a URL to an external site, very similar to pickImage()
        $scope.pickContent = function () {
            editorService.linkPicker({
                currentTarget: $scope.control.value.link,
                multiPicker: false,
                section: "content",
                treeAlias: "content",
                submit: function (data) {
                    $scope.control.value.link = data.target;
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            });
        };
    
        // Remove the selected content or entered link
        $scope.onRemove = function () {
            $scope.control.value.link = undefined;
        };
    });
    
  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 07:37
    Paul de Quant
    0

    Hi Frans,

    Thanks for the code, I had something similar, but even though I can see the objects being saved to the model.value I can't see it persist after submission.

    (function () {
    "use strict";
    
    function InfiniteEditorController($scope, editorService) {
    
        var vm = this;
    
        vm.submit = submit;
        vm.close = close;
        vm.setImageSrc = setImageSrc;
        vm.removeImage = removeImage;
        vm.setLinkSrc = setLinkSrc;
    
        function removeImage() {
            $scope.model.value.imageObj = null;
        }
    
        function setImageSrc() {
    
            var mediaPickerOptions = {
                multiPicker: false,
                onlyImages: true,
                disableFolderSelect: true,
                submit: function (model) {
    
                    if (!$scope.model.value || !$scope.model.value === null) {
                        $scope.model.value = {};
                    }
    
                    $scope.model.value.imageObj = {
                        id: model.selection[0].id,
                        udi: model.selection[0].udi,
                        image: model.selection[0].image
                    };
    
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            };
            editorService.mediaPicker(mediaPickerOptions);
        }
    
        function setLinkSrc() {
    
            var contentPicker = {
                section: "content",
                treeAlias: "content",
                multiPicker: false,
                submit: function (model) {
    
                    if (!$scope.model.value || !$scope.model.value === null) {
                        $scope.model.value = {};
                    }
    
                    $scope.model.value.linkObj = {
                        id: model.selection[0].id,
                        udi: model.selection[0].udi,
                        name: model.selection[0].name
                    };
    
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                }
            };
    
            editorService.treePicker(contentPicker);
    
        }
    
        function submit() {
            if ($scope.model.submit) {
                $scope.model.submit($scope.model);
            }
        }
    
        function close() {
            if ($scope.model.close) {
                $scope.model.close();
            }
        }
    
    }
    
    angular.module("umbraco").controller("My.InfiniteEditorController", InfiniteEditorController);
    

    })();

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 08:02
    Frans de Jong
    0

    Is it not saving? Or is it not showing on reload?

    At first glance I don't understand where you get your model from here

        $scope.model.value.linkObj = {
                    id: model.selection[0].id,
                    udi: model.selection[0].udi,
                    name: model.selection[0].name
                };
    
  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Jul 18, 2019 @ 08:03
    Søren Gregersen
    0

    it's a parameter to the submit-method :)

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 08:05
    Frans de Jong
    0

    Ah, was reading to fast...

    So what is the current behaviour? Does it set the value and is it only not visible on reload? Or if the dialog is closed the value is already invisible?

    And when is submit called? It seems after submit is called the setlinksrc method should be called?

    Can yo usee that happening by adding a bunch of console logs in the start of every method?

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 08:13
    Paul de Quant
    0

    What I've done is outputted the value {{model.value}} on my grid view so I can see what was submitted and I can't see anything I've saved via my custom editor.

    Although I'm not sure if I should be setting something like control.value instead.

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 08:15
    Frans de Jong
    0

    Did you try and add a console log in the methods to see if every method is called and has values?

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 08:18
    Paul de Quant
    0

    I've stepped through all of it and to the point where it gets to the final submit function.

          function submit() {
            if ($scope.model.submit) {
                $scope.model.submit($scope.model);
            }
        }
    

    $scope.model contains a property called value (with everything I've added). which is what I expect. When the overlay closes and returns back to the grid. I can't see any evidence of this when I output the value {{model.value}}

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 08:38
    Paul de Quant
    0

    Also to add to this, when I output the model to the grid view. I can see my added controls, but the value is set to null.

    How do we set the value of the controls?

                                    "controls": [
                                    {
                                        "value": null,
                                        "editor": {
                                            "name": "Standard Card",
                                            "alias": "GridControlsV8.standardcard",
                                            "view": "/App_Plugins/GridControlsV8/BackendView/standard-card.html",
                                            "render": "/App_Plugins/GridControlsV8/FrontendView/standard-card.cshtml",
                                            "icon": "icon-layout",
                                            "config": {}
                                        },
                                        "$index": 0,
                                        "$uniqueId": "7e73682c-f215-48a1-2a73-16dec42e9ead",
                                        "$editorPath": "/App_Plugins/GridControlsV8/BackendView/standard-card.html"
                                    },
                                    {
                                        "value": null,
                                        "editor": {
                                            "name": "Standard Card",
                                            "alias": "GridControlsV8.standardcard",
                                            "view": "/App_Plugins/GridControlsV8/BackendView/standard-card.html",
                                            "render": "/App_Plugins/GridControlsV8/FrontendView/standard-card.cshtml",
                                            "icon": "icon-layout",
                                            "config": {}
                                        },
                                        "$index": 1,
                                        "$uniqueId": "194440f6-2cd4-af59-9a7f-424fe78a9212",
                                        "$editorPath": "/App_Plugins/GridControlsV8/BackendView/standard-card.html"
                                    }
                                ]
    
  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 08:43
    Frans de Jong
    0

    And if you log model after this line submit: function (model) { it still has the value?

    Also if you log the value of $scope.model.value just before editorService.close(); is still has the value?

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 08:47
    Paul de Quant
    0

    There is no value in model at this point, but then the model referenced here is not the whole thing, just the model of the image picker / link picker and not the model of the control as a whole.

  • Paul de Quant 403 posts 1520 karma points
    Jul 18, 2019 @ 08:53
    Paul de Quant
    0

    If it helps, I was using this guide to create the custom control

    https://our.umbraco.com/apidocs/v8/ui/#/api/umbraco.services.editorService

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 18, 2019 @ 09:03
    Frans de Jong
    0

    It looks like you combined multiple examples. In the example the 2 submit functions live in their own controller. They both have their own scope. I think the model is empty because of that. If you create the controllers and refer to the correct one in the view like the example it should work.

  • Paul de Quant 403 posts 1520 karma points
    Jul 19, 2019 @ 07:02
    Paul de Quant
    100

    Hi Frans,

    I've managed to get it working, it turns out that while the model.value was all present and correct in the overlay, when you click submit, which calls the overlay opener controller I wasn't doing anything with that data.

            function open() {
            var options = {
                title: "Standard Card",
                view: "/App_Plugins/GridControls/Editors/standard-card.html",
                submit: function (model) {
                    $scope.control.value = model.value;
                    editorService.close();
                },
                close: function () {
                    editorService.close();
                },
                value: !$scope.control && !$scope.control.value ? {} : $scope.control.value
            };
            editorService.open(options);
        }
    

    I needed to add the line:-

    value: !$scope.control && !$scope.control.value ? {} : $scope.control.value
    
  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 19, 2019 @ 07:04
    Frans de Jong
    0

    Great news! I always find it hard to debug stuff like this. The only way is to console log everything and follow the path until you lose the value.

  • Paul de Quant 403 posts 1520 karma points
    Jul 19, 2019 @ 07:06
    Paul de Quant
    0

    Thanks for the help BTW. I just wish there were more examples for this sort of stuff.

  • Frans de Jong 548 posts 1840 karma points MVP 3x c-trib
    Jul 19, 2019 @ 07:07
    Frans de Jong
    0

    It helps to look at packages on github. There is a lot of useful stuff in there.

Please Sign in or register to post replies

Write your reply to:

Draft