vuetifyjs / vuetify

🐉 Vue Component Framework
https://vuetifyjs.com
MIT License
39.11k stars 6.92k forks source link

[Feature Request] Pressing the clearable icon on <v-text-field> with clearable prop sets the model to null not to empty string #4144

Open zawnk opened 5 years ago

zawnk commented 5 years ago

Versions and Environment

Vuetify: 1.0.18 Vue: 2.5.16 Browsers: Vivaldi 1.96.1147.42 OS: Windows 10

Steps to reproduce

Create a <v-text-field> with clearable and the model for it. Fill in some text. Press X icon (default) to clear the text, check the model.

Expected Behavior

Model is an empty string ''.

Actual Behavior

Model is null.

Reproduction Link

https://codepen.io/anon/pen/YLoaOo?editors=1111

Other comments

It gets annoying when you have String functions on that model and they return errors because they can't be applied to null if a user in the front-end uses the clearable icon. The bug also applies on the newest alpha.

KaelWD commented 5 years ago

See also #2752

johnleider commented 5 years ago

I can see this being added as a prop in the future, reset-value, but currently this is not considered a bug.

ChaStPierre commented 5 years ago

do we have a workaround? Thanks

johnleider commented 5 years ago

You would need to extend the component and rewrite its reset functionality.

duoweb commented 5 years ago

Hi! I found a solution to your problem. Use mask props!

duoweb commented 5 years ago

But I have the opposite problem. I have a object from backend with null values. and if the user enters a value and clicks clearable, the value will change to an empty string instead of null. Provided that the mask is used in the field.

e0 commented 5 years ago

It looks like there is a new prop that solves this problem now. In version > 1.1, there is a prop called clear-icon-cb, which can be used like :clear-icon-cb="handleClear".

lmapii commented 5 years ago

Second an empty-string since this would be consistent with what the value is when the user clears the field by deleting its content.

robokozo commented 5 years ago

I ran into this myself today.

Check out the differences in using clear-icon-cb vs @click:clear (It also shows how you can set the value of the cleared text box to whatever you want)

https://codepen.io/anon/pen/EdPzBd?editors=1011

With @click:clear crashes because even though I set the value to "", the new handler must be setting the value to null afterwards.

I reported the inconsistency here: https://github.com/vuetifyjs/vuetify/issues/5213

NoahCardoza commented 5 years ago

I "third" an empty-string as well for the same reasons. It creates problems because null isn't the same as '', which is what I'd expect to find in a text/string input field.

cb109 commented 5 years ago

Issue just popped up on Discord again. I think it's a good idea to make this configurable, as John suggested.

matteotrapani commented 5 years ago

I can see this being added as a prop in the future, reset-value, but currently this is not considered a bug.

Any news about reset-value @johnleider ? It would be great for me because I must manage clearable on VSelect. In this case clearable sets the model to undefined, but I need it to set the model to null because it represents a FK in my DB.

Plus I would prefer not to use :clear-icon-cb because I have many VSelect and I should write a specific function for each of them.

johnleider commented 5 years ago

It's coming on v1.4

johnleider commented 4 years ago

There is currently a PR open to resolve this but needs a bit more polish. Unfortunately it did not make the cut for v2 but obviously is on the radar. Thank you for your patience.

Flamenco commented 4 years ago

I think in general every component should have a default 'zero' cleared state that is well documented and can be overridden. Instead of 'clearable', perhaps we can create an new property called 'resettable'.

Each component would then have a value or callback function to supply the component.

Additionally , the runtime could provide a few default implementations.

If the function is not supplied, a default handler can simply delegate to 'clearable'

This would be trivial to implement, remove the ambiguity of the clearable operation, and make the user code cleaner and smaller.

<v-text-field resettable />
<v-text-field resettable='' />
<v-text-field :resettable='null' />

<v-text-field :resettable=" ()=>'' " />
<v-text-field :resettable=" ()=>null ">
<v-text-field :resettable=" ()=>undefined ">
<v-text-field :resettable=" ()=>'Default Value' ">
<v-text-field :resettable="$r_empty">
<v-text-field :resettable="$r_null">

<v-select :resettable=" ()=>[] ">
<v-select :resettable=" ()=>['a','b','c'] ">
<v-select :resettable=" ()=>null ">
<v-select :resettable="$r_array">

We can also just add this to the existing clearable property, but in that case things would break if the developer had coded :clearable='true' instead of clearable.

allochi commented 4 years ago

I actually reached this today after a session of debugging to find out the v-select clears the value by setting it to undefined too, which doesn't work well with my api.

