3

I have a Droplist for Approvers and the DataSource of Droplist to /SharedData/Approvers.

I don't want the current user to have his own name in the list. For example, DataSource List is having A, B and C

When A logs in, it should show B and C but not A. Or it should be validated when A selects himself as Approver.

Any idea?

4

It is possible via both a custom field implementation or field validation. Below is the code for both ways.

Solution 1 - A Custom Validation

You should implement a class which will extend the StandardValidator. The code snippet is provided below to create a custom validation for the droplist.

[Serializable]
public class UserValidation : StandardValidator
{
    protected override ValidatorResult Evaluate()
    {
        var selectedValue = ControlValidationValue;

        var username = Context.User.LocalName;

        if (!selectedValue.IsNullOrEmpty() && selectedValue.Equals(username))
        {
            Text = GetText($"Field {GetFieldDisplayName()} cannot select your own name");
            return ValidatorResult.FatalError;
        }

        return ValidatorResult.Valid;
    }

    protected override ValidatorResult GetMaxValidatorResult()
    {
        return GetFailedResult(ValidatorResult.Error);
    }

    public override string Name => "User Validator";
}

In the code above, I have use the LocalName property. This property will return me only the name. Example, Admin.

Note that this piece of code will validate the username against the item name. It is feasible check the username against a field on the items from the list but it will require additional code to retrieve the selected item then read the field.

Once you have deployed the above code, you will need to create a new validation item under the path /sitecore/system/Settings/Validation Rules/Field Rules.

enter image description here

Change the Type to match your namespace. Also, you need to assign the newly created validation rule to the field.

Solution 2 - A Custom Field

You can implement a custom droplist which extend the ValueLookupEx from the namespace Sitecore.Shell.Applications.ContentEditor in the Sitecore.Kernel.dll. The purpose will be to remove the current user from the list of items if it matches.

public class CustomDroplist : ValueLookupEx
{
    protected override Item[] GetItems(Item current)
    {
        var items = base.GetItems(current);

        var username = Sitecore.Context.User.LocalName;

        var resultItems = items.Where(w => !w.Name.Equals(username)).ToArray();

        return resultItems;
    }
}

Once implemented, deploy the code and load the content editor. Then, switch the database to core and navigate to the path /sitecore/system/Field types/List Types and create a new field using the template Template field type.

enter image description here

Update the assembly and class with yours.

Outcome

enter image description here

3

You can specify custom logic to resolve the source of the field using a code: declaration and setting it to your custom Class.

Include a reference to Sitecore.Buckets.dll and create a class which implements IDataSource:

using System.Linq;
using Sitecore.Data.Items;

namespace Sitecore.Sharedsource.Data.FieldSources
{
    public class CustomFieldDataSource : Sitecore.Buckets.FieldTypes.IDataSource
    {
        public Item[] ListQuery(Item item)
        {
            var items = item.Axes.SelectItems("./ancestor-or-self::*[@@templatename='Homepage']/path/to/userlist/*");
            var username = Sitecore.Context.User.LocalName;
            var resultItems = items.Where(w => !w.Name.Equals(username)).ToArray();

            return resultItems;
        }
    }
}

You can now set the field source to code:Sitecore.Sharedsource.Data.FieldSources.CustomFieldDataSource, Sitecore.Sharedsource. The code runs from the context of the context item, i.e. the currently selected item in the content tree.

You can use this syntax for any field that runs the query through the getLookupSourceItems pipeline, such a Droplink, Droplist, Multilist, Treelist, Checklist etc.

Alternatively you could create a custom prefix and handle this yourself using a custom pipeline processor instead in getLookupSourceItems pipeline.

You can read more in these blog posts by John West and Raul Jimenez.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.