Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to disallow clearing selected value #1373

Closed
OlliTietavainenVaadin opened this issue May 17, 2018 · 31 comments
Closed

No way to disallow clearing selected value #1373

OlliTietavainenVaadin opened this issue May 17, 2018 · 31 comments

Comments

@OlliTietavainenVaadin
Copy link
Member

<vaadin.version>10.0.0.beta10</vaadin.version>
Even if the ComboBox is set to be required with setRequired(true), it's still possible to clear the selected value with the x checkmark. There should be a way to make a selection mandatory.

@pleku
Copy link
Contributor

pleku commented May 17, 2018

I'm not sure if that is really the UX that we want, eg. if you have selected the wrong thing and don't want to submit it accidentally but instead clear it... but it probably should be configurable.

We're not going to do anything for this until there is proper support in the web component for it, which is I guess this issue vaadin/vaadin-text-field#92

@mstahv
Copy link
Member

mstahv commented Oct 13, 2018

I wouldn't like to allow clearing the value at all (selecting null). Is there really no way to accomplish that? That maybe wouldn't be a feature belonging to combobox anyways as it is also about new values, but our previous versions has such thing and AFAIK there is no other drop down selection component available. Can't create any decent UI for this very simple (and I'd bet common) use case without hacking with low level element API 😢

@jouni
Copy link
Member

jouni commented Oct 17, 2018

I’d also like to hear more about the use cases where this is needed. Would make it much easier to argue what would be the best UI solution for it.

@mstahv
Copy link
Member

mstahv commented Oct 17, 2018

I came across this issue just because I need a dropdown list (aka select tag in html), which don't allow empty selection. Those are everywhere. And I'm pretty sure that is what most people on this issue are looking for and I assume you are looking for usecases now for something else.

screenshot 2018-10-17 at 22 34 39

ComboBox is just basically the only thing we currently have for selecting an item from a set. A very basic UI need, not possible AFAIK. Also, our ComboBox has traditionally in Vaadin been used as an advanced replacement for basic select tag (aka NativeSelect), without the possibility to type in custom value, but with lazy loading and filtering (although that is in limited manner possible with most GUI frameworks for select tag too).

If you are just looking for use case to remove the clear button of the text, I can give you one: it looks messy.

@heruan
Copy link
Member

heruan commented Oct 17, 2018

