Semantic-ui: [Dropdown] Add Nullable Option for Single Selection

Created on 6 Apr 2015  路  58Comments  路  Source: Semantic-Org/Semantic-UI

If converting any select to a dropdown, for example

<select name="someselect"
    <option value="1" selected="selected">A</option>
    <option value="2">B</option>
    <option value="3">C</option>
</select>

The select is not required, so an empty selection is valid. We already have a value selected (given by something else). But it is not possible to select an empty value from the generated dropdown.

Discussion Enhancement

Most helpful comment

Drop-downs should have reset button / icon by default, here's what I've made for my project!

https://jsfiddle.net/xu4fv5n0/2/
Something like this should be added.

All 58 comments

Hi, please check the readme. Please include a jsfiddle demonstrating your bug and a set of reproducible steps.

Ok, here's the fiddle:

https://jsfiddle.net/christiank/vf7r42ku/

As you see, the first select is ok: No empty value provided in select, no empty value found in dropdown.
In my opinion, the second select must also show an empty selection available, due to given in the origin select element. Same applies to third select, if you do a wrong selection, i think you must be able to select an empty option.

Empty values are used to pass in placeholder text (i.e. "Select Text.."), a few people have complained about this being idiosyncratic.

I need to evaluate whether it makes sense to change this functionality in 2.0 as it will cause breaking changes for anyone who is using it this way in 1.x

