The basics of creating a dropdown are here:
In summary, you need to create a class which implements ISelectionFactory. To implement that interface, you need a method called GetSelections which returns an IEnumarable of ISelectItem. Within that method, it's up to you how you create that list. The example above uses hard-coded strings but you'd probably want to pull it from a datasource of some kind (e.g. a property on the homepage).
Once you've got your SelectionFactory created, you just need to annotate the property you want to appear as a dropdown with a [SelectOne] attribute, for example:
[SelectOne(SelectionFactoryType=typeof(MySelectionFactory))]
And that's it!
I have created my custom dropdown property as My_Prop and i have annotated the property with the [Select Many] Attribute.
My property looks like this :
[SelectMany(SelectionFactoryType = typeof(My_Prop))]
public virtual string dropdown { get; set; }
Can you please tell me how to render this property in the view? I tried @Html.PropertyFor(x=>x.dropdown), but this is not helpful as i'm not getting the list in the web page.
Hi Bhargav,
When adding a SelectMany to a string property you will get your selected values as a comma separated string. You will need to split the values by comma yourself.
I would suggest that you create display templates for your property according to Joel's blog http://joelabrahamsson.com/episerver-7-and-mvc-how-to-customize-rendering-of-properties/ or Dejan's reply to this post.
@Html.DisplayFor(x => x.CurrentPage.dropdown, "CommaSeparatedString")
And in the view do something like
@model string @if (Model != null) { foreach (var item in Model.split( new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { // output your item } }
This code is just quickly thrown together so you might need to do some adjustments.
Hi Alf, My custom property class looks like this :
namespace Enterprise.Models.Properties
{
public class My_Prop : ISelectionFactory
{
public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
var MyDrop = new ISelectItem[]
{
new SelectItem() { Text = "Car", Value = "Car" },
new SelectItem() { Text = "Home", Value = "Home" },
new SelectItem() { Text = "MotorBike", Value = "MotorBike"}
};
return MyDrop;
}
}
}
and i've Annotated the property in the my page as below :
[UIHint(UIHint.LongString)]
[SelectMany(SelectionFactoryType = typeof(My_Prop))]
public virtual string dropdown { get; set; }
I've created the display template which will ovveride the actual LongString property, which goes like this :
LongString.cshtml (path : ~/Views/Shared/DisplayTemplates) - in the solution
@model string
@if (Model != null)
{
<select>
@foreach (var item in Model.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
<option> @item </option>
}
</select>
}
And the view in which i want my property to be displayed as dropdown, is :
@model Enterprise.Models.Pages.StartPage
@using Enterprise.Models.Properties
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/Layouts/_Root.cshtml";
}
<html>
<body>
<div class="container">
@Html.PropertyFor(x => x.maincontent)
</div>
<div>
@Html.DisplayFor(x=>x.dropdown,"LongString")
</div>
</body>
</html>
Still i couldn't get the list in my web page. Did i do something wrong?
I think it's better if you're using something else than Episerver's built in UIHints. Come up with something new that you use in the UIHint attribute as well as the filename of your .cshtml
I don't think you need the UIHint attribute since you give the Tag in the view
@Html.DisplayFor(x=>x.dropdown,"LongString")
So in my case
[SelectMany(SelectionFactoryType = typeof(My_Prop))] public virtual string dropdown { get; set; }
and I have created \Views\Shared\DisplayTemplates\CommaSeparatedString.cshtml
@model string @if (Model != null) { <select> @foreach (var item in Model.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { <option> @item </option> } </select> }
and in the Index.cshtml
@Html.DisplayFor(x => x.dropdown, "CommaSeparatedString")
The name "CommaSeparatedString" is just something I came up with. Feel free to use another name as long as it's not a predefined value in Episerver, such as the ones on the UIHint class
I tried changing the name of display template still nothing is being rendered.
@model string @if (Model != null) { <select> @foreach (var item in Model.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { <option> @item </option> } </select> }
The above piece of code is for rendering this list that i've created here right?
public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
{
var MyDrop = new ISelectItem[]
{
new SelectItem() { Text = "Car", Value = "Car" },
new SelectItem() { Text = "Home", Value = "Home" },
new SelectItem() { Text = "MotorBike", Value = "MotorBike"}
};
return MyDrop;
}
}
Or do i have to make any adjustments?
Hi.
To start with I see that we mixed up an attribute. Use SelectOne instead of SelectMany.
SelectMany gives you a checkbox list and that is where Comma Separated String comes in. You can throw the DisplayTemplate away. Sorry about that
The SelectionFactory and SelectItem part is only for creating the drop down for the editor.
Also since you use DisplayFor instead of PropertyFor, you won't see the editor part in the One Page Edit mode. You need to switch to "All Properties" to be able to edit the field, and see the drop down.
Thank you Alf.
Now I've used PropertyFor instead of DisplayFor and in "All properties" i can see the dropdown that i've created but why can't I see it in the web page?
Did you remove the Display Template part?
can you see it on the web page if you select a value in the drop down?
Yes I've given @Html.PropertyFor(x=>x.dropdown). And i selected a value and i can see only one value in the web page.
And I guess that is the value you selected?
When you are inside episerver, but not in All Properties you should see a blue bon around the place where your view renders the property.
if you have selected a value, the blue box is around the value.
Clicking inside the blue box should open so that you can see the drop down.
Yes its the value that i've selected, but on clicking in that blue box, its letting me to change the selected value there itself instead of displaying the dropdown as you said.
I think this thread may help you with getting the editor to appear correctly:
https://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=145743
In which part of the solution should i create the EditorDescriptor class?
Thank you Alf and Paul. I've got the dropdown in my web page thanks to both of you. I just have one more doubt. Can i add more values to the dropdown while i'm in edit mode.
In that case your SelectionFactory must get the options from another area, for example the StartPage since it's easy to find. Or Create some kind of settings page/block.
You have your SelectioNFactory that is currently returning hard coded options.
A simple way to be to change your SelectionFactory to read the values from another content.
For example add a property to your startpage. Fetch the StartPage and read that property, split it with a good limiter and for each string after the split you select a new SelectItem.
Thinking of it, there's an OLD function in Episerver that I don't think many use nowadays.
Can you try to add "DropDownList" as UIHint on your property?
Go to your page type in admin mode.
Click on the property that should have this dropdown list
Click the radio button "Use custom settings" and start to add your options.
Okay I understood. I have to change the selectionfactory to get values from other property in the page, then i can add them to the SelectItem. That's it right?
Yeah, i added the DropDownList as UIHint for my property.But it is showing that this class doesn't have any custom settings.
Could you try adding the attribute [BackingType(PropertyDropDownList)] to the property?
No, I coudn't. It is showing an error that PropertyDropDownList is invalid in the context. I even added the namespace Episerver.SpecializedProperties.
Where do you get this errors?
Here's an example of where we're using that property
[UIHint("DropDownList")] [BackingType(typeof(EPiServer.SpecializedProperties.PropertyDropDownList))] [Display( Name = "Tab color", Description = "Color for the tab and rest of the content", GroupName = SystemTabNames.Content, Order = 200)] public virtual string TabColor { get; set; }
Yeah.i added the options.Thank you. But now it is only displaying one value, i mean its not like a dropdown list but it is displayed like a string.
Ok, sometimes changing BackingField for an existing property requires more work. Can you try renaming the property? = tells Episerver to create a new Property.
I renamed it to myprop. you want me to create a new property of same type?
I was thinking of only renaming the property on the page (confusing that we have the .net class property as well as the episerver "property" = field on content).
Just adding a 2 on it will work for the test.
public virtual string MyProperty2 {get;set;}
Rebuild, go to episerver edit mode and check if the property now is a dropdown field.
Not even in All Properties mode?
In that case I guess it's easier to continue letting the SelectionFactory fetching the options from another content.
I can see it as dropdown in All properties mode, but on the page its being displayed like a string.
Ok, this works completely fine for me when I'm trying in the Alloy Templates
In the Page Type
[UIHint("DropDownList")] [BackingType(typeof(EPiServer.SpecializedProperties.PropertyDropDownList))] public virtual string Dropdown { get; set; }
In the view
@Html.PropertyFor(x => x.CurrentPage.Dropdown)
Note that if you're using your PageType as Model, you don't need x.CurrentPage, it would be enough to do x.Dropdown
Now the property should be ready to be used
Just one thing for me is that I'm not able to get the options in the dropdown (bug maybe?) but at least I can get the dropdowns.
Need to look a bit more if something is broken or if I am doing something wrong.
Yeah even i can't get options in the dropdown.Anyways thank you so much Alf for taking your time. :)
http://epideveloper.blogspot.com/2013/10/episerver-7-attribute-for-rendering-drop-down-list.html
Hey Alf, see if this might help us. In the above link he created a custom attribute to render the dropdown list with options.
That's another way to manage a SelectionFactory that we already talked about. But you still need to change code and deploy to edit which options to display.
okay.but even if i were to such thing, what if i still can't get ito be displayed as a dropdown.
l'm new to Episerver and i want to create a custom property, especially a drop down list property in which i can add the options in edit mode. I searched through the documentation and i couldn't understand the process they have mentioned. Can i get a clear description of process of creating the custom dropdown property?