Well I might be against the trend, but in my opinion it should always be possible to clear the value of a ComboBox. I see it as a text field on steroids, and like a text field you can clear its value (of course, if it's required it will be invalid—but still empty).

To replace the classic select tag, isn't vaadin-dropdown-menu there already? That will always have a value set, like @mstahv described.

@mstahv
Copy link
Member

mstahv commented Oct 17, 2018

Yes, exactly like I wrote, not necessary a feature of ComboBox, as it is defined elsewhere. But there isn't such a thing as DropDownMenu for Flow yet. And it has been possible before so old users are looking for it.

And based on the web component examples ( https://vaadin.com/components/vaadin-dropdown-menu/html-examples/dropdown-menu-basic-demos ), I'd much rather use either native select component (aka select tag in html) or ComboBox (that has filtering disabled and don't allow empty selection as proposed on this ticket), so I could more quickly select an item from the list by typing in first couple of letters of the item of my desire.

@jouni
Copy link
Member

jouni commented Oct 18, 2018

Thanks @mstahv – I did understand the initial description. I just want concrete examples, not only descriptions how the component should work. Problems, not solutions.

And I understood that the upcoming Select should solve the need. And like @heruan, I consider ComboBox as a text field more than a select. And preventing the user from clearing a text field (by reverting back to a previously approved value) seems like a rare case (and unexpected to the user), which is doable with custom code.

ComboBox has traditionally in Vaadin been used as an advanced replacement for basic select tag (aka NativeSelect), without the possibility to type in custom value, but with lazy loading and filtering

You can still (in v10+) prevent users from entering a custom value (that’s actually the default, right?). Also, ComboBox has traditionally been used since it was possible to theme it and we didn’t have a themable replacement for the native select component.

I'd much rather use either native select component (aka select tag in html) or ComboBox (that has filtering disabled and don't allow empty selection as proposed on this ticket), so I could more quickly select an item from the list by typing in first couple of letters of the item of my desire.

The current implementation allows you to type the first letter of an item to focus it. I agree this should be improved to match the native behavior. I’ll open an enhancement issue for it.

Edit: vaadin/vaadin-select#170

@jouni
Copy link
Member

jouni commented Oct 18, 2018

Question (to everyone who voted for this issue): why was the native <select> component unsuitable for your use case? Or am I right in assuming Flow doesn’t make it easy to use that (you’d have to work with low-level elements)?

@OlliTietavainenVaadin
Copy link
Member Author

Native <select> looks ugly (and inconsistent across browsers/platforms) out of the box and there's no easy server-side API for setting it up. I can fix these issues by writing my own code and styles, but why should I need to?

@mstahv
Copy link
Member

mstahv commented Oct 18, 2018

There is no native select. It would be just fine for my case, but I understand Olli's point on inconsistency on some public facing apps. And don't tell me you can use the low level element API. That can't be the answer. We need the proper Java API and support to Binder, otherwise the whole point of using Vaadin (Flow) is lost. I can then just as well build all on the client side with the frontend framework of my choice.

@Legioth
Copy link
Member

Legioth commented Oct 18, 2018

There's also the case where you want a select and not a text field on steroids, but you still want lazy loading and filtering because there's lots of options to select from.

@OlliTietavainenVaadin
Copy link
Member Author

Additionally, it's not at all obvious that you can use keyboard navigation to select an option in a <select>. Having a cursor in there makes a difference.

@samulivaadin
Copy link
Contributor

Preventing null value would be quite common use case here. The clear button can be hidden with CSS but instead having that hack in every project it would great if even that is provided by framework with some theme or style.

@jouni
Copy link
Member

jouni commented Oct 22, 2018

@samulivaadin agreed. I’ve been waiting for this issue to get fixed so we’d get a common way to achieve the same thing across all components that are based on the text-field: vaadin/vaadin-text-field#92

@OlliTietavainenVaadin
Copy link
Member Author

Might as well post this styling workaround here:

<dom-module theme-for="vaadin-combo-box" id="no-clear-button">
    <template>
        <style>
            :host(.no-clear-button) [part="clear-button"]{
                display:none
            }
        </style>
    </template>
</dom-module>

@anezthes
Copy link
Contributor

anezthes commented Nov 8, 2018

Just ran across this issue as well. Thumbs up, you has.

@jouni
Copy link
Member

jouni commented Nov 8, 2018

@anezthes, can you clarify what your thumbs up refers to?


As this issue got raised again in a discussion internally, I ended up taking a bit more time to think about this.

I still slightly disagree that there should be a way to prevent the user from clearing the value in a combo box. I haven’t yet heard a good argument why this would be a better user experience instead of a validation error. Ignoring user input is in general very bad. I mean, the user is choosing to clear the field and we should respect that and let them know if they need to choose a value in order to proceed.

If I understand the implied use case correctly as being “there are dozens of options and I always want to select one”, then a better solution is more likely a select with a separate filter field inside the dropdown. Then it does not imply that it’s a freeform input field, but there’s only a filter for the options.

An example of that would be the “branch” selector in Github. Using a combo box in its place would seem slightly weird to me, but I suppose you might want to do that if the other alternative was not available as a ready-made component.

That said, I’m removing my 👎, and I’m okay if we want to add this as an opt-in configuration option (for <vaadin-combo-box>). The exact API probably needs some bikeshedding 🙂

@Legioth
Copy link
Member

Legioth commented Nov 12, 2018

Sure, a select component with a filter field in the dropdown would probably be even better, but until that is part of the core component set, an official way of hiding the clear button is a quite good approximation that is surely much easier to implement.

@jouni
Copy link
Member

jouni commented Nov 12, 2018

an official way of hiding the clear button

That’s up next for text field, which should eventually cascade down to the components using it internally: vaadin/vaadin-text-field#92 (comment)

But combo box requires more than that, right? There needs to be an API like “empty selection not allowed”. Otherwise the user can still clear the field with the keyboard.

@masbaehr
Copy link

Hi, I also came across this. For those seeking a programmatic workaround without dirty CSS hacks:

It will just reset to the old value

ComboBox<String> modeCb = new ComboBox<>();
		modeCb.setItems("a", "b");
		modeCb.setValue("a");
		modeCb.setLabel("Select section type");
		modeCb.addValueChangeListener(listener -> {
			if(listener.getValue() == null) {
				modeCb.setValue(listener.getOldValue());
				return;
			}
		});

@aboger
Copy link

aboger commented Dec 11, 2018

@jouni To give you my use case: I have a ComboBox to select an entity type and a Grid showing a list of entities of the selected type. As entity types are known at compile time, I can preselect the entity type which most users usually want to see first. Therefore, I can pre-fill the Grid. That's less effort for users, therefore better UX (according to my client).
The entire website is just about providing entity information in that Grid. Choosing a null entity type in the ComboBox forces me to inform the user about a state that he neither desires nor expects, e.g. by showing a placeholder, notification, whatsoever, ... only to make him restore the previous state by re-selecting a non-null entity type.


I finally made it to construct a solution without the clearButton and without the possibility to set a null value:

@HtmlImport("/html/non-null-combobox-theme.html")
public class NonNullComboBox<T> extends ComboBox<T> {

    public NonNullComboBox() {
        addClassName("non-null-combobox");

        setRequiredIndicatorVisible(true);
        setRequired(true);
        setPreventInvalidInput(true);
        setAllowCustomValue(false);

        addValueChangeListener(listener -> {
            if(listener.getValue() == null) {
                setValue(listener.getOldValue());
            }
        });
    }

}

And in src/main/resources/static/html/non-null-combobox-theme.html the following content. Be aware that it's a Spring based project. Therefore, the content of src/main/resources/static is published automatically:

<dom-module id="non-null-combobox-theme" theme-for="vaadin-combo-box">
    <template>
        <style>
            :host(.non-null-combobox) [part="clear-button"] {
                display:none !important
            }
        </style>
    </template>
</dom-module>

I'm happy with this solution, hope my post helps others or is valuable input to this discussion. Thanks for your awesome work at Vaadin 🙂

@steffen-harbich-cognitum

I am curious, will this be planned for the next release? I mean vaadin/vaadin-text-field#92 is marked as closed.

@jouni
Copy link
Member

jouni commented Jan 14, 2019

@steffen-harbich-itc: the text field clear button feature is not yet out in a stable release (currently in alpha).

Also, I don’t know that work is being done to utilize that feature in combo box (and date & time pickers). There’s a question about breaking changes if we want to align the behavior of all the fields so that the clear button is opt-in in all of them. I would like that (making them consistent), but it could be considered a breaking change.

I’m more towards keeping the process simple and pushing the change in a minor version. End users can still clear the field with the keyboard, and developers can re-enable the button with an attribute. Though, combo box (and date & time pickers) should probably have a way to re-enable the clear button across the whole app, without setting it individually for each and every field (a CSS custom property could work).


That said, we don’t need to wait for the text field clear button feature at all. The feature discussed in this issue is larger than just the visibility of the button. It’s also about preventing the user from setting a null value for the field.

@wfischlein
Copy link

wfischlein commented Jan 17, 2019

I'm confused - now as I ran over this issue as well.
There is setAllowCustomValue in ComboBox but no setAllowNullValue. And there are three types of selects:

  • adding custom values that extend the set of options (e.g. assigning or, if not there, creating new tag for the combobox's target)
  • setting a null value to 'unassign' it in the backend (e.g. a bugticket that gets moved into the backlog and by that is not supposed to have an assignee any longer)
  • choosing from a finite fix set (like in the above example: I have n entity types in my classloader and am asked to pick one
    In the first case the combo can be considered as a text input.

In general when a ui element enables you to set up values that lead to a validation error you should think twice whether there is no better way (disable buttons e.g. when they won't have an effect or would to something evil is better than show an error, allow to set a null entity when it doesn't make sense and then say: 'You are not allow to set the entity to null' is a shitty user experience).
So how long do we wait to have the feature in the ComboBox to hide the 'set to null'-button?

@jouni
Copy link
Member

jouni commented Jan 21, 2019

Thanks for the feedback!

So how long do we wait to have the feature in the ComboBox to hide the 'set to null'-button?

Politely pointing out again that this feature is not just about hiding the clear button.

I assume you saw the workaround by Alexander Boger: https://github.com/vaadin/vaadin-combo-box-flow/issues/79#issuecomment-446231169

I’m not sure if @tomivirkki is aware of this discussion. Adding this feature should start from the web component.

@pleku
Copy link
Contributor

pleku commented Mar 5, 2019

The same feature is available in the Select component since Vaadin 13, with that you can prevent the user from clearing selection. See the example Required here https://vaadin.com/components/vaadin-select/java-examples, API https://vaadin.com/api/platform/13.0.0/com/vaadin/flow/component/select/Select.html#setEmptySelectionAllowed-boolean-

@jouni
Copy link
Member

jouni commented Aug 7, 2019

@pleku I don’t really understand the need for adding setEmptySelectionAllowed to Select. I think it’s redundant and unnecessary.

If an empty selection should not be allowed, the developer should not provide an item in the list which is empty/null. If they want to show a placeholder, there’s the setPlaceholder method for that.

Also, in the example that you linked to, the “placeholder” item is disabled and can’t be selected by the end-user anyway. I assume the only thing setEmptySelectionAllowed(true) does in that example is select the first non-null item by default.

But, I must admit, I don’t know enough about Flow. Maybe there’s a reason why it had to be implemented like this.

@pleku
Copy link
Contributor

pleku commented Aug 8, 2019

@jouni there is no "null/empty" item in Java side for most times (always?). For some components it is not supported. So that is why it is a special case.

@jouni
Copy link
Member

jouni commented Aug 8, 2019

Can you add an example (preferably from a real app) or something? I still don’t understand. I thought not having null/empty values allowed was the thing that was requested 😅

Are you saying that for example that you can’t do select.setValue(null)? I suppose not, but just making sure, that the value of a field can indeed be null, right? 😊

Is the use case such when you need to have a visible item (with or without a label) in the list which corresponds to null in the backend, but it is never actually selectable, acting as a “title/separator” of some kind?

@pleku
Copy link
Contributor

pleku commented Aug 8, 2019

Are you saying that for example that you can’t do select.setValue(null)? I suppose not, but just making sure, that the value of a field can indeed be null, right? 😊

Of course you can do that.

Honestly I'm not sure which use case you're now referring to, the one about ComboBox not allowing clearing the value or making it possible to select a special null item in Select. The latter was also asked about in the above comments, so I commented here that one can configure that in Select now. As it has been possible in framework versions even before, so there are very likely lots of applications using that feature. Please come talk to me offline so we can sort out what ever you need more efficiently, thanks.

@vaadin-bot vaadin-bot transferred this issue from vaadin/vaadin-combo-box-flow Oct 6, 2020
@vaadin-bot vaadin-bot transferred this issue from vaadin/vaadin-combo-box May 19, 2021
@vaadin-bot vaadin-bot transferred this issue from vaadin/web-components May 21, 2021
@rolfsmeds
Copy link
Contributor

As it's no longer clear to anyone what feature exactly this ticket represents, especially since the introduction of the Select component and the setClearButtonVisible API, I'm closing it in favor of #1998.

Please up-vote (👍 ) that new ticket (using the smiley-button in the description header) if you're interested specifically in the functionality described in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
vaadin-core
  
📬  Inbox
Development

No branches or pull requests