• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by spitz7 · Dec 17, 2015 at 09:58 AM · valuedropdown

How to create a dropdown without having an item selected?

Hi all,

I created a dropdown and populated it with several country names for the user to choose from. The dropdown's value starts at 0, so the first country is already selected. I want the caption text to initially be "Country" and not "Afghanistan" so I manually changed it:

 CountryDropdown.captionText.text = "Country";

This works fine almost always, but if the user chooses "Afghanistan" the caption text does not change and stays "Country" and onValueChanged doesn't trigger. This happens because the value was and still is 0.

I tried to set the value property of the dropdown to -1 but Unity treats it as 0. Apparently, it's also not possible to choose a value bigger than the last item on the list. I know I can just add a country to the top of the list and call it "Country" but it seems like an ugly solution.

Is there a way to do what I want?

Thanks for the help!

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Rajeesh_AR · Dec 18, 2015 at 05:39 AM 0
Share

@spitz7 Does it works for you >?

avatar image Riderfan · Feb 17, 2016 at 12:01 PM 1
Share

I ran into a similar problem. Not exactly the same, but similar.

In my case I have a collection of possible values the user can select from, save and change later on when they reload the game. This was all working fine however when I created the content for the drop down list, I would also set the CaptionText to the value the user had previously selected and saved. However as you've also found out, the value on the list would always be 0. $$anonymous$$eaning the user could never select the first item on the list. Hopefully I've explained that well enough.

I really do consider this a bug and have submitted a bug report. We should be able to set a default value of -1 OR if we are setting the captiontext to the same text thats in the drop list, the value should default to that item. That's how other drop down list components work.

At any rate, I created a little routine that would itterate through all the items on the list and do a text match. This is a pretty brute force way to do it, but my list of options is quite small (about 6) and it's a UI component where speed isn't really a concern.

 SetDropValue($$anonymous$$yDropList, DesiredCaptionString);
 
         /// <summary>
         /// Sets the caption text and selected item index to the specified string.
         /// </summary>
         /// <param name="_DropDown">The dropdown list we want to update</param>
         /// <param name="_CaptionText">The caption we want to set. $$anonymous$$ust be an item on the list.</param>
         private void SetDropValue(Dropdown _DropDown, string _CaptionText)
         {
             string Caption = _CaptionText.ToUpper();
 
             //Set the caption we want
             _DropDown.captionText.text = Caption;
 
             //Now we have to hack our way through and set the value based on the caption.
             for (int OptIndex = 0; OptIndex <= (_DropDown.options.Count - 1); OptIndex++)
             {
                 if (_DropDown.options[OptIndex].text.ToUpper() == Caption)
                 {
                     _DropDown.value = OptIndex;
                     break; //don't bother checking the rest
                 }
             }
         }

So now, anytime I need to set a preselected value for a drop list, I just call that function. There's no error handling and doesn't handle cases where the caption is for an item that is not on the list (so your problem may still occur).

Hope that helps someone.

10 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by skylem · Apr 11, 2016 at 07:46 AM