I'm doing the following as a workaround, but I would like to add my voice to have a resettable value.

<v-select
  :value="iso3"
  @input="iso3=$event?$event:null"
  :items="countries"
  item-text="name"
  item-value="iso3"
  label="Country"
  clearable
></v-select>
...
parsher commented 4 years ago

Is this working on?.. I need this feature too.

hussain commented 4 years ago

I'm facing same, even null value would cause a problem in my case since form payload is post'ed/put to an API as json. I'm using axios for frontend. The main issue is that undefined or null values would cause the json key to be removed by axios (and other HTTP lib's).

i.e. this json payload

{
    "name": "Joe",
    "phone": undefined,
    "cellphone": null
}

would make it to backend as

{
    "name": "Joe",
    "cellphone": null
}

key phone and cellphone is totally removed.

if phone was set before in backend/DB, it cannot be cleared to empty/null in backend/DB since cannot post/put undefined or null.

workaround is to use axios interceptor (or interceptor of whatever lib you're using) I added an interceptor as below snippet. This also works for nested object ;) thanks recursion!

/**
 * Add json cleaner to set undefined/null values to empty string.
 * This is to prevent axios(json to string using jsonify) from removing those keys
 * when converting json paylod to string.
 */
function cleanJSON(json) {
    for (let key in json) {
        if (json[key] === undefined || json[key] === null) {
            json[key] = '';
        } else if (typeof json[key] === 'object')
            json[key] = cleanJSON(json[key]);
    }
    return json;
}
// Add a request interceptor
window.axios.interceptors.request.use(
    function(config) {
        if (['post', 'put', 'patch'].includes(config.method)) {
            config.data = cleanJSON(config.data);
        }
        return config;
    },
    function(error) {
        return Promise.reject(error);
    }
);
jacekkarczmarczyk commented 4 years ago

keys phone and cellphone are totally removed.

No?

axios.post(document.location.href, {
    "name": "Joe",
    "phone": undefined,
    "cellphone": null
})

image

hussain commented 4 years ago

No?

You are right, I just tested it. only keys with undefined values are removed, keys with null stays.

so once v-select clears to null I need to remove that interceptor in my case, and for others interceptor can be used to replace to empty-string.

Thanks @jacekkarczmarczyk for correcting me.

I edited my previous comment to correct it.

KaelWD commented 3 years ago

On default values: does anyone differentiate between null and '' in regards to text fields? I'm thinking about setting the default value to null across the board in 2.4 to satisfy #7429 and allow JSON serialization. '' would probably make more sense but may break forms expecting '' to be an actual value rather than a cleared state.

garfonzo commented 3 years ago

I've run into this issue on a number of different form components, as has been mentioned in this thread. Both with the reset function on the v-form component, but also with the clearable prop on v-autocomplete. Resetting to undefined has caused a lot of challenges and work arounds. Thanks to @KaelWD for discussing the reset function with me on the Discord server today.

While I understand using either null or '' as a default reset value, might I also suggest a more flexible solution of having a prop, such as reset-value that allows any value to be used as the reset value. Without the prop, it would fall back to a default of null or ''.

This would help in a wide range of applications where some fields need to have their value reset to something specific for the application. For example, setting a specific field to the id of a related model or setting a field to a specific array.

A blanket reset to null or '' might be fine, but it seems like this is a good place to allow more flexibility.

fdendorfer commented 2 years ago

So is there a workaround for this? I'm using it's value as a prop, which expects type: String and throws an error, if it gets cleared. If I add @click:clear="input = ''", the value is an empty string just for a split second then it changes to null.

van-huyen commented 2 years ago

I'm using @input event for this problem, it will return empty string when click on clear icon:

                      <v-textarea
                        v-model="aaa"
                        dense
                        outlined
                        auto-grow
                        @input="aaa= aaa || ''"
                      />

By the way, please don't show clear icon in readonly mode @KaelWD v-text-field, v-textarea in readonly but can clear text? I think that not good to use.

KaelWD commented 2 years ago

Resolved in #13996

akowald commented 1 year ago

This fix got regressed, so the bug is still open. See link below for the offending line of code. A workaround is to reset the value when the @click:clear event is emitted.

https://github.com/vuetifyjs/vuetify/blob/9cff4ed1a5efd6e3ab14a1201ff59ec95e9f8a0b/packages/vuetify/src/components/VTextField/VTextField.tsx#L129

ponahoum commented 7 months ago

Yup as of 22/09/2023 there is a regression on this one. This is especially painful if you globally enable the "clearable" prop and have to change your api to support null and string instead of string only on all endpoints.