Dynamic Dropdown (ChoiceFieldElement) in Custom Module

Posted by Community Admin on 05-Aug-2018 05:59

Dynamic Dropdown (ChoiceFieldElement) in Custom Module

All Replies

Posted by Community Admin on 08-Apr-2011 00:00

Hey all,

I've placed a dropdown list in my custom module following:

this thread


And what I initially wanted was to simply fill the dropdown dynamically with published names from my images.  So, you add a new image, it'll show up in that list next time you edit the custom module item.

Got the dropdown list working fine.  Using fluent, I can fill it with my image names.  Only problem is, Sitefinity is caching that list.   Adding new images, deleting images, do not change the list unless i restart IIS.

Is there some way to force a ChoiceFieldElement to always refresh itself and dynamically grab data?

Thanks

- William

Posted by Community Admin on 11-Apr-2011 00:00

Hi William,

Could you check whether CreateChildControls where you create each ChoiceItem is called on each request?

All the best,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 11-Apr-2011 00:00

Hi William,

Also we use a service to make the call and this might be the problem. The better option is using the library item ID (Guid) as a value of the ChoiceItem, so that you will not get wrong results when you save the content item.

Best wishes,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 11-Apr-2011 00:00

Hey Ivan,

Can you tell me where that would go?  Intellisence isn't revealing that attribute anywhere I can see in my code for ChoiceElements or fields 

Here are some snippets of code based on that linked post that I'm using in the Definitions file.

This is just in testing, so ignore the namings of variables in this.

var minutesLinkField = new ChoiceFieldElement(mainSection.Fields)
    ID = "minutesLinkFieldControl",
    DataFieldName = "MinutesLink",
    DisplayMode = displayMode,
    Title = Res.Get<MeetingsResources>().MinutesLink,
    ResourceClassId = typeof(MeetingsResources).Name,
    MutuallyExclusive = false,
    RenderChoiceAs = RenderChoicesAs.DropDown,
    FieldName = "minutesLink",
    FieldType = typeof(ChoiceField)
;

// Get all images in album
try
    App.WorkWith()
        .Album(AlbumGuid)
        .Images()
        .Publihed()
        .OrderBy(t => t.Title)
        .ForEach(t => AddChoiceItemToDropdown(minutesLinkField, t.Title, t.UrlName));
catch
 
// Add to main section
mainSection.Fields.Add(minutesLinkField);

// Adds a choice to a dropdown
public static void AddChoiceItemToDropdown(ChoiceFieldElement IN_ChoiceElement, string IN_Text, string IN_Value)
    IN_ChoiceElement.ChoicesConfig.Add(new ChoiceElement(IN_ChoiceElement.ChoicesConfig)
    
        Text = IN_Text,
        Value = IN_Value
    );

Thanks much

- William

Posted by Community Admin on 12-Apr-2011 00:00

Hello William,

You can create a control that inherits from the ChoiceField and populate it as shown below. Then you can add it as a ChiceFieldElement

public class ChoiceFieldCustom : ChoiceField
   
        public ChoiceFieldCustom()
       
            this.RenderChoicesAs = Sitefinity.Web.UI.Fields.Enums.RenderChoicesAs.DropDown;
       

        protected override void CreateChildControls()
       

            var librariesManager = LibrariesManager.GetManager();
            var albums = librariesManager.GetAlbums();
            foreach (Album alb in albums)
           
                if (alb.Items.Count > 0)
               
                    foreach (MediaContent img in alb.Items)
                   
                        ChoiceItem ci = new ChoiceItem();
                        ci.Text = img.Title;
                        ci.Value = img.Title;
                        this.Choices.Add(ci);
                   
               
           
            base.CreateChildControls();
            this.DropDown.Attributes.Add("onchange", "ddChanged(this)");
       

        protected override string LayoutTemplateName
       
            get
           
                return ChoiceFieldCustom.layoutTempalte;
           
       



        public override IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
       
            var descriptors = base.GetScriptDescriptors();

            var descriptor = (ScriptControlDescriptor)descriptors.Last();
            descriptor.Type = typeof(ChoiceField).FullName;

            return descriptors;
       

        private const string layoutTempalte = "Telerik.Sitefinity.Samples.Resources.ChoiceField.ascx";
   