Im no expert when it comes to GUI but if the problem is because the values zero isn't empty couldn't this be fixed by simply adding an empty value and a buffer of 1? so 0 would represent empty heres an old GUI spread i had hope it applies to your problem

 public int listToDrop = 0;
 
 
         if (listToDrop == 0) {
             // display list of parts
             foreach (Transform part in partsList) {
                 // select a part to change
                     if (GUILayout.Button (part.name)) {
            /// + 1 to index because zero = off
                         listToDrop = partsList.IndexOf (part) + 1;
                     }
        }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Chalkcs · May 15, 2016 at 01:28 PM

I found an easy solution. It's actually silly how easy it is. I just add a blank option at the top of the list and ignore it's index (which is 0).

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by naviln · Feb 26, 2020 at 01:43 AM

So I've spent some time battling this problem, because I have been trying to achieve the same thing. I want a placeholder text, that is removed once a real option is selected.

I was messing around with this for a long time, and inspired by a post from Ali Kanat (thanks!) here: https://stackoverflow.com/questions/55297626/disable-an-options-in-a-dropdown-unity

I was finally able to put a robust solution together that I was happy with.


The core idea of this solution is to:

  • Utilize a GridLayout Group on the template content GameObject - this helps you to collapse and hide content.

  • Add a hidden 'placeholder' item to your TMP options

  • And finally, use a 'ToggleCheck' Start script on the Item in the TMP dropdown template, this helps you identify your placeholder and disable (HIDE) it.

  • (A disabled object inside a GridLayoutGroup is 'collapsed' and hidden.)


The GridLayout script will ensure that the placeholder always remains hidden, and now you get the benefit of OnValueChanged firing properly (since the hidden default value is picked first!).

I'll put my steps and scripts here, in case anyone wants to try my idea.


First, in the template of your dropdown, add a GridLayoutGroup Script to the Content GameObject. Give it a fixed width that you like (or if you want more flexibilty, you can add your own grid resize controller script and have it resized to match its parent. for the purpose of this example, im just going to use a fixed width of 400).

Screenshot of where to add this:

alt text


Now, in your dropdown initialization, insert a 'placeholder' item. Give it a unique name that no one will use (I went with {{placeholder.com.data}}):

 var ddl = new List<TMP_Dropdown.OptionData>();            
 //lets first insert a 'placeholder' option
 ddl.Add(new TMP_Dropdown.OptionData("{{placeholder.com.data}}"));
 
 //then fill out your usual entries in the dropdown, as you normally would
 //...
 
 //After that is done, insert these options to your dropdown
 dropdownTMP.options.Clear();
 dropdownTMP.options = ddl;
 //and IMPORTANT - force set the choice to the first item (the placeholder)
 dropdownTMP.value = 0;



Next, the onDropdownValueChange method can now do what it normally does, in addition just add a step to turn the placeholder text label you have off:

   public void OnDropdownValueChange()
     {           
         //turn the placeholder off now, or remove its text (or both)
         TMPPlaceholderText.text = "";
         TMPPlaceholderText.gameObject.SetActive(false);
         //and turn the dropdown label on
         dropdownLabelTMP.gameObject.SetActive(true);
     }

And finally - how to turn the placeholder off on intialization. This you can now achieve by adding a "ToggleCheck" script to the 'Item' GameObject inside the dropdown template. Screenshot of where to add the script:

alt text


And here is the content - you want to catch the name of the 'placeholder' toggle, if it matches the placeholder text you specified, hide it (and make it un-interactable too). NOTE: The name will have the text "Item 0:" prefixed to it, as it was the first option you inserted to the TMP OptionData.

     public class ToggleCheck : MonoBehaviour
     {
         //This script should be attached to Item
         void Start()
         {           
             Toggle toggle = gameObject.GetComponent<Toggle>();            
             if (toggle != null && toggle.name == "Item 0: {{placeholder.com.data}}")
             {
                 toggle.interactable = false;
                 toggle.gameObject.SetActive(false);
                 //and resize the grid layout if you want, since this is the first item, and you only need to do this once.
                 //gameObject.GetComponentInParent<GridResizeController>().ApplyGridResize();
             }
         }
     }
 

This ensures that the placeholder is selected first, allowing OnDropdownValueChange to fire when it is changed for the first time to a real value.


Obviously you should add additional placeholder validation, if someones tries to use item 0, etc. And you could be even smarter with the ToggleCheck script (read the placeholder from some internal lookup table, hide the name etc). It enables a lot more cool customization, potentially. You can decide how you want to implement those things.


Bonus: Here is a method you can use to resize the GridLayoutGroup width to match its parent:

     private void ApplyGridResize(GridLayoutGroup gridLayout)
     {
         // grab the width of my parent
         var width = gameObject.transform.parent.GetComponent<RectTransform>().rect.width;
         Vector2 newSize = new Vector2(width, gridLayout.cellSize.y);            
         gridLayout.cellSize = newSize;
     }



If there is an easier way to achieve this in Unity 2019 and onwards I'd love to hear it! But for now this works really well for me.


gridlayoutgroup.png (131.1 kB)
togglecheck.png (262.1 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by jason416 · Mar 12, 2020 at 03:09 PM

Well it's 2020 now, this is how I'm doing it. Drop this script on the same GO as the Dropdown. It will just overwrite the caption text onEnable, this does not actually change the underlying value of the dropdown. If you want the label to return to the default after selection then add a call to the method again on your click events.

 using UnityEngine;
 using UnityEngine.UI;
 
 public class DefaultDropdown : MonoBehaviour
 {
     public string DefaultText;
     Dropdown dropdown;
 
     private void Awake()
     {
         dropdown = gameObject.GetComponent<Dropdown>();
     }
 
     private void OnEnable()
     {
         SetDefaultText();
     }
 
     public void SetDefaultText()
     {
         dropdown.captionText.text = DefaultText;
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by XAFAX · Nov 10, 2021 at 03:30 PM

In case anyone is still wondering how to add a preface text, here's how you do it:

1) Add a placeholder to the Dropdown Component.

2) Set the Dropdown value to -1 (see code below).

 private void BuildDropdown()
 {
     _dropdown.options = CreateOptions(); // Create some options (optional)
     _dropdown.SetValueWithoutNotify(-1); // Set dropdown value to -1, so that the placeholder is displayed.
     _dropdown.onValueChanged.AddListener(SomeListener); // Add some functionality (optional)
 }

Now the placeholder will be displayed first.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • ‹
  • 1
  • 2

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

TextMeshPro dropdown default value change 0 Answers

How to make dropdown start at value on click 0 Answers

Vector3 List Find Contains Specific X Coordinate Value and Remove 0 Answers

c# problem with changing value with button click 3 Answers

Change value when swiping on mobile 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges