PDA

View Full Version : Anybody have a good way of handling the clearing of a combo box value?



tm8747a
6 Aug 2013, 8:03 AM
I'm finding that the fact that the 'select' event doesn't fire when you clear a combo box is causing me all kinds of headaches for something that should actually be simple. Basically, in the frequent use case where you have a combo that depends on another combo, I want the second combo's store and value to be cleared when the parent combo gets cleared. I've tried three approaches, using the 'change' event, the 'beforedeselect' event, or the 'blur' event.

With the 'change' event, the event fires way too much if you're using typeAhead, which I almost always do. You could just check if the value is blank and only then do something, but then somebody can just clear the text in the combo and start typing again. They weren't clearing the value, they were just typing a new value in. Meanwhile, my second combo will get cleared, which I don't want if the value still exists in the new store that loads (values in child combo could show for multiple values of parent combo).

With the 'beforedeselect' event, it's similar, as soon as you start editing the text, the value is considered deselected and the event fires. I want something that will fire once the user has completed his action, whether is selecting a value or clearing the field.

The 'blur' event seems like it may be the best option. Problem with it is that it doesn't take into account the changing or not of the field. So if I only want to run stuff if the field changed (hence the 'select' event), I'd need to then jump through hoops to track the field value on focus or something, and then check it on blur.

I personally think the 'select' event should fire when you clear, but based on a bug submission I put in, doesn't look like the Sencha team agrees, so I'm out of luck on that one. At the very least, there should be a 'deselect' event that fires when you're done. I guess I could probably just extend the ComboBox class and try to build that into it, but it seems silly to have to do that for something as basic as this. I've also run into issues trying to do override on certain classes that extend/mixin other classes, sometimes my overrides don't seem to work for some reason.

Thoughts? Maybe somebody has already tackled this and come up with robust solution?

tobiu
6 Aug 2013, 8:21 AM
you could override the following method:


clearValue: function() {
this.setValue([]);
}


and fire the select event there, in case this is what you want.
like:


this.fireEvent('select', [rest of the arguments]);


In case another event is firing to often, you can add a buffer into the listener config.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.EventManager-method-addListener
-> options -> buffer

tm8747a
6 Aug 2013, 11:53 AM
you could override the following method:


clearValue: function() {
this.setValue([]);
}


and fire the select event there, in case this is what you want.
like:


this.fireEvent('select', [rest of the arguments]);


In case another event is firing to often, you can add a buffer into the listener config.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.EventManager-method-addListener (http://docs.sencha.com/extjs/4.2.1/#%21/api/Ext.EventManager-method-addListener)
-> options -> buffer

OK, tried this out and still miserable over this. I'll expand on a specific use case. My parent combo, when changed (or cleared), needs to show a confirmation dialog asking the user if he really wants to change this value. If he clicks yes, the value is changed, otherwise the old value is restored.

So there are two problems, one of which I deal with that results in another one. If I have forceSelection set to true on my combo, which is pretty much always, I can't clear the value. If I delete all the text in the combo and then hit escape to close the list of values, then I tab out of the field, the old selection is restored. No problem, I figured, I'll get around this. So I created a custom ComboBox component so I don't have to do this all the time and added the following to it:



this.on('keyup', function(combo, e) {
var val = combo.getRawValue();

if (val === '' || val === null) {
combo.clearValue();
}
});

With this, the moment the text becomes an empty string, I clear the value. Fantastic, works like a charm. However, it's not so fantastic when I have a confirm dialog as above. Because then, as soon as I clear all the text, even if I had the intention of then typing something new to make a new selection, the dialog immediately shows up. Dammit.

So here's the best thing I was able to do. I modified the code to this:



this.on('keyup', function(combo, e) {
if (e.getKey() === Ext.EventObject.ESC) {
var val = combo.getRawValue();

if ((val === '' || val === null) && combo.__focusValue !== null) {
combo.clearValue();
}
combo.__focusValue = combo.getValue();
}
});

this.on('focus', function(combo) {
combo.__focusValue = combo.getValue();
});

Basically, instead of always clearing the value, it now only clear when the user hits ESC on a blank value. It kind of does the job, I guess, but doesn't feel very clean or elegant, more like an ugly bandaid to just get something working. So if anybody has a better idea for a cleaner solution, I'd love to hear it.

Regardless, thanks a lot tobiu for the answer, it at least allowed me to get something working.

Ratan
13 Aug 2014, 10:57 AM
combobox.reset() will reset the value

mhenn
6 Dec 2016, 6:16 AM
I just stumbled over this problem in ExtJS 5.1.3, too. I worked around it by setting the private property "clearValueOnEmpty" to "false". This way, the selection is not reset, when the user removes all the text from the field. The "beforeselect" event handles all the changes then.