Regards,
Ivan Dimitrov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

Posted by Community Admin on 12-Apr-2011 00:00

That looks intriguing , Ivan.

In this case, what would Telerik.Sitefinity.Samples.Resources.ChoiceField.ascx look like then?  I'm assuming you'd need to include that as well.

Thanks

- William

Posted by Community Admin on 13-Apr-2011 00:00

Hi William,

Here is the template

<%@ Control Language="C#" %>
 
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
 
<sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server">
    <Templates>
        <sf:ConditionalTemplate ID="ConditionalTemplate1" Left="DisplayMode" Operator="Equal" Right="Read" runat="server">
            <sf:SitefinityLabel id="titleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl" />
            <sf:SitefinityLabel id="read" runat="server" WrapperTagName="div" HideIfNoText="false" />
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate2" Left="RenderChoicesAs" Operator="Equal" Right="CheckBoxes" runat="server">
            <sf:SitefinityLabel id="titleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl" />
            <asp:CheckBoxList ID="checkBoxes" runat="server" RepeatLayout="Flow" CssClass="sfCheckListBox sfFieldWrp"></asp:CheckBoxList>
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate3" Left="RenderChoicesAs" Operator="Equal" Right="DropDown" runat="server">
            <asp:Label ID="titleLabel" runat="server" CssClass="sfTxtLbl" AssociatedControlID="dropDown"></asp:Label>
            <span class="sfDropdownList sfFieldWrp"><asp:DropDownList ID="dropDown" runat="server"></asp:DropDownList></span>
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate4" Left="RenderChoicesAs" Operator="Equal" Right="ListBox" runat="server">
            <asp:Label ID="titleLabel" runat="server" CssClass="sfTxtLbl" AssociatedControlID="listBox"></asp:Label>
            <asp:ListBox ID="listBox" runat="server"></asp:ListBox>
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate5" Left="RenderChoicesAs" Operator="Equal" Right="RadioButtons" runat="server">
            <sf:SitefinityLabel id="titleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl" />
            <asp:RadioButtonList ID="radioButtons" runat="server"
                                 RepeatLayout="Flow"
                                 RepeatDirection="Vertical"
                                 CssClass="sfRadioList sfFieldWrp">
            </asp:RadioButtonList>
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate6" Left="RenderChoicesAs" Operator="Equal" Right="HorizontalRadioButtons" runat="server">
            <sf:SitefinityLabel id="titleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl" />
            <asp:RadioButtonList ID="radioButtons" runat="server"
                                 RepeatLayout="Flow"
                                 RepeatDirection="Horizontal"
                                 CssClass="sfRadioList sfFieldWrp">
            </asp:RadioButtonList>
        </sf:ConditionalTemplate>
        <sf:ConditionalTemplate ID="ConditionalTemplate7" Left="RenderChoicesAs" Operator="Equal" Right="SingleCheckBox" runat="server">
            <sf:SitefinityLabel id="titleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl" />
            <asp:CheckBox ID="singleCheckBox" runat="server" />
        </sf:ConditionalTemplate>
    </Templates>       
</sf:ConditionalTemplateContainer>
<sf:SitefinityLabel id="descriptionLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfDescription" />
<sf:SitefinityLabel id="exampleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfExample" />


Greetings,
Ivan Dimitrov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

Posted by Community Admin on 13-Apr-2011 00:00

Ivan,

Awesome.  Works perfectly.  Thank you!

- William

Posted by Community Admin on 23-Sep-2011 00:00

Hi Ivan,

