-
Notifications
You must be signed in to change notification settings - Fork 331
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
feat(clearOnSelected): allow users to clear the input instead of filling #244
Conversation
In some use-cases, like when you're using autocomplete to make tags on a page, or using the output in any other way than prefilling the query, you don't want the suggested value to show in the input, but would rather like it to be empty. Before this PR it was basically impossible to have your input not filled, since it came back on blur and a few different places (see `resetInputValue` fixes #241
@alystair, can you check this PR? you need to use the new option, but don't need to change the value in |
Sorry being a bit of a novice here, I fetched your PR, then loaded the scripts: <script src="//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
<script src="/autocomplete.js/index.js"></script> Resulting in the following: index.js:3 Uncaught ReferenceError: module is not defined at index.js:3 Which leads to |
If I try loading standalone/index.js directly it does Uncaught ReferenceError: require is not defined at index.js:4 |
@alystair for now you'll only be able to try it by cloning the repository, then you do |
I uploaded the built file: https://gist.github.com/Haroenv/16d566e435cbafee32be431e045651c7 You can link this directly: https://rawgit.com/Haroenv/16d566e435cbafee32be431e045651c7/raw/5efc69ba498ffb4aed68fb1619e3c1dfa1ae6a0c/autocomplete.min.js |
Doesn't seem to do anything, it reacts the same way as originally shown in issue. Here's the code on my end: let brands = client.initIndex('brands');
autocomplete('[name=sponsors]',
{ clearOnSelected:true },{
source: autocomplete.sources.hits(brands, {filters:'type:sponsor OR type:broadcasting'})
,templates: {
suggestion: function(suggestion) { return '<span>'+suggestion._highlightResult.name.value+'<img src="static/brands/'+suggestion['type'].charAt(0).toLowerCase()+'_'+suggestion.name.replace(/\s/g, '')+'.png'+'" alt=""></span>'; }
,empty: function emptyTemplate() { return '<div class="aa-empty">Brand not in our database - consider <a href="mailto:XXXXXXX">suggesting it</a></div>'; }
}
}).on('autocomplete:selected', function(event, suggestion, dataset) {
let exists = this.parentElement.parentElement.querySelector('[data-guid="'+suggestion['guid']+'"]');
if (exists) { //existing tag
// our tagging code
} else { // create new tag
// our tagging code
}
this.value = '';
}).on('autocomplete:closed', function(event) {
this.value='';
}); |
let brands = client.initIndex('brands');
autocomplete('[name=sponsors]',
{ clearOnSelected:true },{
source: autocomplete.sources.hits(brands, {filters:'type:sponsor OR type:broadcasting'})
,templates: {
suggestion: function(suggestion) { return '<span>'+suggestion._highlightResult.name.value+'<img src="static/brands/'+suggestion['type'].charAt(0).toLowerCase()+'_'+suggestion.name.replace(/\s/g, '')+'.png'+'" alt=""></span>'; }
,empty: function emptyTemplate() { return '<div class="aa-empty">Brand not in our database - consider <a href="mailto:XXXXXXX">suggesting it</a></div>'; }
}
}).on('autocomplete:selected', function(event, suggestion, dataset) {
let exists = this.parentElement.parentElement.querySelector('[data-guid="'+suggestion['guid']+'"]');
if (exists) { //existing tag
// our tagging code
} else { // create new tag
// our tagging code
}
}) |
That doesn't change behavior on blur, as soon as it loses focus the input is restored. I believe this is caused by |
Hmm, this didn’t happen to me when testing, but I have an idea what the cause is :) |
src/autocomplete/typeahead.js
Outdated
@@ -417,7 +418,11 @@ _.mixin(Typeahead.prototype, { | |||
if (typeof datum.value !== 'undefined') { | |||
this.input.setQuery(datum.value); | |||
} | |||
this.input.setInputValue(datum.value, true); | |||
if (this.clearOnSelected) { | |||
this.input.setInputValue('', true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add setQuery here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this.input.setQuery('');
here and we gucci 👍
This made no difference, the only fix that worked for me was to comment out |
if you add |
perfect, I had that initially but accidentally reversed it while developing the tests. It should work completely now @alystair |
Great, ship it 👍 |
Demo of this behaviour in a codesandbox: https://codesandbox.io/s/j76mlmzq4v (would really like a build being done in travis that can be hot linked :p ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few suggestions. Otherwise it seems solid 👍
test/unit/typeahead_spec.js
Outdated
view.input.trigger('enterKeyed', $e); | ||
|
||
expect(spy).toHaveBeenCalled(); | ||
expect(view.input.setQuery).toHaveBeenCalledWith(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check the value of this.$input rather than checking that some methods have been called (in order to not test how the code is done)?
Also would it be possible to have some value to check that there is an actual change of state (this would be a requirement if we can test without spy)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, but didn't know how to set a query here via code 🤔
test/unit/typeahead_spec.js
Outdated
view.$input.on('autocomplete:selected', spy); | ||
view.input.trigger('enterKeyed', $e); | ||
|
||
expect(spy).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you test the values that the callback receives?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's already tested in other tests, this behaviour doesn't change that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why test that it has been called. This feature could mess with the parameters if we do not know the actual implementation.
@@ -31,6 +31,7 @@ function Typeahead(o) { | |||
this.openOnFocus = !!o.openOnFocus; | |||
this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; | |||
this.autoWidth = (o.autoWidth === undefined) ? true : !!o.autoWidth; | |||
this.clearOnSelected = !!o.clearOnSelected; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using Boolean(o.clearOnSelected)
instead of !!o.clearOnSelected
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is in the same style as the other options, technically both are the same :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are the same, indeed. Just not used to see that anymore. If it's consistent, good for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Is there an ETA of when this change will hit the CDNs? We'll use a local copy until then. Thanks again. |
@alystair I'll release tomorrow morning |
In some use-cases, like when you're using autocomplete to make tags on a page, or using the output in any other way than prefilling the query, you don't want the suggested value to show in the input, but would rather like it to be empty.
Before this PR it was basically impossible to have your input not filled, since it came back on blur and a few different places (see
resetInputValue
)fixes #241
now there's a new option:
This makes sure the input clears after selecting, rather dan filling