Copied to clipboard

Flag this post as spam?

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


  • Heather Floyd 610 posts 1032 karma points MVP 6x c-trib
    Jun 03, 2022 @ 16:44
    Heather Floyd
    0

    Umbraco Forms - Create custom FieldPreValueSourceType using picked Content node

    I am attempting to create a custom prevalue source - but I am looking to get data from a property on the node, rather than using children nodes as the source of the prevalues.

    Here is what I have so far:

       using System;
        using System.Collections.Generic;
        using Microsoft.Extensions.Logging;
        using Rwater.Services;
        using Umbraco.Cms.Core;
        using Umbraco.Forms.Core;
        using Umbraco.Forms.Core.Models;
    
        public class FormPrevaluesSourceNode : FieldPreValueSourceType
        {
            private readonly ILogger _logger;
            private readonly IPublishedContentQuery _publishedContentQuery;
    
            [Umbraco.Forms.Core.Attributes.Setting(name: "Form Prevalues Source Node",
                Alias = "SourceNodeId",
                Description = "Node holding the Options desired.",
                View = "pickers.content")]
            public int SourceNodeId { get; set; }
    
            public FormPrevaluesSourceNode(IPublishedContentQuery publishedContentQuery,
                ILogger<FormPrevaluesSourceNode> logger)
            {
                _logger = logger;
                _publishedContentQuery = publishedContentQuery;
    
                this.Id = new Guid("0E4D4E2B-56E1-4E86-84E4-9A0A6051B57C");
                this.Name = "Content-defined Form Prevalues Source Node";
                this.Description = "Select a node of type 'FormPrevaluesSourceNode'";
                this.Group = "Custom";
                this.Icon = "icon-science";
            }
    
    
            public override List<PreValue> GetPreValues(Field field, Form form)
            {
    
    
                List<PreValue> result = new List<PreValue>();
    
                try
                {
                    var node = _publishedContentQuery.Content(SourceNodeId);
                    if (node != null)
                    {
                        int sort = 0;
                        var preValSource = new Models.FormPrevaluesSourceNode(node, null);
    
                        foreach (var prevalue in preValSource.PreValues)
                        {
                            PreValue pv = new PreValue();
                            pv.Id = sort == 0 ? SourceNodeId : sort;
                            pv.Value = prevalue.StoredValue;
                            pv.SortOrder = sort;
                            result.Add(pv);
                            sort++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Unable to get options from FormPrevaluesSourceNode #{SourceNodeId}", ex);
                }
    
                return result;
            }
    
            public override List<Exception> ValidateSettings()
            {
                List<Exception> exs = new List<Exception>();
    
                if (SourceNodeId == default(int))
                    exs.Add(new Exception("'SourceNodeId' setting not filled out’"));
    
                return exs;
            }
        }
    

    and

       public class FormsComposer : IComposer
        {
            public void Compose(IUmbracoBuilder builder)
            {
                builder.WithCollectionBuilder<FieldPreValueSourceCollectionBuilder>()
                    .Add<FormPrevaluesSourceNode>();
            }
        }
    

    But when I compile, I am getting this error:

    Cannot consume scoped service 'Umbraco.Cms.Core.IPublishedContentQuery' from singleton 'MyNamespace.FormPrevaluesSourceNode'.)
    

    Is there a singleton-accessible way to get an IPublishedContent from the int Node Id returned from the Setting?

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jun 03, 2022 @ 16:58
    Andy Butland
    1

    Hi Heather - I think in this context you need to inject IPublishedContentQueryAccessor, which can be injected into singletons, and from there you have a method available TryGetValue that you can use to get an instance of IPublishedContentQuery.

    Hope that helps.

    Andy

  • Heather Floyd 610 posts 1032 karma points MVP 6x c-trib
    Jun 03, 2022 @ 17:24
    Heather Floyd
    0

    Thanks, Andy,

    Do you know if there is a preference between using IPublishedContentQuery or using UmbracoContextFactory ?

    example:

    using (var umbracoContextReference = _UmbracoContextFactory.EnsureUmbracoContext())
                            {
                                iPub = umbracoContextReference.UmbracoContext.Content.GetById(nodeId);
                            }
    
  • Emma Garland 41 posts 123 karma points MVP 7x c-trib
    Dec 06, 2022 @ 20:58
    Emma Garland
    0

    This helped me with a dependency injection scoping struggle, thanks!

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Jun 06, 2022 @ 06:19
    Andy Butland
    0

    No, not sure, but I don't think there'd be any fundamental difference here (i.e. in the end you'd get the same object back to query against).

  • Heather Floyd 610 posts 1032 karma points MVP 6x c-trib
    Jun 06, 2022 @ 16:27
    Heather Floyd
    0

    I was just wondering if one or the other was more performant, or more stable, etc.

Please Sign in or register to post replies

Write your reply to:

Draft