Well, I think we should consider keeping as most backward compatibility as possible, so in my opinion, I would prefer one of the following options:

  • Adding a new class to the select make it nullable or something like that
  • Extending the behavior to just not required select fields (I don't care about undo selection in a required select)

Just created a fiddle to show how this could work with some magic aka. automatization:

https://jsfiddle.net/christiank/khy2z55x/

Some things i fall into was that most options I tried break responsibility. However, I'm not the best JS/HTML-Guru, more type of a PHP-Guru.

I think adding a placeholder setting, that when passed false will not process blank val will allow for both syntax, and also specifying placeholder programmatically.

Added in 2.0.0. Defaults to auto, which will convert values. If a string is specified, will use that string as placeholder, when set to false will ignore any blank values..9b7ecef

However, I think this does not solve the problem: how do you undo the selection in a NOT required select? This is the business case I stept into and it seems that your fiddle does not solve this problem. Even if the select is providind an empty option.

I totally agree with @zelenin , using an option without a value attribute is quite a dirty solution. Including regarding to form generators in Symfony2 and ZF2. For me, it is not a solution to modify form generator templates just to make it possible to undo selection.

Including backward compatibility, I propose the following solution:

  • Options with empty value attribute are treated the same way
  • If you add an clearable to the select/dropdown class attribute you get the following:

    • Option with empty value is treated as empty option, so used as placeholder _and_ empty value

    • It might also be an option to add an additional _X_ button right to the select to make it easier undoing the selection

I'll circle around this week.

I also agree with @chrisandchris and @zelenin. It's really hard to work with a select box which has less features than a native one. It's being a big issue both on undoing the selection and also on the edit pages to update a record having a value already selected.

There's docs on both clearing dropdowns and restoring to page load defaults. Can you elaborate on what's missing @canyildiz?

@jlukic thank you for preparing those detailed docs. I really appreciate this. But I don't think putting a "Clear" button near the select box is same as selecting the first empty option of select. Second is the common behavior all web users are used to.

@jlukic clear button is a workaround for hack that you are using for placeholder. Dropdown must be maximally repeating native select behavior. Only then it may be more featureous without risk for native features.

Im in the same boat as @chrisandchris

<select name="someselect"
    <option value="" selected="selected">None</option>
    <option value="2">A</option>
    <option value="3">B</option>
</select>

Where the user can select A and then change their mind and re-select None.

Having a reset button is not a solution.

A nullable option that can be passed to .dropdown() would be a great backwards compatible option.

Forcing value="" empty string options to disappear after a user selects is not inline with how the native select works.

I like the idea of nullable, since, to me, both cases make sense. This is the last thing on my checklist for dropdown before putting it down.

Any timeframe on this?

Do you want me to have a go at implementing it and doing a PR?

I've had to delay this to 2.x due to time constraints.

It just touches on too much code currently for me to start noodling.

i have fixed this
edit semantic.js at row 5728

                  if(settings.placeholder === 'auto' && value === '') {
                    select.placeholder = name;
                    select.values.push({
                      name     : name,
                      value    : value,
                      disabled : disabled
                    });
                  }
                  else {
                    select.values.push({
                      name     : name,
                      value    : value,
                      disabled : disabled
                    });
                  }

We really need this capability to "un-select" something when a selection is optional.

@jlukic Something as easy as this: http://harvesthq.github.io/chosen/#allow-deselect-on-single-selects

It is really just a close icon that calls .dropdown('clear selection')

Positioning can be tricky since a few things are right floated in dropdown and input padding has to compensate.

Any updates on this? I also think that it's better if their is a blank of option.

Drop-downs should have reset button / icon by default, here's what I've made for my project!

https://jsfiddle.net/xu4fv5n0/2/
Something like this should be added.

@jlukic is there any way to have the restore defaults with the options of useLabels: false? because every time i load some active settings or i dont have anything selected or i have the normal multiple select instead of the counter when useLabels: false is used

Just for not having doubts that this feature is needed, here is a plausible example (from site mailer configuration page) where the empty value makes sense:

<select name="smtp_crypto" id="smtp_crypto">
    <option value="" selected="selected">-- none --</option>
    <option value="ssl">ssl</option>
    <option value="tls">tls</option>
</select>

Edit: I support @chrisandchris about "Options with empty value attribute are treated the same way". I am migrating my designs and I can feel that lack of dropdown variation that behaves exactly as a native select box is a painful problem.

I saw this answer in StackOverflow: http://stackoverflow.com/questions/32381571/semantic-ui-dropdown-default-placeholder-value-issue/40939842#40939842

And starting from there I came to this temporary workaround:

http://jsfiddle.net/efp8z6Ln/416/

HTML:

<form class="ui form">

    <div class="field">

        <label for="smtp_crypto">SMTP Encryption (testing a nullable dropdown):</label>

        <select name="smtp_crypto" id="smtp_crypto" class="ui nullable dropdown">
            <option value="" selected="selected">-- none --</option>
            <option value="ssl">ssl</option>
            <option value="tls">tls</option>
        </select>

    </div>

</form>

JS:

$(function () {

    $('.ui.dropdown').dropdown({
        onChange: function(value) {

            // A workaround, see https://github.com/Semantic-Org/Semantic-UI/issues/2072
            // "[Dropdown] Add Nullable Option for Single Selection"

            var target = $(this);
            var wrapper = target.prop('tagName') == 'SELECT' ? target.parent() : target;

            if (wrapper.hasClass('nullable')) {

                if (value) {

                    var icon = wrapper.find('.dropdown.icon');

                    icon.removeClass('dropdown').addClass('delete').on('click', function(e) {

                        target.dropdown('clear');
                        $(this).removeClass('delete').addClass('dropdown');

                        e.preventDefault();
                        return false;
                    });
                }
            }
        }
    });

});

The desired behavior is activated by adding "nullable" class.

Edit: fireOnInit setting probably needs to be set to true.

The native control at least avoids complications, at the moment it is what I see as a good choice: http://jsfiddle.net/x0d0wo84/1/

Wow, it has been a year and a half and we still don't have an option to preserve an empty option in dropdowns. Sigh.

@ivantcholakov I haven't been able to reproduce your jsfiddle...

I implemented something similar to your solution here http://jsfiddle.net/efp8z6Ln/416/ but I think that's somehow rather confusing for people instead of a simple empty item in the dropdown.

I'd like the feature of an empty valued option element too.

<option value="">None</option>

@ashkonBG solution is the right way. I'm currently looking for the same functionality. User accidentally selects a value and can't unselect it without clearing whole form. If you have some time this is really high priority and should have been in version 1.0.

Really guys? Still no option for this?

@serkandemirel0420 yeah, I can't believe this either.

Some one willing to take over this RP ?

In my case, I did as follows.
I'm glad, if this code will be helpful someone who suffers from the same problem.
And I hope to be resolved the problem by official feature.

HTML:

<div class="field">
    <select class="ui compact optional dropdown" name="gender">
        <option value="">Gender</option>
        <option value="1">Male</option>
        <option value="2">Female</option>
    </select>
</div>

CSS:

.ui.optional.dropdown .menu > .item[data-value=''],
.ui.optional.dropdown .menu > .item[data-value='']:HOVER,
.ui.optional.dropdown .menu > .item.selected[data-value=''] {
    color: transparent !important;
}

JS:

// dropdown for optional
$.when(
    $('select.ui.optional.dropdown').each(function(){
        $(this).dropdown({
            placeholder: $(this).find("option[value='']").text(),
            onHide: function(){
                var dropdown = $(this).closest('.ui.optional.dropdown')
                if(dropdown.find(".menu:has(.item.selected[data-value=''])").size()) {
                    dropdown.find(".text").addClass('default');
                } else {
                    dropdown.find(".text").removeClass('default');
                }
            }
        });
    })
).done(function() {
    var dropdowns = $('.ui.optional.dropdown');
    dropdowns.each(function(){
        var dropdown = $(this);
        if(dropdown.find(".menu:has(.item.selected[data-value=''])").size()) {
            dropdown.find(".text").addClass('default');
        } else {
            dropdown.find(".text").removeClass('default');
        }
    });
});

// dropdown for required
$('select.ui.dropdown:not(.optional)').dropdown();

Wow - more than 2 years have passed and there is still no official way how to do this???
I can't believe my eyes :(

Slightly improved version of @ashkonBG script https://jsfiddle.net/hghkwkgv/1/

Also consider to use if(value!="") instead of if(value) to allow 0 as legit select option.

Only bad thing about this solution is that onChange event is not fired when you initialize that field, so you can't clear/reset default selected value which is set on page loading.

Edit:
This version also contains workaround to call onChange on initialization https://jsfiddle.net/hghkwkgv/6/ and few other fixes.

@DarkSide666 I believe that we can fork and start a new branch since officer is dead~_~

@greatbody Well, yes it looks that @jlukic have no activity for more than 1 month and previously he's not that active too this year. Sad to see that such good repo like Semantic-UI is going down this way. 142 open pull requests, 1070 open issues :(

Sad to see yes, everyone thinks open source is cool and free, maybe use donation button more often.

I already contribute in multiple open-source projects. That's my 2-cents to open-source community :)

Contribution is important to open-source projects and all, but what I think others are trying to say is that new features are being added to the project; but this very major, yet so simple, issue still exists that shouldn't have been there since the early version.

@ashkonBG I completely agree with you

I've been a lead on an open-source project for over 10 years. You are not getting any money off it. Donations or ads won't help. The goal is to have multiple secondary officers who would be able to take over, approve PRs and move project ahead should something happen with the lead.

In a current situation, we've invested a tons of work into https://github.com/atk4/ui to use Semantic UI over any other CSS framework. I still think it's a right choice and if we have to support this project somehow, we would be happy to help. But being open-source guys ourselves, we can't put any funds in.

I really like the syntax of semantic-ui because it's highly readable and much more easier to write as other frameworks, like bootstrap.

But, even with that in mind, it is quite impossible imho to succeed for semantic-ui when the founder does not give any permission/possibility for other people to manage work for him. There is a huge bunch of pull requests open and quite a lot of issues. Forking isn't an option, because a fork will just sink in the dump of forks...

So as long as @jlukic does not respond, it's just as it is. I myself would be able to spend some hours a week to manage issues and pull requests, and I would like to do that for such a good piece of software.

check in to gitter.im / semantic-ui there are some other people who are willing to help.

@romaninsh But in the end it depends on the founder (@jlukic) to respond, so that he can grant someone access to maintain the repository/project/website.

I found adding a new row to database {id:-1, value: null} is the easiest way to deal with this issue.

Here is a patch that you can use to add a new option to $fn.dropdown();

https://github.com/BisManOnline/Semantic-UI-dropdown-selectPlaceholder

This patch will allow you to set:

allowPlaceholderSelect : true;

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions.

bump

Yet another Bump

Here's a workaround: If you add something like <option value="0"></option> to the beginning of your dropdown options then you'll get an empty option.

Just make sure your form processing function realizes that a zero value is a non-choice/null.

Got Yet another Bump

You might want to take a look at this: https://fomantic-ui.com/modules/dropdown.html#clearable-selection

I've added a clearable dropdown for next release of SUI in 33d08ec920c95b0ef9ee84bc31fbdb304916c212 and the proceeding commits.

Pass in clearable: true with any dropdown type.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

batata004 picture batata004  路  3Comments

ghost picture ghost  路  3Comments

arj-196 picture arj-196  路  3Comments

mllamazares picture mllamazares  路  3Comments

davialexandre picture davialexandre  路  3Comments