11

I have a drop tree and my client wants to be able to have the possibility to choose from two folders. We have a multi site and the structure looks like this:

Site 1 Data FolderHeWantsToChose

Site 2 Data FolderHeWantsToChose

I have tried something like this:

datasource=/sitecore/content/Site 1/Data/FolderHeWantsToChose&
datasource=/sitecore/content/Site 2/Data/FolderHeWantsToChose

and

/sitecore/content/Site 1/Data/FolderHeWantsToChose|/sitecore/content/Site 2/Data/FolderHeWantsToChose

and

ancestor::*[@@templatename='Site']/Data/FolderHeWantsToChose/*

but I can't find any good query to display only the folders and not the whole Sitecore tree.

4

2 Answers 2

5

As far I see you have 2 sites with same structure.

On your Datasource you make a small mistake, your query must be :

query:./ancestor-or-self::*[@@templatename='Site']/Data/FolderHeWantsToChose

A droptree is pointing to an item not to childs of an item.

Please see Datasource Properies of class Sitecore.Shell.Applications.ContentEditor.Tree (this is used for Droptree) :

 public string Source
    {
        get
        {
            return StringUtil.GetString(new string[]
            {
                this._source
            });
        }
        set
        {
            Assert.ArgumentNotNull(value, "value");
            if (!value.StartsWith("query:", StringComparison.InvariantCulture))
            {
                this._source = value;
                return;
            }
            Item item = Client.ContentDatabase.GetItem(this.ItemID);
            if (item == null)
            {
                return;
            }
            Item item2 = item.Axes.SelectSingleItem(value.Substring("query:".Length));
            if (item2 == null)
            {
                return;
            }
            this._source = item2.ID.ToString();
        }
    }
4

I just copy the answer from this blogpost - http://kamsar.net/index.php/2015/05/A-Multiple-Root-Treelist-Field

Sitecore itself provides a MultiRootTreeList control that is used for rendering the insert data source item dialog (which supports multiple roots).

Implementation (https://gist.github.com/kamsar/33d1245ffdb630b1f126):

using System;
using System.Linq;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor;
using Sitecore.Text;
using Sitecore.Web;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.WebControls;

namespace Kamsar.FieldTypes
{
    /// <summary>
    /// This field type is like a tree list, but you can specify more than one root item to select from (for example, videos or photos)
    /// The data source roots are specified using pipe delimiting just like regular Sitecore Query language
    /// </summary>
    public class MultiRootTreeList : TreeList
    {
        protected override void OnLoad(EventArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            base.OnLoad(args);

            if (!Sitecore.Context.ClientPage.IsEvent)
            {
                // find the existing TreeviewEx that the base OnLoad added, get a ref to its parent, and remove it from controls
                var existingTreeView = (TreeviewEx)WebUtil.FindControlOfType(this, typeof(TreeviewEx));
                var treeviewParent = existingTreeView.Parent;

                existingTreeView.Parent.Controls.Clear(); // remove stock treeviewex, we replace with multiroot

                // find the existing DataContext that the base OnLoad added, get a ref to its parent, and remove it from controls
                var dataContext = (DataContext)WebUtil.FindControlOfType(this, typeof(DataContext));
                var dataContextParent = dataContext.Parent;

                dataContextParent.Controls.Remove(dataContext); // remove stock datacontext, we parse our own

                // create our MultiRootTreeview to replace the TreeviewEx
                var impostor = new Sitecore.Web.UI.WebControls.MultiRootTreeview();
                impostor.ID = existingTreeView.ID;
                impostor.DblClick = existingTreeView.DblClick;
                impostor.Enabled = existingTreeView.Enabled;
                impostor.DisplayFieldName = existingTreeView.DisplayFieldName;

                // parse the data source and create appropriate data contexts out of it
                var dataContexts = ParseDataContexts(dataContext);

                impostor.DataContext = string.Join("|", dataContexts.Select(x => x.ID));
                foreach(var context in dataContexts) dataContextParent.Controls.Add(context);

                // inject our replaced control where the TreeviewEx originally was
                treeviewParent.Controls.Add(impostor);
            }
        }

        /// <summary>
        /// Parses multiple source roots into discrete data context controls (e.g. 'dataSource=/sitecore/content|/sitecore/media library')
        /// </summary>
        /// <param name="originalDataContext">The original data context the base control generated. We reuse some of its property values.</param>
        /// <returns></returns>
        protected virtual DataContext[] ParseDataContexts(DataContext originalDataContext)
        {
            return new ListString(DataSource).Select(x => CreateDataContext(originalDataContext, x)).ToArray();
        }

        /// <summary>
        /// Creates a DataContext control for a given Sitecore path data source
        /// </summary>
        protected virtual DataContext CreateDataContext(DataContext baseDataContext, string dataSource)
        {
            DataContext dataContext = new DataContext();
            dataContext.ID = GetUniqueID("D");
            dataContext.Filter = baseDataContext.Filter;
            dataContext.DataViewName = "Master";
            if (!string.IsNullOrEmpty(DatabaseName))
            {
                dataContext.Parameters = "databasename=" + DatabaseName;
            }
            dataContext.Root = dataSource;
            dataContext.Language = Language.Parse(ItemLanguage);

            return dataContext;
        }
    }
}
2
  • 2
    This is for treeView and I need it for droptree I think it is a bit of a difference :)
    – Radu
    Commented Dec 20, 2016 at 15:25
  • True, thanks for your remark :) if I will have time I would like to change to work with droptree. Maybe it's good starting point to the asker until I/we provide the exact answer. Commented Dec 20, 2016 at 15:47

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.