I've used the same class you provided except that I inherited from FormChoiceField instead of ChoiceField cos' I'm creating as custom form control.

[DatabaseMapping(UserFriendlyDataType.ShortText)]
public class CountryDropdownlist : FormChoiceField

Also, I can't use .Last() as you've done in the GetScriptDescriptors()
var descriptor = (ScriptControlDescriptor)descriptors.Last();

I'm not sure which assembly/namespace is missing cos' the intellicense is not picking up for that.
So I changed it to the following:
public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
 
 var descriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
 
            var descriptor = new ScriptControlDescriptor(this.GetType().FullName, this.ClientID);
            descriptor.AddComponentProperty("dropDown", this.DropDown.ClientID);
            descriptors.Add(descriptor);
 
            return descriptors;
 

I'm binding the country list as follow:
protected override void CreateChildControls()
        
            if (!Page.IsPostBack)
            
                this.Choices.Clear();
                // Add default null field
                ChoiceItem ciNull = new ChoiceItem();
                ciNull.Text = "-- Select Country --";
                ciNull.Value = string.Empty;
                this.Choices.Add(ciNull);
                // Add country lsit
                foreach (string country in GetCountries())
                
                    ChoiceItem ci = new ChoiceItem();
                    ci.Text = country;
                    ci.Value = country;
                    this.Choices.Add(ci);
                
 
                base.CreateChildControls();
                this.DropDown.AppendDataBoundItems = false;
                this.DropDown.Attributes.Add("onchange", "ddChanged(this)");
            
        

The list is displaying fine but when I submit a form, it's throwing the following error:

Key cannot be null.
Parameter name: key

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentNullException: Key cannot be null.
Parameter name: key


Any idea what I might have missed?
Also in the admin edit form page, I can't edit anything and can't publish or go back to forms at all. The whole page seems to be disabled.

Appreciate your help, thanks.

Posted by Community Admin on 23-Sep-2011 00:00

Could you also explain a abit on what this statement means:
this.DropDown.Attributes.Add("onchange", "ddChanged(this)");
what's "ddChanged"? Is that a control name? where can I find it?

Posted by Community Admin on 26-Sep-2011 00:00

Hello? anybody help please?

Posted by Community Admin on 27-Sep-2011 00:00

@Mayvelous,

>>this.DropDown.Attributes.Add("onchange", "ddChanged(this)");
This statement creates the onchange attribute for the dropdownbox and attaches the ddChanged function written on JavaScript  to the onchange event. In the plain HTML it looks like:
<input type="select" name="....." ....... onchange="ddChanged(this)" />

When you select another item in the dropdownbox the onchange event will be fired. So, you need to define somewhere the JS function something like this:
function ddChanged(el)

alert('Item changed');


I hope this helps,
Anton

Posted by Community Admin on 23-Jul-2012 00:00

Hi Ivan,
I have taken your code "Dynamic Dropdown (ChoiceFieldElement) in Custom Module" and modified code and RenderChoicesAs class property as "checkboxes" so that i can have a custom field in module for choice selection.

Its getting me error says Expecting state 'Element'.. Encountered 'Text'  with name '', namespace ''  when i select only one item in checkbox list and publish the module. Published successfully when number of selected items are two or more than it. See attached image.

Please help.

Thanks
Vishwaraj Malik






 


 

Posted by Community Admin on 23-Jul-2012 00:00

Hi Ivan,
I have taken your code "Dynamic Dropdown (ChoiceFieldElement) in Custom Module" and modified code and RenderChoicesAs class property as "checkboxes" so that i can have a custom field in module for choice selection.

Its getting me error says Expecting state 'Element'.. Encountered 'Text'  with name '', namespace ''  when i select only one item in checkbox list and publish the module. Published successfully when number of selected items are two or more than it. See attached image.

Please help.

Thanks
Vishwaraj Malik






 


 

This thread is closed