+1-888-365-2779
Try Now
More in this section

Forums / Sitefinity SDK / Dynamic Dropdown (ChoiceFieldElement) in Custom Module

Dynamic Dropdown (ChoiceFieldElement) in Custom Module

14 posts, 1 answered
  1. William
    William avatar
    108 posts
    Registered:
    15 Feb 2011
    08 Apr 2011
    Link to this post
    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
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    19 Sep 2016
    11 Apr 2011
    Link to this post
    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
  3. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    19 Sep 2016
    11 Apr 2011
    Link to this post
    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
  4. William
    William avatar
    108 posts
    Registered:
    15 Feb 2011
    11 Apr 2011
    Link to this post
    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
  5. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    19 Sep 2016
    12 Apr 2011
    Link to this post
    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 >>

  6. William
    William avatar
    108 posts
    Registered:
    15 Feb 2011
    12 Apr 2011
    Link to this post
    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
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    19 Sep 2016
    13 Apr 2011
    Link to this post
    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 >>

    Answered
  8. William
    William avatar
    108 posts
    Registered:
    15 Feb 2011
    13 Apr 2011
    Link to this post
    Ivan,

    Awesome.  Works perfectly.  Thank you!

    - William
  9. Mayvelous
    Mayvelous avatar
    43 posts
    Registered:
    26 May 2011
    23 Sep 2011
    Link to this post
    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.
  10. Mayvelous
    Mayvelous avatar
    43 posts
    Registered:
    26 May 2011
    23 Sep 2011
    Link to this post
    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?
  11. Mayvelous
    Mayvelous avatar
    43 posts
    Registered:
    26 May 2011
    26 Sep 2011
    Link to this post
    Hello? anybody help please?
  12. Anton Mernov
    Anton Mernov avatar
    110 posts
    Registered:
    03 Dec 2008
    27 Sep 2011
    Link to this post
    @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
  13. Vishwaraj
    Vishwaraj avatar
    2 posts
    Registered:
    02 Jul 2012
    23 Jul 2012
    Link to this post
    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






     


     

  14. Vishwaraj
    Vishwaraj avatar
    2 posts
    Registered:
    02 Jul 2012
    23 Jul 2012
    Link to this post
    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






     


     

14 posts, 1 answered